- self.cur = self.con.cursor()
- #print cmd
- self.cur.execute(cmd)
- rows = self.cur.fetchall()
- highest_version_int=0
- highest_version=""
- #print rows
- for row in rows: #look for the latest version
- if row[0]>highest_version_int:
- highest_version_int, highest_version = row[0:2]
- return highest_version_int, highest_version
- except (mdb.Error, AttributeError), e:
- #print cmd
- print "get_db_version DB Exception %d: %s" % (e.args[0], e.args[1])
- r,c = self.format_error(e)
- if r!=-HTTP_Request_Timeout or retry_==1: return r,c
-
- def disconnect(self):
- '''disconnect from specific data base'''
- try:
- self.con.close()
- del self.con
- except mdb.Error, e:
- print "Error disconnecting from DB: Error %d: %s" % (e.args[0], e.args[1])
- return -1
- except AttributeError, e: #self.con not defined
- if e[0][-5:] == "'con'": return -1, "Database internal error, no connection."
- else: raise
-
- def format_error(self, e, command=None, extra=None):
- if type(e[0]) is str:
- if e[0][-5:] == "'con'": return -HTTP_Internal_Server_Error, "DB Exception, no connection."
- else: raise
- if e.args[0]==2006 or e.args[0]==2013 : #MySQL server has gone away (((or))) Exception 2013: Lost connection to MySQL server during query
- #reconnect
- self.connect()
- return -HTTP_Request_Timeout,"Database reconnection. Try Again"
-
- fk=e.args[1].find("foreign key constraint fails")
- if fk>=0:
- if command=="update": return -HTTP_Bad_Request, "tenant_id %s not found." % extra
- elif command=="delete": return -HTTP_Bad_Request, "Resource is not free. There are %s that prevent deleting it." % extra
- de = e.args[1].find("Duplicate entry")
- fk = e.args[1].find("for key")
- uk = e.args[1].find("Unknown column")
- wc = e.args[1].find("in 'where clause'")
- fl = e.args[1].find("in 'field list'")
- #print de, fk, uk, wc,fl
- if de>=0:
- if fk>=0: #error 1062
- return -HTTP_Conflict, "Value %s already in use for %s" % (e.args[1][de+15:fk], e.args[1][fk+7:])
- if uk>=0:
- if wc>=0:
- return -HTTP_Bad_Request, "Field %s can not be used for filtering" % e.args[1][uk+14:wc]
- if fl>=0:
- return -HTTP_Bad_Request, "Field %s does not exist" % e.args[1][uk+14:wc]
- return -HTTP_Internal_Server_Error, "Database internal Error %d: %s" % (e.args[0], e.args[1])
-
- def __str2db_format(self, data):
- '''Convert string data to database format.
- If data is None it returns the 'Null' text,
- otherwise it returns the text surrounded by quotes ensuring internal quotes are escaped.
- '''
- if data==None:
- return 'Null'
- out=str(data)
- if "'" not in out:
- return "'" + out + "'"
- elif '"' not in out:
- return '"' + out + '"'
- else:
- return json.dumps(out)
-
- def __tuple2db_format_set(self, data):
- '''Compose the needed text for a SQL SET, parameter 'data' is a pair tuple (A,B),
- and it returns the text 'A="B"', where A is a field of a table and B is the value
- If B is None it returns the 'A=Null' text, without surrounding Null by quotes
- If B is not None it returns the text "A='B'" or 'A="B"' where B is surrounded by quotes,
- and it ensures internal quotes of B are escaped.
- '''
- if data[1]==None:
- return str(data[0]) + "=Null"
- out=str(data[1])
- if "'" not in out:
- return str(data[0]) + "='" + out + "'"
- elif '"' not in out:
- return str(data[0]) + '="' + out + '"'
- else:
- return str(data[0]) + '=' + json.dumps(out)
-
- def __tuple2db_format_where(self, data):
- '''Compose the needed text for a SQL WHERE, parameter 'data' is a pair tuple (A,B),
- and it returns the text 'A="B"', where A is a field of a table and B is the value
- If B is None it returns the 'A is Null' text, without surrounding Null by quotes
- If B is not None it returns the text "A='B'" or 'A="B"' where B is surrounded by quotes,
- and it ensures internal quotes of B are escaped.
- '''
- if data[1]==None:
- return str(data[0]) + " is Null"
-
-# if type(data[1]) is tuple: #this can only happen in a WHERE_OR clause
-# text =[]
-# for d in data[1]:
-# if d==None:
-# text.append(str(data[0]) + " is Null")
-# continue
-# out=str(d)
-# if "'" not in out:
-# text.append( str(data[0]) + "='" + out + "'" )
-# elif '"' not in out:
-# text.append( str(data[0]) + '="' + out + '"' )
-# else:
-# text.append( str(data[0]) + '=' + json.dumps(out) )
-# return " OR ".join(text)
-
- out=str(data[1])
- if "'" not in out:
- return str(data[0]) + "='" + out + "'"
- elif '"' not in out:
- return str(data[0]) + '="' + out + '"'
- else:
- return str(data[0]) + '=' + json.dumps(out)
-
- def __tuple2db_format_where_not(self, data):
- '''Compose the needed text for a SQL WHERE(not). parameter 'data' is a pair tuple (A,B),
- and it returns the text 'A<>"B"', where A is a field of a table and B is the value
- If B is None it returns the 'A is not Null' text, without surrounding Null by quotes
- If B is not None it returns the text "A<>'B'" or 'A<>"B"' where B is surrounded by quotes,
- and it ensures internal quotes of B are escaped.
- '''
- if data[1]==None:
- return str(data[0]) + " is not Null"
- out=str(data[1])
- if "'" not in out:
- return str(data[0]) + "<>'" + out + "'"
- elif '"' not in out:
- return str(data[0]) + '<>"' + out + '"'
- else:
- return str(data[0]) + '<>' + json.dumps(out)
-
- def __remove_quotes(self, data):
- '''remove single quotes ' of any string content of data dictionary'''
- for k,v in data.items():
- if type(v) == str:
- if "'" in v:
- data[k] = data[k].replace("'","_")
-
- def __update_rows(self, table, UPDATE, WHERE, log=False, modified_time=0):
- ''' Update one or several rows into a table.
- Atributes
- UPDATE: dictionary with the key: value to change
- table: table where to update
- WHERE: dictionary of elements to update
- Return: (result, descriptive text) where result indicates the number of updated files, negative if error
- '''
- #gettting uuid
- uuid = WHERE['uuid'] if 'uuid' in WHERE else None
- values = ",".join(map(self.__tuple2db_format_set, UPDATE.iteritems() ))
- if modified_time:
- values += ",modified_at=%f" % modified_time
- cmd= "UPDATE " + table +" SET " + values +\
- " WHERE " + " and ".join(map(self.__tuple2db_format_where, WHERE.iteritems() ))
- print cmd
- self.cur.execute(cmd)
- nb_rows = self.cur.rowcount
- if nb_rows > 0 and log:
- #inserting new log
- if uuid is None: uuid_k = uuid_v = ""
- else: uuid_k=",uuid"; uuid_v=",'" + str(uuid) + "'"
- cmd = "INSERT INTO logs (related,level%s,description) VALUES ('%s','debug'%s,\"updating %d entry %s\")" \
- % (uuid_k, table, uuid_v, nb_rows, (str(UPDATE)).replace('"','-') )
- print cmd
- self.cur.execute(cmd)
- return nb_rows, "%d updated from %s" % (nb_rows, table[:-1] )
-
- def _new_row_internal(self, table, INSERT, tenant_id=None, add_uuid=False, root_uuid=None, log=False, created_time=0):
- ''' Add one row into a table. It DOES NOT begin or end the transaction, so self.con.cursor must be created
- Attribute
- INSERT: dictionary with the key: value to insert
- table: table where to insert
- tenant_id: only useful for logs. If provided, logs will use this tenant_id
- add_uuid: if True, it will create an uuid key entry at INSERT if not provided
- It checks presence of uuid and add one automatically otherwise
- Return: (result, uuid) where result can be 0 if error, or 1 if ok
- '''
-
- if add_uuid:
- #create uuid if not provided
- if 'uuid' not in INSERT:
- uuid = INSERT['uuid'] = str(myUuid.uuid1()) # create_uuid
- else:
- uuid = str(INSERT['uuid'])
- else:
- uuid=None
- if add_uuid:
- #defining root_uuid if not provided
- if root_uuid is None:
- root_uuid = uuid
- if created_time:
- created_at = created_time
- else:
- created_at=time.time()
- #inserting new uuid
- cmd = "INSERT INTO uuids (uuid, root_uuid, used_at, created_at) VALUES ('%s','%s','%s', %f)" % (uuid, root_uuid, table, created_at)
- print cmd
- self.cur.execute(cmd)
- #insertion
- cmd= "INSERT INTO " + table +" SET " + \
- ",".join(map(self.__tuple2db_format_set, INSERT.iteritems() ))
- if created_time:
- cmd += ",created_at=%f" % created_time
- print cmd
- self.cur.execute(cmd)
- nb_rows = self.cur.rowcount
- #inserting new log
- if nb_rows > 0 and log:
- if add_uuid: del INSERT['uuid']
- if uuid is None: uuid_k = uuid_v = ""
- else: uuid_k=",uuid"; uuid_v=",'" + str(uuid) + "'"
- if tenant_id is None: tenant_k = tenant_v = ""
- else: tenant_k=",nfvo_tenant_id"; tenant_v=",'" + str(tenant_id) + "'"
- cmd = "INSERT INTO logs (related,level%s%s,description) VALUES ('%s','debug'%s%s,\"new %s %s\")" \
- % (uuid_k, tenant_k, table, uuid_v, tenant_v, table[:-1], str(INSERT).replace('"','-'))
- print cmd
- self.cur.execute(cmd)
- return nb_rows, uuid
-
- def __get_rows(self,table,uuid):
- self.cur.execute("SELECT * FROM " + str(table) +" where uuid='" + str(uuid) + "'")
- rows = self.cur.fetchall()
- return self.cur.rowcount, rows
+
+ myVNFDict = {}
+ myVNFDict["name"] = vnf_name
+ myVNFDict["descriptor"] = vnf_descriptor['vnf'].get('descriptor')
+ myVNFDict["public"] = vnf_descriptor['vnf'].get('public', "false")
+ myVNFDict["description"] = vnf_descriptor['vnf']['description']
+ myVNFDict["class"] = vnf_descriptor['vnf'].get('class',"MISC")
+ myVNFDict["tenant_id"] = vnf_descriptor['vnf'].get("tenant_id")
+
+ vnf_id = self._new_row_internal('vnfs', myVNFDict, add_uuid=True, root_uuid=None, created_time=created_time)
+ #print "Adding new vms to the NFVO database"
+ #For each vm, we must create the appropriate vm in the NFVO database.
+ vmDict = {}
+ for _,vm in VNFCDict.iteritems():
+ #This code could make the name of the vms grow and grow.
+ #If we agree to follow this convention, we should check with a regex that the vnfc name is not including yet the vnf name
+ #vm['name'] = "%s-%s" % (vnf_name,vm['name'])
+ #print "VM name: %s. Description: %s" % (vm['name'], vm['description'])
+ vm["vnf_id"] = vnf_id
+ created_time += 0.00001
+ vm_id = self._new_row_internal('vms', vm, add_uuid=True, root_uuid=vnf_id, created_time=created_time)
+ #print "Internal vm id in NFVO DB: %s" % vm_id
+ vmDict[vm['name']] = vm_id
+
+ #Collect the data interfaces of each VM/VNFC under the 'numas' field
+ dataifacesDict = {}
+ for vm in vnf_descriptor['vnf']['VNFC']:
+ dataifacesDict[vm['name']] = {}
+ for numa in vm.get('numas', []):
+ for dataiface in numa.get('interfaces',[]):
+ db_base._convert_bandwidth(dataiface, logger=self.logger)
+ dataifacesDict[vm['name']][dataiface['name']] = {}
+ dataifacesDict[vm['name']][dataiface['name']]['vpci'] = dataiface['vpci']
+ dataifacesDict[vm['name']][dataiface['name']]['bw'] = dataiface['bandwidth']
+ dataifacesDict[vm['name']][dataiface['name']]['model'] = "PF" if dataiface['dedicated']=="yes" else ("VF" if dataiface['dedicated']=="no" else "VFnotShared")