1 # -*- coding: utf-8 -*-
4 # Copyright 2015 Telefónica Investigación 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 db_base
import HTTP_Unauthorized
, HTTP_Bad_Request
, HTTP_Internal_Server_Error
, HTTP_Not_Found
,\
35 HTTP_Conflict
, HTTP_Method_Not_Allowed
36 import console_proxy_thread
as cli
39 from db_base
import db_base_Exception
42 global vimconn_imported
45 vimconn_imported
={} #dictionary with VIM type as key, loaded module as value
46 logger
= logging
.getLogger('mano.nfvo')
48 class NfvoException(Exception):
49 def __init__(self
, message
, http_code
):
50 self
.http_code
= http_code
51 Exception.__init
__(self
, message
)
54 def get_flavorlist(mydb
, vnf_id
, nfvo_tenant
=None):
56 return result, content:
57 <0, error_text upon error
58 nb_records, flavor_list on success
61 WHERE_dict
['vnf_id'] = vnf_id
62 if nfvo_tenant
is not None:
63 WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
65 #result, content = mydb.get_table(FROM='vms join vnfs on vms.vnf_id = vnfs.uuid',SELECT=('uuid'),WHERE=WHERE_dict )
66 #result, content = mydb.get_table(FROM='vms',SELECT=('vim_flavor_id',),WHERE=WHERE_dict )
67 flavors
= mydb
.get_rows(FROM
='vms join flavors on vms.flavor_id=flavors.uuid',SELECT
=('flavor_id',),WHERE
=WHERE_dict
)
68 #print "get_flavor_list result:", result
69 #print "get_flavor_list content:", content
71 for flavor
in flavors
:
72 flavorList
.append(flavor
['flavor_id'])
75 def get_imagelist(mydb
, vnf_id
, nfvo_tenant
=None):
77 return result, content:
78 <0, error_text upon error
79 nb_records, flavor_list on success
82 WHERE_dict
['vnf_id'] = vnf_id
83 if nfvo_tenant
is not None:
84 WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
86 #result, content = mydb.get_table(FROM='vms join vnfs on vms-vnf_id = vnfs.uuid',SELECT=('uuid'),WHERE=WHERE_dict )
87 images
= mydb
.get_rows(FROM
='vms join images on vms.image_id=images.uuid',SELECT
=('image_id',),WHERE
=WHERE_dict
)
90 imageList
.append(image
['image_id'])
93 def get_vim(mydb
, nfvo_tenant
=None, datacenter_id
=None, datacenter_name
=None, vim_tenant
=None):
94 '''Obtain a dictionary of VIM (datacenter) classes with some of the input parameters
95 return result, content:
96 <0, error_text upon error
97 NUMBER, dictionary with datacenter_id: vim_class with these keys:
98 'nfvo_tenant_id','datacenter_id','vim_tenant_id','vim_url','vim_url_admin','datacenter_name','type','user','passwd'
101 if nfvo_tenant
is not None: WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
102 if datacenter_id
is not None: WHERE_dict
['d.uuid'] = datacenter_id
103 if datacenter_name
is not None: WHERE_dict
['d.name'] = datacenter_name
104 if vim_tenant
is not None: WHERE_dict
['dt.vim_tenant_id'] = vim_tenant
105 if nfvo_tenant
or vim_tenant
:
106 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'
107 select_
= ('type','config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name',
108 'dt.uuid as datacenter_tenant_id','dt.vim_tenant_name as vim_tenant_name','dt.vim_tenant_id as vim_tenant_id',
111 from_
= 'datacenters as d'
112 select_
= ('type','config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name')
114 vims
= mydb
.get_rows(FROM
=from_
, SELECT
=select_
, WHERE
=WHERE_dict
)
117 extra
={'datacenter_tenant_id': vim
.get('datacenter_tenant_id')}
118 if vim
["config"] != None:
119 extra
.update(yaml
.load(vim
["config"]))
120 if vim
["type"] not in vimconn_imported
:
123 module
= "vimconn_" + vim
["type"]
124 module_info
= imp
.find_module(module
)
125 vim_conn
= imp
.load_module(vim
["type"], *module_info
)
126 vimconn_imported
[vim
["type"]] = vim_conn
127 except (IOError, ImportError) as e
:
128 if module_info
and module_info
[0]:
129 file.close(module_info
[0])
130 raise NfvoException("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format(
131 vim
["type"], module
, type(e
).__name
__, str(e
)), HTTP_Bad_Request
)
135 # return -HTTP_Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
136 vim_dict
[ vim
['datacenter_id'] ] = vimconn_imported
[ vim
["type"] ].vimconnector(
137 uuid
=vim
['datacenter_id'], name
=vim
['datacenter_name'],
138 tenant_id
=vim
.get('vim_tenant_id'), tenant_name
=vim
.get('vim_tenant_name'),
139 url
=vim
['vim_url'], url_admin
=vim
['vim_url_admin'],
140 user
=vim
.get('user'), passwd
=vim
.get('passwd'),
143 except Exception as e
:
144 raise NfvoException("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, str(e
)), HTTP_Internal_Server_Error
)
146 except db_base_Exception
as e
:
147 raise NfvoException(str(e
) + " at nfvo.get_vim", e
.http_code
)
149 def rollback(mydb
, vims
, rollback_list
):
151 #delete things by reverse order
152 for i
in range(len(rollback_list
)-1, -1, -1):
153 item
= rollback_list
[i
]
154 if item
["where"]=="vim":
155 if item
["vim_id"] not in vims
:
157 vim
=vims
[ item
["vim_id"] ]
159 if item
["what"]=="image":
160 vim
.delete_image(item
["uuid"])
161 mydb
.delete_row(FROM
="datacenters_images", WHERE
={"datacenter_id": vim
["id"], "vim_id":item
["uuid"]})
162 elif item
["what"]=="flavor":
163 vim
.delete_flavor(item
["uuid"])
164 mydb
.delete_row(FROM
="datacenters_flavos", WHERE
={"datacenter_id": vim
["id"], "vim_id":item
["uuid"]})
165 elif item
["what"]=="network":
166 vim
.delete_network(item
["uuid"])
167 elif item
["what"]=="vm":
168 vim
.delete_vminstance(item
["uuid"])
169 except vimconn
.vimconnException
as e
:
170 logger
.error("Error in rollback. Not possible to delete VIM %s '%s'. Message: %s", item
['what'], item
["uuid"], str(e
))
171 undeleted_items
.append("{} {} from VIM {}".format(item
['what'], item
["uuid"], vim
["name"]))
172 except db_base_Exception
as e
:
173 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB.datacenters Message: %s", item
['what'], item
["uuid"], str(e
))
177 if item
["what"]=="image":
178 mydb
.delete_row(FROM
="images", WHERE
={"uuid": item
["uuid"]})
179 elif item
["what"]=="flavor":
180 mydb
.delete_row(FROM
="flavors", WHERE
={"uuid": item
["uuid"]})
181 except db_base_Exception
as e
:
182 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB. Message: %s", item
['what'], item
["uuid"], str(e
))
183 undeleted_items
.append("{} '{}'".format(item
['what'], item
["uuid"]))
184 if len(undeleted_items
)==0:
185 return True," Rollback successful."
187 return False," Rollback fails to delete: " + str(undeleted_items
)
189 def check_vnf_descriptor(vnf_descriptor
):
191 #create a dictionary with vnfc-name: vnfc:interface-list key:values pairs
193 for vnfc
in vnf_descriptor
["vnf"]["VNFC"]:
195 #dataplane interfaces
196 for numa
in vnfc
.get("numas",() ):
197 for interface
in numa
.get("interfaces",()):
198 if interface
["name"] in name_list
:
199 raise NfvoException("Error at vnf:VNFC[name:'{}']:numas:interfaces:name, interface name '{}' already used in this VNFC"\
200 .format(vnfc
["name"], interface
["name"]),
202 name_list
.append( interface
["name"] )
204 for interface
in vnfc
.get("bridge-ifaces",() ):
205 if interface
["name"] in name_list
:
206 raise NfvoException("Error at vnf:VNFC[name:'{}']:bridge-ifaces:name, interface name '{}' already used in this VNFC"\
207 .format(vnfc
["name"], interface
["name"]),
209 name_list
.append( interface
["name"] )
210 vnfc_interfaces
[ vnfc
["name"] ] = name_list
212 #check if the info in external_connections matches with the one in the vnfcs
214 for external_connection
in vnf_descriptor
["vnf"].get("external-connections",() ):
215 if external_connection
["name"] in name_list
:
216 raise NfvoException("Error at vnf:external-connections:name, value '{}' already used as an external-connection"\
217 .format(external_connection
["name"]),
219 name_list
.append(external_connection
["name"])
220 if external_connection
["VNFC"] not in vnfc_interfaces
:
221 raise NfvoException("Error at vnf:external-connections[name:'{}']:VNFC, value '{}' does not match any VNFC"\
222 .format(external_connection
["name"], external_connection
["VNFC"]),
225 if external_connection
["local_iface_name"] not in vnfc_interfaces
[ external_connection
["VNFC"] ]:
226 raise NfvoException("Error at vnf:external-connections[name:'{}']:local_iface_name, value '{}' does not match any interface of this VNFC"\
227 .format(external_connection
["name"], external_connection
["local_iface_name"]),
230 #check if the info in internal_connections matches with the one in the vnfcs
232 for internal_connection
in vnf_descriptor
["vnf"].get("internal-connections",() ):
233 if internal_connection
["name"] in name_list
:
234 raise NfvoException("Error at vnf:internal-connections:name, value '%s' already used as an internal-connection"\
235 .format(internal_connection
["name"]),
237 name_list
.append(internal_connection
["name"])
238 #We should check that internal-connections of type "ptp" have only 2 elements
239 if len(internal_connection
["elements"])>2 and internal_connection
["type"] == "ptp":
240 raise NfvoException("Error at vnf:internal-connections[name:'{}']:elements, size must be 2 for a type:'ptp'"\
241 .format(internal_connection
["name"]),
243 for port
in internal_connection
["elements"]:
244 if port
["VNFC"] not in vnfc_interfaces
:
245 raise NfvoException("Error at vnf:internal-connections[name:'{}']:elements[]:VNFC, value '{}' does not match any VNFC"\
246 .format(internal_connection
["name"], port
["VNFC"]),
248 if port
["local_iface_name"] not in vnfc_interfaces
[ port
["VNFC"] ]:
249 raise NfvoException("Error at vnf:internal-connections[name:'{}']:elements[]:local_iface_name, value '{}' does not match any interface of this VNFC"\
250 .format(internal_connection
["name"], port
["local_iface_name"]),
252 return -HTTP_Bad_Request
,
254 def create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
= False):
256 if only_create_at_vim
:
257 image_mano_id
= image_dict
['uuid']
259 images
= mydb
.get_rows(FROM
="images", WHERE
={'location':image_dict
['location'], 'metadata':image_dict
['metadata']})
261 image_mano_id
= images
[0]['uuid']
264 temp_image_dict
={'name':image_dict
['name'], 'description':image_dict
.get('description',None),
265 'location':image_dict
['location'], 'metadata':image_dict
.get('metadata',None)
267 image_mano_id
= mydb
.new_row('images', temp_image_dict
, add_uuid
=True)
268 rollback_list
.append({"where":"mano", "what":"image","uuid":image_mano_id
})
269 #create image at every vim
270 for vim_id
,vim
in vims
.iteritems():
271 image_created
="false"
273 image_db
= mydb
.get_rows(FROM
="datacenters_images", WHERE
={'datacenter_id':vim_id
, 'image_id':image_mano_id
})
274 #look at VIM if this image exist
276 image_vim_id
= vim
.get_image_id_from_path(image_dict
['location'])
277 except vimconn
.vimconnNotFoundException
as e
:
278 #Create the image in VIM
280 image_vim_id
= vim
.new_image(image_dict
)
281 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"image","uuid":image_vim_id
})
283 except vimconn
.vimconnException
as e
:
285 logger
.error("Error creating image at VIM: %s", str(e
))
287 image_vim_id
= str(e
)
288 logger
.warn("Error creating image at VIM: %s", str(e
))
290 except vimconn
.vimconnException
as e
:
291 logger
.warn("Error contacting VIM to know if the image exist at VIM: %s", str(e
))
292 image_vim_id
= str(e
)
294 #if reach here the image has been create or exist
296 #add new vim_id at datacenters_images
297 mydb
.new_row('datacenters_images', {'datacenter_id':vim_id
, 'image_id':image_mano_id
, 'vim_id': image_vim_id
, 'created':image_created
})
298 elif image_db
[0]["vim_id"]!=image_vim_id
:
299 #modify existing vim_id at datacenters_images
300 mydb
.update_rows('datacenters_images', UPDATE
={'vim_id':image_vim_id
}, WHERE
={'datacenter_id':vim_id
, 'image_id':image_mano_id
})
302 return image_vim_id
if only_create_at_vim
else image_mano_id
304 def create_or_use_flavor(mydb
, vims
, flavor_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
= False):
305 temp_flavor_dict
= {'disk':flavor_dict
.get('disk',1),
306 'ram':flavor_dict
.get('ram'),
307 'vcpus':flavor_dict
.get('vcpus'),
309 if 'extended' in flavor_dict
and flavor_dict
['extended']==None:
310 del flavor_dict
['extended']
311 if 'extended' in flavor_dict
:
312 temp_flavor_dict
['extended']=yaml
.safe_dump(flavor_dict
['extended'],default_flow_style
=True,width
=256)
314 #look if flavor exist
315 if only_create_at_vim
:
316 flavor_mano_id
= flavor_dict
['uuid']
318 flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
320 flavor_mano_id
= flavors
[0]['uuid']
323 #create one by one the images of aditional disks
324 dev_image_list
=[] #list of images
325 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None:
327 for device
in flavor_dict
['extended'].get('devices',[]):
328 if "image" not in device
:
330 image_dict
={'location':device
['image'], 'name':flavor_dict
['name']+str(dev_nb
)+"-img", 'description':flavor_dict
.get('description')}
331 image_metadata_dict
= device
.get('image metadata', None)
332 image_metadata_str
= None
333 if image_metadata_dict
!= None:
334 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
335 image_dict
['metadata']=image_metadata_str
336 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
337 #print "Additional disk image id for VNFC %s: %s" % (flavor_dict['name']+str(dev_nb)+"-img", image_id)
338 dev_image_list
.append(image_id
)
340 temp_flavor_dict
['name'] = flavor_dict
['name']
341 temp_flavor_dict
['description'] = flavor_dict
.get('description',None)
342 content
= mydb
.new_row('flavors', temp_flavor_dict
, add_uuid
=True)
343 flavor_mano_id
= content
344 rollback_list
.append({"where":"mano", "what":"flavor","uuid":flavor_mano_id
})
345 #create flavor at every vim
346 if 'uuid' in flavor_dict
:
347 del flavor_dict
['uuid']
349 for vim_id
,vim
in vims
.items():
350 flavor_created
="false"
352 flavor_db
= mydb
.get_rows(FROM
="datacenters_flavors", WHERE
={'datacenter_id':vim_id
, 'flavor_id':flavor_mano_id
})
353 #look at VIM if this flavor exist SKIPPED
354 #res_vim, flavor_vim_id = vim.get_flavor_id_from_path(flavor_dict['location'])
356 # print "Error contacting VIM to know if the flavor %s existed previously." %flavor_vim_id
360 #Create the flavor in VIM
361 #Translate images at devices from MANO id to VIM id
362 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None and "devices" in flavor_dict
['extended']:
363 #make a copy of original devices
365 for device
in flavor_dict
["extended"].get("devices",[]):
368 devices_original
.append(dev
)
369 if 'image' in device
:
371 if 'image metadata' in device
:
372 del device
['image metadata']
374 for index
in range(0,len(devices_original
)) :
375 device
=devices_original
[index
]
376 if "image" not in device
:
378 image_dict
={'location':device
['image'], 'name':flavor_dict
['name']+str(dev_nb
)+"-img", 'description':flavor_dict
.get('description')}
379 image_metadata_dict
= device
.get('image metadata', None)
380 image_metadata_str
= None
381 if image_metadata_dict
!= None:
382 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
383 image_dict
['metadata']=image_metadata_str
384 image_mano_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
=return_on_error
)
385 image_dict
["uuid"]=image_mano_id
386 image_vim_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=True, return_on_error
=return_on_error
)
387 flavor_dict
["extended"]["devices"][index
]['imageRef']=image_vim_id
390 #check that this vim_id exist in VIM, if not create
391 flavor_vim_id
=flavor_db
[0]["vim_id"]
393 vim
.get_flavor(flavor_vim_id
)
394 continue #flavor exist
395 except vimconn
.vimconnException
:
397 #create flavor at vim
398 logger
.debug("nfvo.create_or_use_flavor() adding flavor to VIM %s", vim
["name"])
400 flavor_vim_id
= vim
.new_flavor(flavor_dict
)
401 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"flavor","uuid":flavor_vim_id
})
402 flavor_created
="true"
403 except vimconn
.vimconnException
as e
:
405 logger
.error("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
407 logger
.warn("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
409 #if reach here the flavor has been create or exist
410 if len(flavor_db
)==0:
411 #add new vim_id at datacenters_flavors
412 mydb
.new_row('datacenters_flavors', {'datacenter_id':vim_id
, 'flavor_id':flavor_mano_id
, 'vim_id': flavor_vim_id
, 'created':flavor_created
})
413 elif flavor_db
[0]["vim_id"]!=flavor_vim_id
:
414 #modify existing vim_id at datacenters_flavors
415 mydb
.update_rows('datacenters_flavors', UPDATE
={'vim_id':flavor_vim_id
}, WHERE
={'datacenter_id':vim_id
, 'flavor_id':flavor_mano_id
})
417 return flavor_vim_id
if only_create_at_vim
else flavor_mano_id
419 def new_vnf(mydb
, tenant_id
, vnf_descriptor
):
422 # Step 1. Check the VNF descriptor
423 check_vnf_descriptor(vnf_descriptor
)
424 # Step 2. Check tenant exist
425 if tenant_id
!= "any":
426 check_tenant(mydb
, tenant_id
)
427 if "tenant_id" in vnf_descriptor
["vnf"]:
428 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
429 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
432 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
433 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
434 vims
= get_vim(mydb
, tenant_id
)
438 # Step 4. Review the descriptor and add missing fields
439 #print vnf_descriptor
440 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
441 vnf_name
= vnf_descriptor
['vnf']['name']
442 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
443 if "physical" in vnf_descriptor
['vnf']:
444 del vnf_descriptor
['vnf']['physical']
445 #print vnf_descriptor
446 # Step 5. Check internal connections
447 # TODO: to be moved to step 1????
448 internal_connections
=vnf_descriptor
['vnf'].get('internal_connections',[])
449 for ic
in internal_connections
:
450 if len(ic
['elements'])>2 and ic
['type']=='ptp':
451 raise NfvoException("Mismatch 'type':'ptp' with {} elements at 'vnf':'internal-conections'['name':'{}']. Change 'type' to 'data'".format(len(ic
), ic
['name']),
453 elif len(ic
['elements'])==2 and ic
['type']=='data':
454 raise NfvoException("Mismatch 'type':'data' with 2 elements at 'vnf':'internal-conections'['name':'{}']. Change 'type' to 'ptp'".format(ic
['name']),
457 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
458 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
459 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
461 #For each VNFC, we add it to the VNFCDict and we create a flavor.
462 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
463 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
465 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
466 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
468 VNFCitem
["name"] = vnfc
['name']
469 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
471 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
474 myflavorDict
["name"] = vnfc
['name']+"-flv"
475 myflavorDict
["description"] = VNFCitem
["description"]
476 myflavorDict
["ram"] = vnfc
.get("ram", 0)
477 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
478 myflavorDict
["disk"] = vnfc
.get("disk", 1)
479 myflavorDict
["extended"] = {}
481 devices
= vnfc
.get("devices")
483 myflavorDict
["extended"]["devices"] = devices
486 # 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
487 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
489 # Previous code has been commented
490 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
491 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
492 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
493 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
495 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
497 # print "Error creating flavor: unknown processor model. Rollback successful."
498 # return -HTTP_Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
500 # return -HTTP_Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
501 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
503 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
504 myflavorDict
['extended']['numas'] = vnfc
['numas']
508 # Step 6.2 New flavors are created in the VIM
509 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
511 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
512 VNFCitem
["flavor_id"] = flavor_id
513 VNFCDict
[vnfc
['name']] = VNFCitem
515 logger
.debug("Creating new images in the VIM for each VNFC")
516 # Step 6.3 New images are created in the VIM
517 #For each VNFC, we must create the appropriate image.
518 #This "for" loop might be integrated with the previous one
519 #In case this integration is made, the VNFCDict might become a VNFClist.
520 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
521 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
522 image_dict
={'location':vnfc
['VNFC image'], 'name':vnfc
['name']+"-img", 'description':VNFCDict
[vnfc
['name']]['description']}
523 image_metadata_dict
= vnfc
.get('image metadata', None)
524 image_metadata_str
= None
525 if image_metadata_dict
is not None:
526 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
527 image_dict
['metadata']=image_metadata_str
528 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
529 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
530 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
531 VNFCDict
[vnfc
['name']]["image_id"] = image_id
532 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
['VNFC image']
535 # Step 7. Storing the VNF descriptor in the repository
536 if "descriptor" not in vnf_descriptor
["vnf"]:
537 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
539 # Step 8. Adding the VNF to the NFVO DB
540 vnf_id
= mydb
.new_vnf_as_a_whole(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
542 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
543 _
, message
= rollback(mydb
, vims
, rollback_list
)
544 if isinstance(e
, db_base_Exception
):
545 error_text
= "Exception at database"
546 elif isinstance(e
, KeyError):
547 error_text
= "KeyError exception "
548 e
.http_code
= HTTP_Internal_Server_Error
550 error_text
= "Exception at VIM"
551 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
552 #logger.error("start_scenario %s", error_text)
553 raise NfvoException(error_text
, e
.http_code
)
555 def get_vnf_id(mydb
, tenant_id
, vnf_id
):
556 #check valid tenant_id
557 check_tenant(mydb
, tenant_id
)
560 if tenant_id
!= "any":
561 where_or
["tenant_id"] = tenant_id
562 where_or
["public"] = True
563 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
566 filter_keys
= ('uuid','name','description','public', "tenant_id", "created_at")
567 filtered_content
= dict( (k
,v
) for k
,v
in vnf
.iteritems() if k
in filter_keys
)
568 #change_keys_http2db(filtered_content, http2db_vnf, reverse=True)
569 data
={'vnf' : filtered_content
}
571 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id',
572 SELECT
=('vms.uuid as uuid','vms.name as name', 'vms.description as description'),
573 WHERE
={'vnfs.uuid': vnf_id
} )
575 raise NfvoException("vnf '{}' not found".format(vnf_id
), HTTP_Not_Found
)
577 data
['vnf']['VNFC'] = content
579 content
= mydb
.get_rows(FROM
='vnfs join nets on vnfs.uuid=nets.vnf_id',
580 SELECT
=('nets.uuid as uuid','nets.name as name','nets.description as description', 'nets.type as type', 'nets.multipoint as multipoint'),
581 WHERE
={'vnfs.uuid': vnf_id
} )
582 data
['vnf']['nets'] = content
584 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces on vms.uuid=interfaces.vm_id',\
585 SELECT
=('interfaces.uuid as uuid','interfaces.external_name as external_name', 'vms.name as vm_name', 'interfaces.vm_id as vm_id', \
586 'interfaces.internal_name as internal_name', 'interfaces.type as type', 'interfaces.vpci as vpci','interfaces.bw as bw'),\
587 WHERE
={'vnfs.uuid': vnf_id
},
588 WHERE_NOT
={'interfaces.external_name': None} )
590 data
['vnf']['external-connections'] = content
594 def delete_vnf(mydb
,tenant_id
,vnf_id
,datacenter
=None,vim_tenant
=None):
596 if tenant_id
!= "any":
597 check_tenant(mydb
, tenant_id
)
598 # Get the URL of the VIM from the nfvo_tenant and the datacenter
599 vims
= get_vim(mydb
, tenant_id
)
603 # Checking if it is a valid uuid and, if not, getting the uuid assuming that the name was provided"
605 if tenant_id
!= "any":
606 where_or
["tenant_id"] = tenant_id
607 where_or
["public"] = True
608 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
611 # "Getting the list of flavors and tenants of the VNF"
612 flavorList
= get_flavorlist(mydb
, vnf_id
)
613 if len(flavorList
)==0:
614 logger
.warn("delete_vnf error. No flavors found for the VNF id '%s'", vnf_id
)
616 imageList
= get_imagelist(mydb
, vnf_id
)
617 if len(imageList
)==0:
618 logger
.warn( "delete_vnf error. No images found for the VNF id '%s'", vnf_id
)
620 deleted
= mydb
.delete_row_by_id('vnfs', vnf_id
)
622 raise NfvoException("vnf '{}' not found".format(vnf_id
), HTTP_Not_Found
)
625 for flavor
in flavorList
:
626 #check if flavor is used by other vnf
628 c
= mydb
.get_rows(FROM
='vms', WHERE
={'flavor_id':flavor
} )
630 logger
.debug("Flavor '%s' not deleted because it is being used by another VNF", flavor
)
632 #flavor not used, must be deleted
634 c
= mydb
.get_rows(FROM
='datacenters_flavors', WHERE
={'flavor_id':flavor
})
636 if flavor_vim
["datacenter_id"] not in vims
:
638 if flavor_vim
['created']=='false': #skip this flavor because not created by openmano
640 myvim
=vims
[ flavor_vim
["datacenter_id"] ]
642 myvim
.delete_flavor(flavor_vim
["vim_id"])
643 except vimconn
.vimconnNotFoundException
as e
:
644 logger
.warn("VIM flavor %s not exist at datacenter %s", flavor_vim
["vim_id"], flavor_vim
["datacenter_id"] )
645 except vimconn
.vimconnException
as e
:
646 logger
.error("Not possible to delete VIM flavor %s from datacenter %s: %s %s",
647 flavor_vim
["vim_id"], flavor_vim
["datacenter_id"], type(e
).__name
__, str(e
))
648 undeletedItems
.append("flavor {} from VIM {}".format(flavor_vim
["vim_id"], flavor_vim
["datacenter_id"] ))
649 #delete flavor from Database, using table flavors and with cascade foreign key also at datacenters_flavors
650 mydb
.delete_row_by_id('flavors', flavor
)
651 except db_base_Exception
as e
:
652 logger
.error("delete_vnf_error. Not possible to get flavor details and delete '%s'. %s", flavor
, str(e
))
653 undeletedItems
.append("flavor %s" % flavor
)
656 for image
in imageList
:
658 #check if image is used by other vnf
659 c
= mydb
.get_rows(FROM
='vms', WHERE
={'image_id':image
} )
661 logger
.debug("Image '%s' not deleted because it is being used by another VNF", image
)
663 #image not used, must be deleted
665 c
= mydb
.get_rows(FROM
='datacenters_images', WHERE
={'image_id':image
})
667 if image_vim
["datacenter_id"] not in vims
:
669 if image_vim
['created']=='false': #skip this image because not created by openmano
671 myvim
=vims
[ image_vim
["datacenter_id"] ]
673 myvim
.delete_image(image_vim
["vim_id"])
674 except vimconn
.vimconnNotFoundException
as e
:
675 logger
.warn("VIM image %s not exist at datacenter %s", image_vim
["vim_id"], image_vim
["datacenter_id"] )
676 except vimconn
.vimconnException
as e
:
677 logger
.error("Not possible to delete VIM image %s from datacenter %s: %s %s",
678 image_vim
["vim_id"], image_vim
["datacenter_id"], type(e
).__name
__, str(e
))
679 undeletedItems
.append("image {} from VIM {}".format(image_vim
["vim_id"], image_vim
["datacenter_id"] ))
680 #delete image from Database, using table images and with cascade foreign key also at datacenters_images
681 mydb
.delete_row_by_id('images', image
)
682 except db_base_Exception
as e
:
683 logger
.error("delete_vnf_error. Not possible to get image details and delete '%s'. %s", image
, str(e
))
684 undeletedItems
.append("image %s" % image
)
686 return vnf_id
+ " " + vnf
["name"]
688 # return "delete_vnf. Undeleted: %s" %(undeletedItems)
690 def get_hosts_info(mydb
, nfvo_tenant_id
, datacenter_name
=None):
691 result
, vims
= get_vim(mydb
, nfvo_tenant_id
, None, datacenter_name
)
695 return -HTTP_Not_Found
, "datacenter '%s' not found" % datacenter_name
696 myvim
= vims
.values()[0]
697 result
,servers
= myvim
.get_hosts_info()
699 return result
, servers
700 topology
= {'name':myvim
['name'] , 'servers': servers
}
701 return result
, topology
703 def get_hosts(mydb
, nfvo_tenant_id
):
704 vims
= get_vim(mydb
, nfvo_tenant_id
)
706 raise NfvoException("No datacenter found for tenant '{}'".format(str(nfvo_tenant_id
)), HTTP_Not_Found
)
708 #print "nfvo.datacenter_action() error. Several datacenters found"
709 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
710 myvim
= vims
.values()[0]
712 hosts
= myvim
.get_hosts()
713 logger
.debug('VIM hosts response: '+ yaml
.safe_dump(hosts
, indent
=4, default_flow_style
=False))
715 datacenter
= {'Datacenters': [ {'name':myvim
['name'],'servers':[]} ] }
717 server
={'name':host
['name'], 'vms':[]}
718 for vm
in host
['instances']:
719 #get internal name and model
721 c
= mydb
.get_rows(SELECT
=('name',), FROM
='instance_vms as iv join vms on iv.vm_id=vms.uuid',\
722 WHERE
={'vim_vm_id':vm
['id']} )
724 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' not found at tidnfvo".format(vm
['id']))
726 server
['vms'].append( {'name':vm
['name'] , 'model':c
[0]['name']} )
728 except db_base_Exception
as e
:
729 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' error {}".format(vm
['id'], str(e
)))
730 datacenter
['Datacenters'][0]['servers'].append(server
)
731 #return -400, "en construccion"
733 #print 'datacenters '+ json.dumps(datacenter, indent=4)
735 except vimconn
.vimconnException
as e
:
736 raise NfvoException("Not possible to get_host_list from VIM: {}".format(str(e
)), e
.http_code
)
738 def new_scenario(mydb
, tenant_id
, topo
):
740 # result, vims = get_vim(mydb, tenant_id)
742 # return result, vims
744 if tenant_id
!= "any":
745 check_tenant(mydb
, tenant_id
)
746 if "tenant_id" in topo
:
747 if topo
["tenant_id"] != tenant_id
:
748 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(topo
["tenant_id"], tenant_id
),
753 #1.1: get VNFs and external_networks (other_nets).
755 other_nets
={} #external_networks, bridge_networks and data_networkds
756 nodes
= topo
['topology']['nodes']
757 for k
in nodes
.keys():
758 if nodes
[k
]['type'] == 'VNF':
760 vnfs
[k
]['ifaces'] = {}
761 elif nodes
[k
]['type'] == 'other_network' or nodes
[k
]['type'] == 'external_network':
762 other_nets
[k
] = nodes
[k
]
763 other_nets
[k
]['external']=True
764 elif nodes
[k
]['type'] == 'network':
765 other_nets
[k
] = nodes
[k
]
766 other_nets
[k
]['external']=False
769 #1.2: Check that VNF are present at database table vnfs. Insert uuid, description and external interfaces
770 for name
,vnf
in vnfs
.items():
772 where_or
={"tenant_id": tenant_id
, 'public': "true"}
774 error_pos
= "'topology':'nodes':'" + name
+ "'"
776 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
777 where
['uuid'] = vnf
['vnf_id']
778 if 'VNF model' in vnf
:
779 error_text
+= " 'VNF model' " + vnf
['VNF model']
780 where
['name'] = vnf
['VNF model']
782 raise NfvoException("Descriptor need a 'vnf_id' or 'VNF model' field at " + error_pos
, HTTP_Bad_Request
)
784 vnf_db
= mydb
.get_rows(SELECT
=('uuid','name','description'),
790 raise NfvoException("unknown" + error_text
+ " at " + error_pos
, HTTP_Not_Found
)
792 raise NfvoException("more than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", HTTP_Conflict
)
793 vnf
['uuid']=vnf_db
[0]['uuid']
794 vnf
['description']=vnf_db
[0]['description']
795 #get external interfaces
796 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name','i.uuid as iface_uuid', 'i.type as type'),
797 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
798 WHERE
={'vnfs.uuid':vnf
['uuid']}, WHERE_NOT
={'external_name':None} )
799 for ext_iface
in ext_ifaces
:
800 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type':ext_iface
['type']}
802 #1.4 get list of connections
803 conections
= topo
['topology']['connections']
805 for k
in conections
.keys():
806 if type(conections
[k
]['nodes'])==dict: #dict with node:iface pairs
807 ifaces_list
= conections
[k
]['nodes'].items()
808 elif type(conections
[k
]['nodes'])==list: #list with dictionary
810 conection_pair_list
= map(lambda x
: x
.items(), conections
[k
]['nodes'] )
811 for k2
in conection_pair_list
:
814 con_type
= conections
[k
].get("type", "link")
815 if con_type
!= "link":
817 raise NfvoException("Format error. Reapeted network name at 'topology':'connections':'{}'".format(str(k
)), HTTP_Bad_Request
)
818 other_nets
[k
] = {'external': False}
819 if conections
[k
].get("graph"):
820 other_nets
[k
]["graph"] = conections
[k
]["graph"]
821 ifaces_list
.append( (k
, None) )
824 if con_type
== "external_network":
825 other_nets
[k
]['external'] = True
826 if conections
[k
].get("model"):
827 other_nets
[k
]["model"] = conections
[k
]["model"]
829 other_nets
[k
]["model"] = k
830 if con_type
== "dataplane_net" or con_type
== "bridge_net":
831 other_nets
[k
]["model"] = con_type
834 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)
835 #print set(ifaces_list)
836 #check valid VNF and iface names
837 for iface
in ifaces_list
:
838 if iface
[0] not in vnfs
and iface
[0] not in other_nets
:
839 raise NfvoException("format error. Invalid VNF name at 'topology':'connections':'{}':'nodes':'{}'".format(
840 str(k
), iface
[0]), HTTP_Not_Found
)
841 if iface
[0] in vnfs
and iface
[1] not in vnfs
[ iface
[0] ]['ifaces']:
842 raise NfvoException("format error. Invalid interface name at 'topology':'connections':'{}':'nodes':'{}':'{}'".format(
843 str(k
), iface
[0], iface
[1]), HTTP_Not_Found
)
845 #1.5 unify connections from the pair list to a consolidated list
847 while index
< len(conections_list
):
849 while index2
< len(conections_list
):
850 if len(conections_list
[index
] & conections_list
[index2
])>0: #common interface, join nets
851 conections_list
[index
] |
= conections_list
[index2
]
852 del conections_list
[index2
]
855 conections_list
[index
] = list(conections_list
[index
]) # from set to list again
857 #for k in conections_list:
862 #1.6 Delete non external nets
863 # for k in other_nets.keys():
864 # if other_nets[k]['model']=='bridge' or other_nets[k]['model']=='dataplane_net' or other_nets[k]['model']=='bridge_net':
865 # for con in conections_list:
867 # for index in range(0,len(con)):
868 # if con[index][0] == k: delete_indexes.insert(0,index) #order from higher to lower
869 # for index in delete_indexes:
872 #1.7: Check external_ports are present at database table datacenter_nets
873 for k
,net
in other_nets
.items():
874 error_pos
= "'topology':'nodes':'" + k
+ "'"
875 if net
['external']==False:
876 if 'name' not in net
:
878 if 'model' not in net
:
879 raise NfvoException("needed a 'model' at " + error_pos
, HTTP_Bad_Request
)
880 if net
['model']=='bridge_net':
881 net
['type']='bridge';
882 elif net
['model']=='dataplane_net':
885 raise NfvoException("unknown 'model' '"+ net
['model'] +"' at " + error_pos
, HTTP_Not_Found
)
887 #IF we do not want to check that external network exist at datacenter
892 # if 'net_id' in net:
893 # error_text += " 'net_id' " + net['net_id']
894 # WHERE_['uuid'] = net['net_id']
896 # error_text += " 'model' " + net['model']
897 # WHERE_['name'] = net['model']
898 # if len(WHERE_) == 0:
899 # return -HTTP_Bad_Request, "needed a 'net_id' or 'model' at " + error_pos
900 # r,net_db = mydb.get_table(SELECT=('uuid','name','description','type','shared'),
901 # FROM='datacenter_nets', WHERE=WHERE_ )
903 # print "nfvo.new_scenario Error getting datacenter_nets",r,net_db
905 # print "nfvo.new_scenario Error" +error_text+ " is not present at database"
906 # return -HTTP_Bad_Request, "unknown " +error_text+ " at " + error_pos
908 # print "nfvo.new_scenario Error more than one external_network for " +error_text+ " is present at database"
909 # return -HTTP_Bad_Request, "more than one external_network for " +error_text+ "at "+ error_pos + " Concrete with 'net_id'"
910 # other_nets[k].update(net_db[0])
913 net_nb
=0 #Number of nets
914 for con
in conections_list
:
915 #check if this is connected to a external net
919 for index
in range(0,len(con
)):
920 #check if this is connected to a external net
921 for net_key
in other_nets
.keys():
922 if con
[index
][0]==net_key
:
923 if other_net_index
>=0:
924 error_text
="There is some interface connected both to net '%s' and net '%s'" % (con
[other_net_index
][0], net_key
)
925 #print "nfvo.new_scenario " + error_text
926 raise NfvoException(error_text
, HTTP_Bad_Request
)
928 other_net_index
= index
931 #print "other_net_index", other_net_index
933 if other_net_index
>=0:
934 del con
[other_net_index
]
935 #IF we do not want to check that external network exist at datacenter
936 if other_nets
[net_target
]['external'] :
937 if "name" not in other_nets
[net_target
]:
938 other_nets
[net_target
]['name'] = other_nets
[net_target
]['model']
939 if other_nets
[net_target
]["type"] == "external_network":
940 if vnfs
[ con
[0][0] ]['ifaces'][ con
[0][1] ]["type"] == "data":
941 other_nets
[net_target
]["type"] = "data"
943 other_nets
[net_target
]["type"] = "bridge"
945 # if other_nets[net_target]['external'] :
946 # 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
947 # if type_=='data' and other_nets[net_target]['type']=="ptp":
948 # error_text = "Error connecting %d nodes on a not multipoint net %s" % (len(con), net_target)
949 # print "nfvo.new_scenario " + error_text
950 # return -HTTP_Bad_Request, error_text
953 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
956 net_type_bridge
=False
958 net_target
= "__-__net"+str(net_nb
)
959 net_list
[net_target
] = {'name': "net-"+str(net_nb
), 'description':"net-%s in scenario %s" %(net_nb
,topo
['name']),
962 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
963 iface_type
= vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['type']
964 if iface_type
=='mgmt' or iface_type
=='bridge':
965 net_type_bridge
= True
968 if net_type_bridge
and net_type_data
:
969 error_text
= "Error connection interfaces of bridge type with data type. Firs node %s, iface %s" % (iface
[0], iface
[1])
970 #print "nfvo.new_scenario " + error_text
971 raise NfvoException(error_text
, HTTP_Bad_Request
)
972 elif net_type_bridge
:
975 type_
='data' if len(con
)>2 else 'ptp'
976 net_list
[net_target
]['type'] = type_
979 error_text
= "Error connection node %s : %s does not match any VNF or interface" % (iface
[0], iface
[1])
980 #print "nfvo.new_scenario " + error_text
982 raise NfvoException(error_text
, HTTP_Bad_Request
)
984 #1.8: Connect to management net all not already connected interfaces of type 'mgmt'
985 #1.8.1 obtain management net
986 mgmt_net
= mydb
.get_rows(SELECT
=('uuid','name','description','type','shared'),
987 FROM
='datacenter_nets', WHERE
={'name':'mgmt'} )
988 #1.8.2 check all interfaces from all vnfs
991 for vnf
in vnfs
.values():
992 for iface
in vnf
['ifaces'].values():
993 if iface
['type']=='mgmt' and 'net_key' not in iface
:
995 iface
['net_key'] = 'mgmt'
997 if add_mgmt_net
and 'mgmt' not in net_list
:
998 net_list
['mgmt']=mgmt_net
[0]
999 net_list
['mgmt']['external']=True
1000 net_list
['mgmt']['graph']={'visible':False}
1002 net_list
.update(other_nets
)
1004 #print 'net_list', net_list
1009 #2: insert scenario. filling tables scenarios,sce_vnfs,sce_interfaces,sce_nets
1010 c
= mydb
.new_scenario( { 'vnfs':vnfs
, 'nets':net_list
,
1011 'tenant_id':tenant_id
, 'name':topo
['name'],
1012 'description':topo
.get('description',topo
['name']),
1013 'public': topo
.get('public', False)
1018 def new_scenario_v02(mydb
, tenant_id
, scenario_dict
):
1019 scenario
= scenario_dict
["scenario"]
1020 if tenant_id
!= "any":
1021 check_tenant(mydb
, tenant_id
)
1022 if "tenant_id" in scenario
:
1023 if scenario
["tenant_id"] != tenant_id
:
1024 print "nfvo.new_scenario_v02() tenant '%s' not found" % tenant_id
1025 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(
1026 scenario
["tenant_id"], tenant_id
), HTTP_Unauthorized
)
1030 #1: Check that VNF are present at database table vnfs and update content into scenario dict
1031 for name
,vnf
in scenario
["vnfs"].iteritems():
1033 where_or
={"tenant_id": tenant_id
, 'public': "true"}
1035 error_pos
= "'topology':'nodes':'" + name
+ "'"
1037 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
1038 where
['uuid'] = vnf
['vnf_id']
1039 if 'vnf_name' in vnf
:
1040 error_text
+= " 'vnf_name' " + vnf
['vnf_name']
1041 where
['name'] = vnf
['vnf_name']
1043 raise NfvoException("Needed a 'vnf_id' or 'VNF model' at " + error_pos
, HTTP_Bad_Request
)
1044 vnf_db
= mydb
.get_rows(SELECT
=('uuid','name','description'),
1050 raise NfvoException("Unknown" + error_text
+ " at " + error_pos
, HTTP_Not_Found
)
1052 raise NfvoException("More than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", HTTP_Conflict
)
1053 vnf
['uuid']=vnf_db
[0]['uuid']
1054 vnf
['description']=vnf_db
[0]['description']
1056 #get external interfaces
1057 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name','i.uuid as iface_uuid', 'i.type as type'),
1058 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
1059 WHERE
={'vnfs.uuid':vnf
['uuid']}, WHERE_NOT
={'external_name':None} )
1060 for ext_iface
in ext_ifaces
:
1061 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type':ext_iface
['type']}
1063 #2: Insert net_key at every vnf interface
1064 for net_name
,net
in scenario
["networks"].iteritems():
1065 net_type_bridge
=False
1067 for iface_dict
in net
["interfaces"]:
1068 for vnf
,iface
in iface_dict
.iteritems():
1069 if vnf
not in scenario
["vnfs"]:
1070 error_text
= "Error at 'networks':'%s':'interfaces' VNF '%s' not match any VNF at 'vnfs'" % (net_name
, vnf
)
1071 #print "nfvo.new_scenario_v02 " + error_text
1072 raise NfvoException(error_text
, HTTP_Not_Found
)
1073 if iface
not in scenario
["vnfs"][vnf
]['ifaces']:
1074 error_text
= "Error at 'networks':'%s':'interfaces':'%s' interface not match any VNF interface" % (net_name
, iface
)
1075 #print "nfvo.new_scenario_v02 " + error_text
1076 raise NfvoException(error_text
, HTTP_Bad_Request
)
1077 if "net_key" in scenario
["vnfs"][vnf
]['ifaces'][iface
]:
1078 error_text
= "Error at 'networks':'%s':'interfaces':'%s' interface already connected at network '%s'" \
1079 % (net_name
, iface
,scenario
["vnfs"][vnf
]['ifaces'][iface
]['net_key'])
1080 #print "nfvo.new_scenario_v02 " + error_text
1081 raise NfvoException(error_text
, HTTP_Bad_Request
)
1082 scenario
["vnfs"][vnf
]['ifaces'][ iface
]['net_key'] = net_name
1083 iface_type
= scenario
["vnfs"][vnf
]['ifaces'][iface
]['type']
1084 if iface_type
=='mgmt' or iface_type
=='bridge':
1085 net_type_bridge
= True
1087 net_type_data
= True
1088 if net_type_bridge
and net_type_data
:
1089 error_text
= "Error connection interfaces of bridge type and data type at 'networks':'%s':'interfaces'" % (net_name
)
1090 #print "nfvo.new_scenario " + error_text
1091 raise NfvoException(error_text
, HTTP_Bad_Request
)
1092 elif net_type_bridge
:
1095 type_
='data' if len(net
["interfaces"])>2 else 'ptp'
1097 net
['name'] = net_name
1098 net
['external'] = net
.get('external', False)
1100 #3: insert at database
1101 scenario
["nets"] = scenario
["networks"]
1102 scenario
['tenant_id'] = tenant_id
1103 scenario_id
= mydb
.new_scenario( scenario
)
1106 def edit_scenario(mydb
, tenant_id
, scenario_id
, data
):
1107 data
["uuid"] = scenario_id
1108 data
["tenant_id"] = tenant_id
1109 c
= mydb
.edit_scenario( data
)
1112 def start_scenario(mydb
, tenant_id
, scenario_id
, instance_scenario_name
, instance_scenario_description
, datacenter
=None,vim_tenant
=None, startvms
=True):
1113 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
1114 datacenter_id
= None
1115 datacenter_name
=None
1116 if datacenter
!= None:
1117 if utils
.check_valid_uuid(datacenter
):
1118 datacenter_id
= datacenter
1120 datacenter_name
= datacenter
1121 vims
= get_vim(mydb
, tenant_id
, datacenter_id
, datacenter_name
, vim_tenant
)
1123 raise NfvoException("datacenter '{}' not found".format(datacenter
), HTTP_Not_Found
)
1125 #logger.error("nfvo.datacenter_new_netmap() error. Several datacenters found")
1126 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
1127 myvim
= vims
.values()[0]
1128 myvim_tenant
= myvim
['tenant_id']
1129 datacenter_id
= myvim
['id']
1130 datacenter_name
= myvim
['name']
1131 datacenter_tenant_id
= myvim
['config']['datacenter_tenant_id']
1134 #print "Checking that the scenario_id exists and getting the scenario dictionary"
1135 scenarioDict
= mydb
.get_scenario(scenario_id
, tenant_id
, datacenter_id
)
1136 scenarioDict
['datacenter_tenant_id'] = datacenter_tenant_id
1137 scenarioDict
['datacenter_id'] = datacenter_id
1138 #print '================scenarioDict======================='
1139 #print json.dumps(scenarioDict, indent=4)
1140 #print 'BEGIN launching instance scenario "%s" based on "%s"' % (instance_scenario_name,scenarioDict['name'])
1142 logger
.debug("start_scenario Scenario %s: consisting of %d VNF(s)", scenarioDict
['name'],len(scenarioDict
['vnfs']))
1143 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
1145 auxNetDict
= {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
1146 auxNetDict
['scenario'] = {}
1148 logger
.debug("start_scenario 1. Creating new nets (sce_nets) in the VIM")
1149 for sce_net
in scenarioDict
['nets']:
1150 #print "Net name: %s. Description: %s" % (sce_net["name"], sce_net["description"])
1152 myNetName
= "%s.%s" % (instance_scenario_name
, sce_net
['name'])
1153 myNetName
= myNetName
[0:255] #limit length
1154 myNetType
= sce_net
['type']
1156 myNetDict
["name"] = myNetName
1157 myNetDict
["type"] = myNetType
1158 myNetDict
["tenant_id"] = myvim_tenant
1160 #We should use the dictionary as input parameter for new_network
1162 if not sce_net
["external"]:
1163 network_id
= myvim
.new_network(myNetName
, myNetType
)
1164 #print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id)
1165 sce_net
['vim_id'] = network_id
1166 auxNetDict
['scenario'][sce_net
['uuid']] = network_id
1167 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
1169 if sce_net
['vim_id'] == None:
1170 error_text
= "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name
, sce_net
['name'])
1171 _
, message
= rollback(mydb
, vims
, rollbackList
)
1172 logger
.error("nfvo.start_scenario: %s", error_text
)
1173 raise NfvoException(error_text
, HTTP_Bad_Request
)
1174 logger
.debug("Using existent VIM network for scenario %s. Network id %s", scenarioDict
['name'],sce_net
['vim_id'])
1175 auxNetDict
['scenario'][sce_net
['uuid']] = sce_net
['vim_id']
1177 logger
.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM")
1178 #For each vnf net, we create it and we add it to instanceNetlist.
1179 for sce_vnf
in scenarioDict
['vnfs']:
1180 for net
in sce_vnf
['nets']:
1181 #print "Net name: %s. Description: %s" % (net["name"], net["description"])
1183 myNetName
= "%s.%s" % (instance_scenario_name
,net
['name'])
1184 myNetName
= myNetName
[0:255] #limit length
1185 myNetType
= net
['type']
1187 myNetDict
["name"] = myNetName
1188 myNetDict
["type"] = myNetType
1189 myNetDict
["tenant_id"] = myvim_tenant
1192 #We should use the dictionary as input parameter for new_network
1193 network_id
= myvim
.new_network(myNetName
, myNetType
)
1194 #print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id)
1195 net
['vim_id'] = network_id
1196 if sce_vnf
['uuid'] not in auxNetDict
:
1197 auxNetDict
[sce_vnf
['uuid']] = {}
1198 auxNetDict
[sce_vnf
['uuid']][net
['uuid']] = network_id
1199 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
1201 #print "auxNetDict:"
1202 #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
1204 logger
.debug("start_scenario 3. Creating new vm instances in the VIM")
1205 #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
1207 for sce_vnf
in scenarioDict
['vnfs']:
1208 for vm
in sce_vnf
['vms']:
1211 #myVMDict['name'] = "%s-%s-%s" % (scenarioDict['name'],sce_vnf['name'], vm['name'])
1212 myVMDict
['name'] = "%s.%s.%d" % (instance_scenario_name
,sce_vnf
['name'],i
)
1213 #myVMDict['description'] = vm['description']
1214 myVMDict
['description'] = myVMDict
['name'][0:99]
1216 myVMDict
['start'] = "no"
1217 myVMDict
['name'] = myVMDict
['name'][0:255] #limit name length
1218 #print "VM name: %s. Description: %s" % (myVMDict['name'], myVMDict['name'])
1220 #create image at vim in case it not exist
1221 image_dict
= mydb
.get_table_by_uuid_name("images", vm
['image_id'])
1222 image_id
= create_or_use_image(mydb
, vims
, image_dict
, [], True)
1223 vm
['vim_image_id'] = image_id
1225 #create flavor at vim in case it not exist
1226 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
1227 if flavor_dict
['extended']!=None:
1228 flavor_dict
['extended']= yaml
.load(flavor_dict
['extended'])
1229 flavor_id
= create_or_use_flavor(mydb
, vims
, flavor_dict
, [], True)
1230 vm
['vim_flavor_id'] = flavor_id
1233 myVMDict
['imageRef'] = vm
['vim_image_id']
1234 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
1235 myVMDict
['networks'] = []
1236 for iface
in vm
['interfaces']:
1238 if iface
['type']=="data":
1239 netDict
['type'] = iface
['model']
1240 elif "model" in iface
and iface
["model"]!=None:
1241 netDict
['model']=iface
['model']
1242 #TODO in future, remove this because mac_address will not be set, and the type of PV,VF is obtained from iterface table model
1243 #discover type of interface looking at flavor
1244 for numa
in flavor_dict
.get('extended',{}).get('numas',[]):
1245 for flavor_iface
in numa
.get('interfaces',[]):
1246 if flavor_iface
.get('name') == iface
['internal_name']:
1247 if flavor_iface
['dedicated'] == 'yes':
1248 netDict
['type']="PF" #passthrough
1249 elif flavor_iface
['dedicated'] == 'no':
1250 netDict
['type']="VF" #siov
1251 elif flavor_iface
['dedicated'] == 'yes:sriov':
1252 netDict
['type']="VFnotShared" #sriov but only one sriov on the PF
1253 netDict
["mac_address"] = flavor_iface
.get("mac_address")
1255 netDict
["use"]=iface
['type']
1256 if netDict
["use"]=="data" and not netDict
.get("type"):
1257 #print "netDict", netDict
1258 #print "iface", iface
1259 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'])
1260 if flavor_dict
.get('extended')==None:
1261 raise NfvoException(e_text
+ "After database migration some information is not available. \
1262 Try to delete and create the scenarios and VNFs again", HTTP_Conflict
)
1264 raise NfvoException(e_text
, HTTP_Internal_Server_Error
)
1265 if netDict
["use"]=="mgmt" or netDict
["use"]=="bridge":
1266 netDict
["type"]="virtual"
1267 if "vpci" in iface
and iface
["vpci"] is not None:
1268 netDict
['vpci'] = iface
['vpci']
1269 if "mac" in iface
and iface
["mac"] is not None:
1270 netDict
['mac_address'] = iface
['mac']
1271 netDict
['name'] = iface
['internal_name']
1272 if iface
['net_id'] is None:
1273 for vnf_iface
in sce_vnf
["interfaces"]:
1276 if vnf_iface
['interface_id']==iface
['uuid']:
1277 netDict
['net_id'] = auxNetDict
['scenario'][ vnf_iface
['sce_net_id'] ]
1280 netDict
['net_id'] = auxNetDict
[ sce_vnf
['uuid'] ][ iface
['net_id'] ]
1281 #skip bridge ifaces not connected to any net
1282 #if 'net_id' not in netDict or netDict['net_id']==None:
1284 myVMDict
['networks'].append(netDict
)
1285 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
1286 #print myVMDict['name']
1287 #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
1288 #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
1289 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
1290 vm_id
= myvim
.new_vminstance(myVMDict
['name'],myVMDict
['description'],myVMDict
.get('start', None),
1291 myVMDict
['imageRef'],myVMDict
['flavorRef'],myVMDict
['networks'])
1292 #print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id)
1293 vm
['vim_id'] = vm_id
1294 rollbackList
.append({'what':'vm','where':'vim','vim_id':datacenter_id
,'uuid':vm_id
})
1295 #put interface uuid back to scenario[vnfs][vms[[interfaces]
1296 for net
in myVMDict
['networks']:
1298 for iface
in vm
['interfaces']:
1299 if net
["name"]==iface
["internal_name"]:
1300 iface
["vim_id"]=net
["vim_id"]
1303 logger
.debug("start scenario Deployment done")
1304 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
1305 #r,c = mydb.new_instance_scenario_as_a_whole(nfvo_tenant,scenarioDict['name'],scenarioDict)
1306 instance_id
= mydb
.new_instance_scenario_as_a_whole(tenant_id
,instance_scenario_name
, instance_scenario_description
, scenarioDict
)
1307 return mydb
.get_instance_scenario(instance_id
)
1309 except (db_base_Exception
, vimconn
.vimconnException
) as e
:
1310 _
, message
= rollback(mydb
, vims
, rollbackList
)
1311 if isinstance(e
, db_base_Exception
):
1312 error_text
= "Exception at database"
1314 error_text
= "Exception at VIM"
1315 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1316 #logger.error("start_scenario %s", error_text)
1317 raise NfvoException(error_text
, e
.http_code
)
1319 def create_instance(mydb
, tenant_id
, instance_dict
):
1320 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
1321 scenario
= instance_dict
["scenario"]
1322 datacenter_id
= None
1323 datacenter_name
=None
1324 datacenter
= instance_dict
.get("datacenter")
1326 if utils
.check_valid_uuid(datacenter
):
1327 datacenter_id
= datacenter
1329 datacenter_name
= datacenter
1330 vims
= get_vim(mydb
, tenant_id
, datacenter_id
, datacenter_name
, vim_tenant
=None)
1332 raise NfvoException("datacenter '{}' not found".format(str(datacenter
)), HTTP_Not_Found
)
1334 #print "nfvo.datacenter_action() error. Several datacenters found"
1335 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
1336 myvim
= vims
.values()[0]
1337 #myvim_tenant = myvim['tenant_id']
1338 datacenter_id
= myvim
['id']
1339 datacenter_name
= myvim
['name']
1340 datacenter_tenant_id
= myvim
['config']['datacenter_tenant_id']
1343 #print "Checking that the scenario exists and getting the scenario dictionary"
1344 scenarioDict
= mydb
.get_scenario(scenario
, tenant_id
, datacenter_id
)
1345 scenarioDict
['datacenter_tenant_id'] = datacenter_tenant_id
1346 scenarioDict
['datacenter_id'] = datacenter_id
1348 auxNetDict
= {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
1349 auxNetDict
['scenario'] = {}
1351 #print "scenario dict: ",yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
1352 instance_name
= instance_dict
["name"]
1353 instance_description
= instance_dict
.get("description")
1355 #0 check correct parameters
1356 for descriptor_net
in instance_dict
.get("networks",{}).keys():
1358 for scenario_net
in scenarioDict
['nets']:
1359 if descriptor_net
== scenario_net
["name"]:
1363 raise NfvoException("Invalid scenario network name '{}' at instance:networks".format(descriptor_net
), HTTP_Bad_Request
)
1364 for descriptor_vnf
in instance_dict
.get("vnfs",{}).keys():
1366 for scenario_vnf
in scenarioDict
['vnfs']:
1367 if descriptor_vnf
== scenario_vnf
['name']:
1371 raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(descriptor_vnf
), HTTP_Bad_Request
)
1373 #1. Creating new nets (sce_nets) in the VIM"
1374 for sce_net
in scenarioDict
['nets']:
1375 descriptor_net
= instance_dict
.get("networks",{}).get(sce_net
["name"],{})
1376 net_name
= descriptor_net
.get("name")
1377 net_type
= sce_net
['type']
1378 lookfor_filter
= {'admin_state_up': True, 'status': 'ACTIVE'} #'shared': True
1379 if sce_net
["external"]:
1381 net_name
= sce_net
["name"]
1382 if "netmap-use" in descriptor_net
or "netmap-create" in descriptor_net
:
1383 create_network
= False
1384 lookfor_network
= False
1385 if "netmap-use" in descriptor_net
:
1386 lookfor_network
= True
1387 if utils
.check_valid_uuid(descriptor_net
["netmap-use"]):
1388 filter_text
= "scenario id '%s'" % descriptor_net
["netmap-use"]
1389 lookfor_filter
["id"] = descriptor_net
["netmap-use"]
1391 filter_text
= "scenario name '%s'" % descriptor_net
["netmap-use"]
1392 lookfor_filter
["name"] = descriptor_net
["netmap-use"]
1393 if "netmap-create" in descriptor_net
:
1394 create_network
= True
1395 net_vim_name
= net_name
1396 if descriptor_net
["netmap-create"]:
1397 net_vim_name
= descriptor_net
["netmap-create"]
1399 elif sce_net
['vim_id'] != None:
1400 #there is a netmap at datacenter_nets database
1401 create_network
= False
1402 lookfor_network
= True
1403 lookfor_filter
["id"] = sce_net
['vim_id']
1404 filter_text
= "vim_id '%s' datacenter_netmap name '%s'. Try to reload vims with datacenter-net-update" % (sce_net
['vim_id'], sce_net
["name"])
1405 #look for network at datacenter and return error
1407 #There is not a netmap, look at datacenter for a net with this name and create if not found
1408 create_network
= True
1409 lookfor_network
= True
1410 lookfor_filter
["name"] = sce_net
["name"]
1411 net_vim_name
= sce_net
["name"]
1412 filter_text
= "scenario name '%s'" % sce_net
["name"]
1415 net_name
= "%s.%s" %(instance_name
, sce_net
["name"])
1416 net_name
= net_name
[:255] #limit length
1417 net_vim_name
= net_name
1418 create_network
= True
1419 lookfor_network
= False
1422 vim_nets
= myvim
.get_network_list(filter_dict
=lookfor_filter
)
1423 if len(vim_nets
) > 1:
1424 raise NfvoException("More than one candidate VIM network found for " + filter_text
, HTTP_Bad_Request
)
1425 elif len(vim_nets
) == 0:
1426 if not create_network
:
1427 raise NfvoException("No candidate VIM network found for " + filter_text
, HTTP_Bad_Request
)
1429 sce_net
['vim_id'] = vim_nets
[0]['id']
1430 auxNetDict
['scenario'][sce_net
['uuid']] = vim_nets
[0]['id']
1431 create_network
= False
1433 #if network is not external
1434 network_id
= myvim
.new_network(net_vim_name
, net_type
)
1435 sce_net
['vim_id'] = network_id
1436 auxNetDict
['scenario'][sce_net
['uuid']] = network_id
1437 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
1439 #2. Creating new nets (vnf internal nets) in the VIM"
1440 #For each vnf net, we create it and we add it to instanceNetlist.
1441 for sce_vnf
in scenarioDict
['vnfs']:
1442 for net
in sce_vnf
['nets']:
1443 descriptor_net
= instance_dict
.get("vnfs",{}).get(sce_vnf
["name"],{})
1444 net_name
= descriptor_net
.get("name")
1446 net_name
= "%s.%s" %(instance_name
, net
["name"])
1447 net_name
= net_name
[:255] #limit length
1448 net_type
= net
['type']
1449 network_id
= myvim
.new_network(net_name
, net_type
)
1450 net
['vim_id'] = network_id
1451 if sce_vnf
['uuid'] not in auxNetDict
:
1452 auxNetDict
[sce_vnf
['uuid']] = {}
1453 auxNetDict
[sce_vnf
['uuid']][net
['uuid']] = network_id
1454 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
1456 #print "auxNetDict:"
1457 #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
1459 #3. Creating new vm instances in the VIM
1460 #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
1461 for sce_vnf
in scenarioDict
['vnfs']:
1463 for vm
in sce_vnf
['vms']:
1466 myVMDict
['name'] = "%s.%s.%d" % (instance_name
,sce_vnf
['name'],i
)
1467 myVMDict
['description'] = myVMDict
['name'][0:99]
1469 # myVMDict['start'] = "no"
1470 myVMDict
['name'] = myVMDict
['name'][0:255] #limit name length
1471 #create image at vim in case it not exist
1472 image_dict
= mydb
.get_table_by_uuid_name("images", vm
['image_id'])
1473 image_id
= create_or_use_image(mydb
, vims
, image_dict
, [], True)
1474 vm
['vim_image_id'] = image_id
1476 #create flavor at vim in case it not exist
1477 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
1478 if flavor_dict
['extended']!=None:
1479 flavor_dict
['extended']= yaml
.load(flavor_dict
['extended'])
1480 flavor_id
= create_or_use_flavor(mydb
, vims
, flavor_dict
, rollbackList
, True)
1481 vm
['vim_flavor_id'] = flavor_id
1483 myVMDict
['imageRef'] = vm
['vim_image_id']
1484 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
1485 myVMDict
['networks'] = []
1486 #TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true
1487 for iface
in vm
['interfaces']:
1489 if iface
['type']=="data":
1490 netDict
['type'] = iface
['model']
1491 elif "model" in iface
and iface
["model"]!=None:
1492 netDict
['model']=iface
['model']
1493 #TODO in future, remove this because mac_address will not be set, and the type of PV,VF is obtained from iterface table model
1494 #discover type of interface looking at flavor
1495 for numa
in flavor_dict
.get('extended',{}).get('numas',[]):
1496 for flavor_iface
in numa
.get('interfaces',[]):
1497 if flavor_iface
.get('name') == iface
['internal_name']:
1498 if flavor_iface
['dedicated'] == 'yes':
1499 netDict
['type']="PF" #passthrough
1500 elif flavor_iface
['dedicated'] == 'no':
1501 netDict
['type']="VF" #siov
1502 elif flavor_iface
['dedicated'] == 'yes:sriov':
1503 netDict
['type']="VFnotShared" #sriov but only one sriov on the PF
1504 netDict
["mac_address"] = flavor_iface
.get("mac_address")
1506 netDict
["use"]=iface
['type']
1507 if netDict
["use"]=="data" and not netDict
.get("type"):
1508 #print "netDict", netDict
1509 #print "iface", iface
1510 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'])
1511 if flavor_dict
.get('extended')==None:
1512 raise NfvoException(e_text
+ "After database migration some information is not available. \
1513 Try to delete and create the scenarios and VNFs again", HTTP_Conflict
)
1515 raise NfvoException(e_text
, HTTP_Internal_Server_Error
)
1516 if netDict
["use"]=="mgmt" or netDict
["use"]=="bridge":
1517 netDict
["type"]="virtual"
1518 if "vpci" in iface
and iface
["vpci"] is not None:
1519 netDict
['vpci'] = iface
['vpci']
1520 if "mac" in iface
and iface
["mac"] is not None:
1521 netDict
['mac_address'] = iface
['mac']
1522 netDict
['name'] = iface
['internal_name']
1523 if iface
['net_id'] is None:
1524 for vnf_iface
in sce_vnf
["interfaces"]:
1527 if vnf_iface
['interface_id']==iface
['uuid']:
1528 netDict
['net_id'] = auxNetDict
['scenario'][ vnf_iface
['sce_net_id'] ]
1531 netDict
['net_id'] = auxNetDict
[ sce_vnf
['uuid'] ][ iface
['net_id'] ]
1532 #skip bridge ifaces not connected to any net
1533 #if 'net_id' not in netDict or netDict['net_id']==None:
1535 myVMDict
['networks'].append(netDict
)
1536 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
1537 #print myVMDict['name']
1538 #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
1539 #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
1540 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
1541 vm_id
= myvim
.new_vminstance(myVMDict
['name'],myVMDict
['description'],myVMDict
.get('start', None),
1542 myVMDict
['imageRef'],myVMDict
['flavorRef'],myVMDict
['networks'])
1543 vm
['vim_id'] = vm_id
1544 rollbackList
.append({'what':'vm','where':'vim','vim_id':datacenter_id
,'uuid':vm_id
})
1545 #put interface uuid back to scenario[vnfs][vms[[interfaces]
1546 for net
in myVMDict
['networks']:
1548 for iface
in vm
['interfaces']:
1549 if net
["name"]==iface
["internal_name"]:
1550 iface
["vim_id"]=net
["vim_id"]
1552 logger
.debug("create_instance Deployment done")
1553 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
1554 #r,c = mydb.new_instance_scenario_as_a_whole(nfvo_tenant,scenarioDict['name'],scenarioDict)
1555 instance_id
= mydb
.new_instance_scenario_as_a_whole(tenant_id
,instance_name
, instance_description
, scenarioDict
)
1556 return mydb
.get_instance_scenario(instance_id
)
1557 except (NfvoException
, vimconn
.vimconnException
,db_base_Exception
) as e
:
1558 message
= rollback(mydb
, vims
, rollbackList
)
1559 if isinstance(e
, db_base_Exception
):
1560 error_text
= "database Exception"
1561 elif isinstance(e
, vimconn
.vimconnException
):
1562 error_text
= "VIM Exception"
1564 error_text
= "Exception"
1565 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1566 #logger.error("create_instance: %s", error_text)
1567 raise NfvoException(error_text
, e
.http_code
)
1569 def delete_instance(mydb
, tenant_id
, instance_id
):
1570 #print "Checking that the instance_id exists and getting the instance dictionary"
1571 instanceDict
= mydb
.get_instance_scenario(instance_id
, tenant_id
)
1572 #print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
1573 tenant_id
= instanceDict
["tenant_id"]
1574 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
1576 vims
= get_vim(mydb
, tenant_id
, instanceDict
['datacenter_id'])
1578 logger
.error("!!!!!! nfvo.delete_instance() datacenter not found!!!!")
1581 myvim
= vims
.values()[0]
1582 except NfvoException
as e
:
1583 logger
.error("!!!!!! nfvo.delete_instance() datacenter Exception!!!! " + str(e
))
1587 #1. Delete from Database
1589 #result,c = mydb.delete_row_by_id('instance_scenarios', instance_id, nfvo_tenant)
1590 message
= mydb
.delete_instance_scenario(instance_id
, tenant_id
)
1594 error_msg
= "Not possible to delete VIM VMs and networks. Datacenter not found at database!!!"
1600 for sce_vnf
in instanceDict
['vnfs']:
1603 for vm
in sce_vnf
['vms']:
1605 myvim
.delete_vminstance(vm
['vim_vm_id'])
1606 except vimconn
.vimconnNotFoundException
as e
:
1607 error_msg
+="\n VM id={} not found at VIM".format(vm
['vim_vm_id'])
1608 logger
.warn("VM instance '%s'uuid '%s', VIM id '%s', from VNF_id '%s' not found",
1609 vm
['name'], vm
['uuid'], vm
['vim_vm_id'], sce_vnf
['vnf_id'])
1610 except vimconn
.vimconnException
as e
:
1611 error_msg
+="\n Error: " + e
.http_code
+ " VM id=" + vm
['vim_vm_id']
1612 logger
.error("Error %d deleting VM instance '%s'uuid '%s', VIM id '%s', from VNF_id '%s': %s",
1613 e
.http_code
, vm
['name'], vm
['uuid'], vm
['vim_vm_id'], sce_vnf
['vnf_id'], str(e
))
1617 for net
in instanceDict
['nets']:
1619 continue #skip not created nets
1623 myvim
.delete_network(net
['vim_net_id'])
1624 except vimconn
.vimconnNotFoundException
as e
:
1625 error_msg
+="\n NET id={} not found at VIM".format(net
['vim_net_id'])
1626 logger
.warn("NET '%s', VIM id '%s', from VNF_id '%s' not found",
1627 net
['uuid'], vm
['vim_net_id'], sce_vnf
['vnf_id'])
1628 except vimconn
.vimconnException
as e
:
1629 error_msg
+="\n Error: " + e
.http_code
+ " Net id=" + net
['vim_vm_id']
1630 logger
.error("Error %d deleting NET '%s', VIM id '%s', from VNF_id '%s': %s",
1631 e
.http_code
, net
['uuid'], net
['vim_net_id'], sce_vnf
['vnf_id'], str(e
))
1632 if len(error_msg
)>0:
1633 return 'instance ' + message
+ ' deleted but some elements could not be deleted, or already deleted (error: 404) from VIM: ' + error_msg
1635 return 'instance ' + message
+ ' deleted'
1637 def refresh_instance(mydb
, nfvo_tenant
, instanceDict
, datacenter
=None, vim_tenant
=None):
1638 '''Refreshes a scenario instance. It modifies instanceDict'''
1640 - 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
1643 # Assumption: nfvo_tenant and instance_id were checked before entering into this function
1644 #print "nfvo.refresh_instance begins"
1645 #print json.dumps(instanceDict, indent=4)
1647 #print "Getting the VIM URL and the VIM tenant_id"
1648 vims
= get_vim(mydb
, nfvo_tenant
, instanceDict
['datacenter_id'])
1650 raise NfvoException("datacenter '{}' not found".format(str(instanceDict
['datacenter_id'])), HTTP_Not_Found
)
1651 myvim
= vims
.values()[0]
1653 # 1. Getting VIM vm and net list
1654 vms_updated
= [] #List of VM instance uuids in openmano that were updated
1657 for sce_vnf
in instanceDict
['vnfs']:
1658 for vm
in sce_vnf
['vms']:
1659 vm_list
.append(vm
['vim_vm_id'])
1660 vms_notupdated
.append(vm
["uuid"])
1662 nets_updated
= [] #List of VM instance uuids in openmano that were updated
1665 for net
in instanceDict
['nets']:
1666 net_list
.append(net
['vim_net_id'])
1667 nets_notupdated
.append(net
["uuid"])
1670 # 1. Getting the status of all VMs
1671 vm_dict
= myvim
.refresh_vms_status(vm_list
)
1673 # 2. Update the status of VMs in the instanceDict, while collects the VMs whose status changed
1674 for sce_vnf
in instanceDict
['vnfs']:
1675 for vm
in sce_vnf
['vms']:
1676 vm_id
= vm
['vim_vm_id']
1677 interfaces
= vm_dict
[vm_id
].pop('interfaces', [])
1678 #2.0 look if contain manamgement interface, and if not change status from ACTIVE:NoMgmtIP to ACTIVE
1679 has_mgmt_iface
= False
1680 for iface
in vm
["interfaces"]:
1681 if iface
["type"]=="mgmt":
1682 has_mgmt_iface
= True
1683 if vm_dict
[vm_id
]['status'] == "ACTIVE:NoMgmtIP" and not has_mgmt_iface
:
1684 vm_dict
[vm_id
]['status'] = "ACTIVE"
1685 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'):
1686 vm
['status'] = vm_dict
[vm_id
]['status']
1687 vm
['error_msg'] = vm_dict
[vm_id
].get('error_msg')
1688 vm
['vim_info'] = vm_dict
[vm_id
].get('vim_info')
1689 # 2.1. Update in openmano DB the VMs whose status changed
1691 updates
= mydb
.update_rows('instance_vms', UPDATE
=vm_dict
[vm_id
], WHERE
={'uuid':vm
["uuid"]})
1692 vms_notupdated
.remove(vm
["uuid"])
1694 vms_updated
.append(vm
["uuid"])
1695 except db_base_Exception
as e
:
1696 logger
.error("nfvo.refresh_instance error database update: %s", str(e
))
1697 # 2.2. Update in openmano DB the interface VMs
1698 for interface
in interfaces
:
1699 #translate from vim_net_id to instance_net_id
1701 for net
in instanceDict
['nets']:
1702 if net
["vim_net_id"] == interface
["vim_net_id"]:
1703 network_id
= net
["uuid"]
1707 del interface
["vim_net_id"]
1709 mydb
.update_rows('instance_interfaces', UPDATE
=interface
, WHERE
={'instance_vm_id':vm
["uuid"], "instance_net_id":network_id
})
1710 except db_base_Exception
as e
:
1711 logger
.error( "nfvo.refresh_instance error with vm=%s, interface_net_id=%s", vm
["uuid"], network_id
)
1713 # 3. Getting the status of all nets
1714 net_dict
= myvim
.refresh_nets_status(net_list
)
1716 # 4. Update the status of nets in the instanceDict, while collects the nets whose status changed
1717 # TODO: update nets inside a vnf
1718 for net
in instanceDict
['nets']:
1719 net_id
= net
['vim_net_id']
1720 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'):
1721 net
['status'] = net_dict
[net_id
]['status']
1722 net
['error_msg'] = net_dict
[net_id
].get('error_msg')
1723 net
['vim_info'] = net_dict
[net_id
].get('vim_info')
1724 # 5.1. Update in openmano DB the nets whose status changed
1726 updated
= mydb
.update_rows('instance_nets', UPDATE
=net_dict
[net_id
], WHERE
={'uuid':net
["uuid"]})
1727 nets_notupdated
.remove(net
["uuid"])
1729 nets_updated
.append(net
["uuid"])
1730 except db_base_Exception
as e
:
1731 logger
.error("nfvo.refresh_instance error database update: %s", str(e
))
1732 except vimconn
.vimconnException
as e
:
1733 #logger.error("VIM exception %s %s", type(e).__name__, str(e))
1734 raise NfvoException(str(e
), e
.http_code
)
1736 # Returns appropriate output
1737 #print "nfvo.refresh_instance finishes"
1738 logger
.debug("VMs updated in the database: %s; nets updated in the database %s; VMs not updated: %s; nets not updated: %s",
1739 str(vms_updated
), str(nets_updated
), str(vms_notupdated
), str(nets_notupdated
))
1740 instance_id
= instanceDict
['uuid']
1741 if len(vms_notupdated
)+len(nets_notupdated
)>0:
1742 error_msg
= "VMs not updated: " + str(vms_notupdated
) + "; nets not updated: " + str(nets_notupdated
)
1743 return len(vms_notupdated
)+len(nets_notupdated
), 'Scenario instance ' + instance_id
+ ' refreshed but some elements could not be updated in the database: ' + error_msg
1745 return 0, 'Scenario instance ' + instance_id
+ ' refreshed.'
1747 def instance_action(mydb
,nfvo_tenant
,instance_id
, action_dict
):
1748 #print "Checking that the instance_id exists and getting the instance dictionary"
1749 instanceDict
= mydb
.get_instance_scenario(instance_id
, nfvo_tenant
)
1750 #print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
1752 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
1753 vims
= get_vim(mydb
, nfvo_tenant
, instanceDict
['datacenter_id'])
1755 raise NfvoException("datacenter '{}' not found".format(str(instanceDict
['datacenter_id'])), HTTP_Not_Found
)
1756 myvim
= vims
.values()[0]
1759 input_vnfs
= action_dict
.pop("vnfs", [])
1760 input_vms
= action_dict
.pop("vms", [])
1761 action_over_all
= True if len(input_vnfs
)==0 and len (input_vms
)==0 else False
1765 for sce_vnf
in instanceDict
['vnfs']:
1766 for vm
in sce_vnf
['vms']:
1767 if not action_over_all
:
1768 if sce_vnf
['uuid'] not in input_vnfs
and sce_vnf
['vnf_name'] not in input_vnfs
and \
1769 vm
['uuid'] not in input_vms
and vm
['name'] not in input_vms
:
1772 data
= myvim
.action_vminstance(vm
['vim_vm_id'], action_dict
)
1773 if "console" in action_dict
:
1774 if not global_config
["http_console_proxy"]:
1775 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
1776 "description": "{protocol}//{ip}:{port}/{suffix}".format(
1777 protocol
=data
["protocol"],
1778 ip
= data
["server"],
1779 port
= data
["port"],
1780 suffix
= data
["suffix"]),
1784 elif data
["server"]=="127.0.0.1" or data
["server"]=="localhost":
1785 vm_result
[ vm
['uuid'] ] = {"vim_result": -HTTP_Unauthorized
,
1786 "description": "this console is only reachable by local interface",
1791 #print "console data", data
1793 console_thread
= create_or_use_console_proxy_thread(data
["server"], data
["port"])
1794 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
1795 "description": "{protocol}//{ip}:{port}/{suffix}".format(
1796 protocol
=data
["protocol"],
1797 ip
= global_config
["http_console_host"],
1798 port
= console_thread
.port
,
1799 suffix
= data
["suffix"]),
1803 except NfvoException
as e
:
1804 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
1808 vm_result
[ vm
['uuid'] ] = {"vim_result": 200, "description": "ok", "name":vm
['name']}
1810 except vimconn
.vimconnException
as e
:
1811 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
1814 if vm_ok
==0: #all goes wrong
1819 def create_or_use_console_proxy_thread(console_server
, console_port
):
1820 #look for a non-used port
1821 console_thread_key
= console_server
+ ":" + str(console_port
)
1822 if console_thread_key
in global_config
["console_thread"]:
1823 #global_config["console_thread"][console_thread_key].start_timeout()
1824 return global_config
["console_thread"][console_thread_key
]
1826 for port
in global_config
["console_port_iterator"]():
1827 #print "create_or_use_console_proxy_thread() port:", port
1828 if port
in global_config
["console_ports"]:
1831 clithread
= cli
.ConsoleProxyThread(global_config
['http_host'], port
, console_server
, console_port
)
1833 global_config
["console_thread"][console_thread_key
] = clithread
1834 global_config
["console_ports"][port
] = console_thread_key
1836 except cli
.ConsoleProxyExceptionPortUsed
as e
:
1837 #port used, try with onoher
1839 except cli
.ConsoleProxyException
as e
:
1840 raise NfvoException(str(e
), HTTP_Bad_Request
)
1841 raise NfvoException("Not found any free 'http_console_ports'", HTTP_Conflict
)
1843 def check_tenant(mydb
, tenant_id
):
1844 '''check that tenant exists at database'''
1845 tenant
= mydb
.get_rows(FROM
='nfvo_tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
})
1847 raise NfvoException("tenant '{}' not found".format(tenant_id
), HTTP_Not_Found
)
1850 def new_tenant(mydb
, tenant_dict
):
1851 tenant_id
= mydb
.new_row("nfvo_tenants", tenant_dict
, add_uuid
=True)
1854 def delete_tenant(mydb
, tenant
):
1855 #get nfvo_tenant info
1857 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant
, 'tenant')
1858 mydb
.delete_row_by_id("nfvo_tenants", tenant_dict
['uuid'])
1859 return tenant_dict
['uuid'] + " " + tenant_dict
["name"]
1861 def new_datacenter(mydb
, datacenter_descriptor
):
1862 if "config" in datacenter_descriptor
:
1863 datacenter_descriptor
["config"]=yaml
.safe_dump(datacenter_descriptor
["config"],default_flow_style
=True,width
=256)
1864 datacenter_id
= mydb
.new_row("datacenters", datacenter_descriptor
, add_uuid
=True)
1865 return datacenter_id
1867 def edit_datacenter(mydb
, datacenter_id_name
, datacenter_descriptor
):
1868 #obtain data, check that only one exist
1869 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id_name
)
1871 datacenter_id
= datacenter
['uuid']
1872 where
={'uuid': datacenter
['uuid']}
1873 if "config" in datacenter_descriptor
:
1874 if datacenter_descriptor
['config']!=None:
1876 new_config_dict
= datacenter_descriptor
["config"]
1879 for k
in new_config_dict
:
1880 if new_config_dict
[k
]==None:
1883 config_dict
= yaml
.load(datacenter
["config"])
1884 config_dict
.update(new_config_dict
)
1888 except Exception as e
:
1889 raise NfvoException("Bad format at datacenter:config " + str(e
), HTTP_Bad_Request
)
1890 datacenter_descriptor
["config"]= yaml
.safe_dump(config_dict
,default_flow_style
=True,width
=256) if len(config_dict
)>0 else None
1891 mydb
.update_rows('datacenters', datacenter_descriptor
, where
)
1892 return datacenter_id
1894 def delete_datacenter(mydb
, datacenter
):
1895 #get nfvo_tenant info
1896 datacenter_dict
= mydb
.get_table_by_uuid_name('datacenters', datacenter
, 'datacenter')
1897 mydb
.delete_row_by_id("datacenters", datacenter_dict
['uuid'])
1898 return datacenter_dict
['uuid'] + " " + datacenter_dict
['name']
1900 def associate_datacenter_to_tenant(mydb
, nfvo_tenant
, datacenter
, vim_tenant_id
=None, vim_tenant_name
=None, vim_username
=None, vim_password
=None):
1901 #get datacenter info
1902 if utils
.check_valid_uuid(datacenter
):
1903 vims
= get_vim(mydb
, datacenter_id
=datacenter
)
1905 vims
= get_vim(mydb
, datacenter_name
=datacenter
)
1907 raise NfvoException("datacenter '{}' not found".format(str(datacenter
)), HTTP_Not_Found
)
1909 #print "nfvo.datacenter_action() error. Several datacenters found"
1910 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
1912 datacenter_id
=vims
.keys()[0]
1913 myvim
=vims
[datacenter_id
]
1914 datacenter_name
=myvim
["name"]
1916 create_vim_tenant
=True if vim_tenant_id
==None and vim_tenant_name
==None else False
1918 #get nfvo_tenant info
1919 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant
)
1920 if vim_tenant_name
==None:
1921 vim_tenant_name
=tenant_dict
['name']
1923 #check that this association does not exist before
1924 tenants_datacenter_dict
={"nfvo_tenant_id":tenant_dict
['uuid'], "datacenter_id":datacenter_id
}
1925 tenants_datacenters
= mydb
.get_rows(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
1926 if len(tenants_datacenters
)>0:
1927 raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id
, tenant_dict
['uuid']), HTTP_Conflict
)
1929 vim_tenant_id_exist_atdb
=False
1930 if not create_vim_tenant
:
1931 where_
={"datacenter_id": datacenter_id
}
1932 if vim_tenant_id
!=None:
1933 where_
["vim_tenant_id"] = vim_tenant_id
1934 if vim_tenant_name
!=None:
1935 where_
["vim_tenant_name"] = vim_tenant_name
1936 #check if vim_tenant_id is already at database
1937 datacenter_tenants_dict
= mydb
.get_rows(FROM
='datacenter_tenants', WHERE
=where_
)
1938 if len(datacenter_tenants_dict
)>=1:
1939 datacenter_tenants_dict
= datacenter_tenants_dict
[0]
1940 vim_tenant_id_exist_atdb
=True
1941 #TODO check if a field has changed and edit entry at datacenter_tenants at DB
1943 datacenter_tenants_dict
= {}
1944 #insert at table datacenter_tenants
1945 else: #if vim_tenant_id==None:
1946 #create tenant at VIM if not provided
1948 vim_tenant_id
= myvim
.new_tenant(vim_tenant_name
, "created by openmano for datacenter "+datacenter_name
)
1949 except vimconn
.vimconnException
as e
:
1950 raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id
, str(e
)), HTTP_Internal_Server_Error
)
1951 datacenter_tenants_dict
= {}
1952 datacenter_tenants_dict
["created"]="true"
1954 #fill datacenter_tenants table
1955 if not vim_tenant_id_exist_atdb
:
1956 datacenter_tenants_dict
["vim_tenant_id"] = vim_tenant_id
1957 datacenter_tenants_dict
["vim_tenant_name"] = vim_tenant_name
1958 datacenter_tenants_dict
["user"] = vim_username
1959 datacenter_tenants_dict
["passwd"] = vim_password
1960 datacenter_tenants_dict
["datacenter_id"] = datacenter_id
1961 id_
= mydb
.new_row('datacenter_tenants', datacenter_tenants_dict
, add_uuid
=True)
1962 datacenter_tenants_dict
["uuid"] = id_
1964 #fill tenants_datacenters table
1965 tenants_datacenter_dict
["datacenter_tenant_id"]=datacenter_tenants_dict
["uuid"]
1966 mydb
.new_row('tenants_datacenters', tenants_datacenter_dict
)
1967 return datacenter_id
1969 def deassociate_datacenter_to_tenant(mydb
, tenant_id
, datacenter
, vim_tenant_id
=None):
1970 #get datacenter info
1971 if utils
.check_valid_uuid(datacenter
):
1972 vims
= get_vim(mydb
, datacenter_id
=datacenter
)
1974 vims
= get_vim(mydb
, datacenter_name
=datacenter
)
1976 raise NfvoException("datacenter '{}' not found".format(str(datacenter
)), HTTP_Not_Found
)
1978 #print "nfvo.datacenter_action() error. Several datacenters found"
1979 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
1980 datacenter_id
=vims
.keys()[0]
1981 myvim
=vims
[datacenter_id
]
1983 #get nfvo_tenant info
1984 if not tenant_id
or tenant_id
=="any":
1987 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant_id
)
1988 tenant_uuid
= tenant_dict
['uuid']
1990 #check that this association exist before
1991 tenants_datacenter_dict
={"datacenter_id":datacenter_id
}
1993 tenants_datacenter_dict
["nfvo_tenant_id"] = tenant_uuid
1994 tenant_datacenter_list
= mydb
.get_rows(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
1995 if len(tenant_datacenter_list
)==0 and tenant_uuid
:
1996 raise NfvoException("datacenter '{}' and tenant '{}' are not attached".format(datacenter_id
, tenant_dict
['uuid']), HTTP_Not_Found
)
1998 #delete this association
1999 mydb
.delete_row(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
2001 #get vim_tenant info and deletes
2003 for tenant_datacenter_item
in tenant_datacenter_list
:
2004 vim_tenant_dict
= mydb
.get_table_by_uuid_name('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
2005 #try to delete vim:tenant
2007 mydb
.delete_row_by_id('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
2008 if vim_tenant_dict
['created']=='true':
2009 #delete tenant at VIM if created by NFVO
2011 myvim
.delete_tenant(vim_tenant_dict
['vim_tenant_id'])
2012 except vimconn
.vimconnException
as e
:
2013 warning
= "Not possible to delete vim_tenant_id {} from VIM: {} ".format(vim_tenant_dict
['vim_tenant_id'], str(e
))
2014 logger
.warn(warning
)
2015 except db_base_Exception
as e
:
2016 logger
.error("Cannot delete datacenter_tenants " + str(e
))
2017 pass #the error will be caused because dependencies, vim_tenant can not be deleted
2019 return "datacenter {} detached. {}".format(datacenter_id
, warning
)
2021 def datacenter_action(mydb
, tenant_id
, datacenter
, action_dict
):
2023 #get datacenter info
2024 if utils
.check_valid_uuid(datacenter
):
2025 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2027 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2029 raise NfvoException("datacenter '{}' not found".format(str(datacenter
)), HTTP_Not_Found
)
2031 #print "nfvo.datacenter_action() error. Several datacenters found"
2032 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2033 datacenter_id
=vims
.keys()[0]
2034 myvim
=vims
[datacenter_id
]
2036 if 'net-update' in action_dict
:
2038 nets
= myvim
.get_network_list(filter_dict
={'shared': True, 'admin_state_up': True, 'status': 'ACTIVE'})
2040 except vimconn
.vimconnException
as e
:
2041 #logger.error("nfvo.datacenter_action() Not possible to get_network_list from VIM: %s ", str(e))
2042 raise NfvoException(str(e
), HTTP_Internal_Server_Error
)
2043 #update nets Change from VIM format to NFVO format
2046 net_nfvo
={'datacenter_id': datacenter_id
}
2047 net_nfvo
['name'] = net
['name']
2048 #net_nfvo['description']= net['name']
2049 net_nfvo
['vim_net_id'] = net
['id']
2050 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
2051 net_nfvo
['shared'] = net
['shared']
2052 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
2053 net_list
.append(net_nfvo
)
2054 inserted
, deleted
= mydb
.update_datacenter_nets(datacenter_id
, net_list
)
2055 logger
.info("Inserted %d nets, deleted %d old nets", inserted
, deleted
)
2057 elif 'net-edit' in action_dict
:
2058 net
= action_dict
['net-edit'].pop('net')
2059 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
2060 result
= mydb
.update_rows('datacenter_nets', action_dict
['net-edit'],
2061 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
2063 elif 'net-delete' in action_dict
:
2064 net
= action_dict
['net-deelte'].get('net')
2065 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
2066 result
= mydb
.delete_row(FROM
='datacenter_nets',
2067 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
2071 raise NfvoException("Unknown action " + str(action_dict
), HTTP_Bad_Request
)
2073 def datacenter_edit_netmap(mydb
, tenant_id
, datacenter
, netmap
, action_dict
):
2074 #get datacenter info
2075 if utils
.check_valid_uuid(datacenter
):
2076 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2078 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2080 raise NfvoException("datacenter '{}' not found".format(str(datacenter
)), HTTP_Not_Found
)
2082 #print "nfvo.datacenter_action() error. Several datacenters found"
2083 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2084 datacenter_id
=vims
.keys()[0]
2086 what
= 'uuid' if utils
.check_valid_uuid(netmap
) else 'name'
2087 result
= mydb
.update_rows('datacenter_nets', action_dict
['netmap'],
2088 WHERE
={'datacenter_id':datacenter_id
, what
: netmap
})
2091 def datacenter_new_netmap(mydb
, tenant_id
, datacenter
, action_dict
=None):
2092 #get datacenter info
2093 if utils
.check_valid_uuid(datacenter
):
2094 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2096 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2098 raise NfvoException("datacenter '{}' not found".format(datacenter
), HTTP_Not_Found
)
2100 #logger.error("nfvo.datacenter_new_netmap() error. Several datacenters found")
2101 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2102 datacenter_id
=vims
.keys()[0]
2103 myvim
=vims
[datacenter_id
]
2106 action_dict
= action_dict
["netmap"]
2107 if 'vim_id' in action_dict
:
2108 filter_dict
["id"] = action_dict
['vim_id']
2109 if 'vim_name' in action_dict
:
2110 filter_dict
["name"] = action_dict
['vim_name']
2112 filter_dict
["shared"] = True
2115 vim_nets
= myvim
.get_network_list(filter_dict
=filter_dict
)
2116 except vimconn
.vimconnException
as e
:
2117 #logger.error("nfvo.datacenter_new_netmap() Not possible to get_network_list from VIM: %s ", str(e))
2118 raise NfvoException(str(e
), HTTP_Internal_Server_Error
)
2119 if len(vim_nets
)>1 and action_dict
:
2120 raise NfvoException("more than two networks found, specify with vim_id", HTTP_Conflict
)
2121 elif len(vim_nets
)==0: # and action_dict:
2122 raise NfvoException("Not found a network at VIM with " + str(filter_dict
), HTTP_Not_Found
)
2124 for net
in vim_nets
:
2125 net_nfvo
={'datacenter_id': datacenter_id
}
2126 if action_dict
and "name" in action_dict
:
2127 net_nfvo
['name'] = action_dict
['name']
2129 net_nfvo
['name'] = net
['name']
2130 #net_nfvo['description']= net['name']
2131 net_nfvo
['vim_net_id'] = net
['id']
2132 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
2133 net_nfvo
['shared'] = net
['shared']
2134 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
2136 net_id
= mydb
.new_row("datacenter_nets", net_nfvo
, add_uuid
=True)
2137 net_nfvo
["status"] = "OK"
2138 net_nfvo
["uuid"] = net_id
2139 except db_base_Exception
as e
:
2143 net_nfvo
["status"] = "FAIL: " + str(e
)
2144 net_list
.append(net_nfvo
)
2147 def vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
):
2148 #get datacenter info
2149 if utils
.check_valid_uuid(datacenter
):
2150 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2152 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2154 raise NfvoException("datacenter '{}' not found".format(datacenter
), HTTP_Not_Found
)
2156 #logger.error("nfvo.datacenter_new_netmap() error. Several datacenters found")
2157 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2158 datacenter_id
=vims
.keys()[0]
2159 myvim
=vims
[datacenter_id
]
2162 if utils
.check_valid_uuid(name
):
2163 filter_dict
["id"] = name
2165 filter_dict
["name"] = name
2167 if item
=="networks":
2168 #filter_dict['tenant_id'] = myvim['tenant_id']
2169 content
= myvim
.get_network_list(filter_dict
=filter_dict
)
2170 elif item
=="tenants":
2171 content
= myvim
.get_tenant_list(filter_dict
=filter_dict
)
2173 raise NfvoException(item
+ "?", HTTP_Method_Not_Allowed
)
2174 logger
.debug("vim_action response ", content
) #update nets Change from VIM format to NFVO format
2175 if name
and len(content
)==1:
2176 return {item
[:-1]: content
[0]}
2177 elif name
and len(content
)==0:
2178 raise NfvoException("No {} found with ".format(item
[:-1]) + " and ".join(map(lambda x
: str(x
[0])+": "+str(x
[1]), filter_dict
.iteritems())),
2181 return {item
: content
}
2182 except vimconn
.vimconnException
as e
:
2183 print "vim_action Not possible to get_%s_list from VIM: %s " % (item
, str(e
))
2184 raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item
, str(e
)), e
.http_code
)
2186 def vim_action_delete(mydb
, tenant_id
, datacenter
, item
, name
):
2187 #get datacenter info
2188 if tenant_id
== "any":
2191 if utils
.check_valid_uuid(datacenter
):
2192 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2194 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2196 raise NfvoException("datacenter '{}' not found".format(datacenter
), HTTP_Not_Found
)
2198 #logger.error("nfvo.datacenter_new_netmap() error. Several datacenters found")
2199 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2200 datacenter_id
=vims
.keys()[0]
2201 myvim
=vims
[datacenter_id
]
2203 content
= vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
)
2204 logger
.debug("vim_action_delete vim response: " + str(content
))
2205 items
= content
.values()[0]
2206 if type(items
)==list and len(items
)==0:
2207 raise NfvoException("Not found " + item
, HTTP_Not_Found
)
2208 elif type(items
)==list and len(items
)>1:
2209 raise NfvoException("Found more than one {} with this name. Use uuid.".format(item
), HTTP_Not_Found
)
2210 else: # it is a dict
2211 item_id
= items
["id"]
2212 item_name
= str(items
.get("name"))
2215 if item
=="networks":
2216 content
= myvim
.delete_network(item_id
)
2217 elif item
=="tenants":
2218 content
= myvim
.delete_tenant(item_id
)
2220 raise NfvoException(item
+ "?", HTTP_Method_Not_Allowed
)
2221 except vimconn
.vimconnException
as e
:
2222 #logger.error( "vim_action Not possible to delete_{} {}from VIM: {} ".format(item, name, str(e)))
2223 raise NfvoException("Not possible to delete_{} {} from VIM: {}".format(item
, name
, str(e
)), e
.http_code
)
2225 return "{} {} {} deleted".format(item
[:-1], item_id
,item_name
)
2227 def vim_action_create(mydb
, tenant_id
, datacenter
, item
, descriptor
):
2228 #get datacenter info
2229 print "vim_action_create descriptor", descriptor
2230 if tenant_id
== "any":
2233 if utils
.check_valid_uuid(datacenter
):
2234 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_id
=datacenter
)
2236 vims
= get_vim(mydb
, nfvo_tenant
=tenant_id
, datacenter_name
=datacenter
)
2238 raise NfvoException("datacenter '{}' not found".format(datacenter
), HTTP_Not_Found
)
2240 #logger.error("nfvo.datacenter_new_netmap() error. Several datacenters found")
2241 raise NfvoException("More than one datacenters found, try to identify with uuid", HTTP_Conflict
)
2242 datacenter_id
=vims
.keys()[0]
2243 myvim
=vims
[datacenter_id
]
2246 if item
=="networks":
2247 net
= descriptor
["network"]
2248 net_name
= net
.pop("name")
2249 net_type
= net
.pop("type", "bridge")
2250 net_public
=net
.pop("shared", False)
2251 content
= myvim
.new_network(net_name
, net_type
, net_public
, **net
)
2252 elif item
=="tenants":
2253 tenant
= descriptor
["tenant"]
2254 content
= myvim
.new_tenant(tenant
["name"], tenant
.get("description"))
2256 raise NfvoException(item
+ "?", HTTP_Method_Not_Allowed
)
2257 except vimconn
.vimconnException
as e
:
2258 raise NfvoException("Not possible to create {} at VIM: {}".format(item
, str(e
)), e
.http_code
)
2260 return vim_action_get(mydb
, tenant_id
, datacenter
, item
, content
)