X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=vim_db.py;h=d6ac871052310da46846aa5a5fed35507f9b2b2a;hb=refs%2Fchanges%2F77%2F1277%2F2;hp=f2e448da7a971e3faafdac5efb41c9948459102b;hpb=181f17585738e6724b781cb1b371e8ac3c394cc1;p=osm%2Fopenvim.git diff --git a/vim_db.py b/vim_db.py index f2e448d..d6ac871 100644 --- a/vim_db.py +++ b/vim_db.py @@ -37,6 +37,7 @@ import uuid as myUuid import auxiliary_functions as af import json import logging +from netaddr import IPNetwork, IPSet, IPRange, all_matching_cidrs HTTP_Bad_Request = 400 HTTP_Unauthorized = 401 @@ -216,33 +217,41 @@ class vim_db(): 'WHERE': dict of key:values, translated to key=value AND ... (Optional) 'WHERE_NOT': dict of key:values, translated to key!=value AND ... (Optional) 'WHERE_OR': dict of key:values, translated to key=value OR ... (Optional) + 'WHERE_AND_OR: str 'AND' or 'OR'(by default) mark the priority to 'WHERE AND (WHERE_OR)' or (WHERE) OR WHERE_OR' (Optional) 'LIMIT': limit of number of rows (Optional) + 'DISTINCT': make a select distinct to remove repeated elements Return: a list with dictionarys at each row ''' #print sql_dict - select_= "SELECT " + ("*" if 'SELECT' not in sql_dict else ",".join(map(str,sql_dict['SELECT'])) ) + select_ = "SELECT " + if sql_dict.get("DISTINCT"): + select_ += "DISTINCT " + select_ += ("*" if not sql_dict.get('SELECT') else ",".join(map(str,sql_dict['SELECT'])) ) #print 'select_', select_ from_ = "FROM " + str(sql_dict['FROM']) #print 'from_', from_ where_and = None where_or = None - if 'WHERE' in sql_dict and len(sql_dict['WHERE']) > 0: - w=sql_dict['WHERE'] - where_and = " AND ".join(map( lambda x: str(x) + (" is Null" if w[x] is None else "='"+str(w[x])+"'"), w.keys()) ) - if 'WHERE_NOT' in sql_dict and len(sql_dict['WHERE_NOT']) > 0: - w=sql_dict['WHERE_NOT'] - where_and_not = " AND ".join(map( lambda x: str(x) + (" is not Null" if w[x] is None else "!='"+str(w[x])+"'"), w.keys()) ) + w = sql_dict.get('WHERE') + if w: + where_and = " AND ".join(map( lambda x: str(x) + (" is Null" if w[x] is None else "='"+str(w[x])+"'"), w.keys()) ) + w = sql_dict.get('WHERE_NOT') + if w: + where_and_not = " AND ".join(map( lambda x: str(x) + (" is not Null" if w[x] is None else "!='"+str(w[x])+"'"), w.keys()) ) if where_and: where_and += " AND " + where_and_not else: where_and = where_and_not - if 'WHERE_OR' in sql_dict and len(sql_dict['WHERE_OR']) > 0: - w=sql_dict['WHERE_OR'] + w = sql_dict.get('WHERE_OR') + if w: where_or = " OR ".join(map( lambda x: str(x) + (" is Null" if w[x] is None else "='"+str(w[x])+"'"), w.keys()) ) if where_and!=None and where_or!=None: - where_ = "WHERE (" + where_and + ") OR " + where_or + if sql_dict.get("WHERE_AND_OR") == "AND": + where_ = "WHERE " + where_and + " AND (" + where_or + ")" + else: + where_ = "WHERE (" + where_and + ") OR " + where_or elif where_and!=None and where_or==None: where_ = "WHERE " + where_and elif where_and==None and where_or!=None: @@ -250,7 +259,7 @@ class vim_db(): else: where_ = "" #print 'where_', where_ - limit_ = "LIMIT " + str(sql_dict['LIMIT']) if 'LIMIT' in sql_dict else "" + limit_ = "LIMIT " + str(sql_dict['LIMIT']) if sql_dict.get("LIMIT") else "" #print 'limit_', limit_ cmd = " ".join( (select_, from_, where_, limit_) ) for retry_ in range(0,2): @@ -1389,8 +1398,21 @@ class vim_db(): #insert resources nb_bridge_ifaces = nb_cores = nb_ifaces = nb_numas = 0 #insert bridged_ifaces + for iface in bridgedifaces: #generate and insert a iface uuid + if 'enable_dhcp' in iface and iface['enable_dhcp']: + dhcp_first_ip = iface["dhcp_first_ip"] + del iface["dhcp_first_ip"] + dhcp_last_ip = iface["dhcp_last_ip"] + del iface["dhcp_last_ip"] + dhcp_cidr = iface["cidr"] + del iface["cidr"] + del iface["enable_dhcp"] + used_dhcp_ips = self._get_dhcp_ip_used_list(iface["net_id"]) + iface["ip_address"] = self.get_free_ip_from_range(dhcp_first_ip, dhcp_last_ip, + dhcp_cidr, used_dhcp_ips) + iface['uuid'] = str(myUuid.uuid1()) # create_uuid cmd = "INSERT INTO uuids (uuid, root_uuid, used_at) VALUES ('%s','%s', 'ports')" % (iface['uuid'], uuid) self.logger.debug(cmd) @@ -1497,6 +1519,58 @@ class vim_db(): r,c = self.format_error(e, "new_instance", cmd) if r!=-HTTP_Request_Timeout or retry_==1: return r,c + def get_free_ip_from_range(self, first_ip, last_ip, cidr, ip_used_list): + """ + Calculate a free IP from a range given + :param first_ip: First dhcp ip range + :param last_ip: Last dhcp ip range + :param cidr: net cidr + :param ip_used_list: contain all used ips to avoid ip collisions + :return: + """ + + ip_tools = IPNetwork(cidr) + cidr_len = ip_tools.prefixlen + ips = IPNetwork(first_ip + '/' + str(cidr_len)) + ip_used_list.append(str(ips[0])) # first ip + ip_used_list.append(str(ips[1])) # gw ip + ip_used_list.append(str(ips[-1])) # broadcast ip + for vm_ip in ips: + if str(vm_ip) not in ip_used_list: + return vm_ip + + return None + + def _get_dhcp_ip_used_list(self, net_id): + """ + REtreive from DB all ips already used by the dhcp server for a given net + :param net_id: + :return: + """ + WHERE={'type': 'instance:ovs', 'net_id': net_id} + for retry_ in range(0, 2): + cmd = "" + self.cur = self.con.cursor(mdb.cursors.DictCursor) + select_ = "SELECT uuid, ip_address FROM ports " + + if WHERE is None or len(WHERE) == 0: + where_ = "" + else: + where_ = "WHERE " + " AND ".join( + map(lambda x: str(x) + (" is Null" if WHERE[x] is None else "='" + str(WHERE[x]) + "'"), + WHERE.keys())) + limit_ = "LIMIT 100" + cmd = " ".join((select_, where_, limit_)) + self.logger.debug(cmd) + self.cur.execute(cmd) + ports = self.cur.fetchall() + ip_address_list = [] + for port in ports: + ip_address_list.append(port['ip_address']) + + return ip_address_list + + def delete_instance(self, instance_id, tenant_id, net_dataplane_list, ports_to_free, net_ovs_list, logcause="requested by http"): for retry_ in range(0,2): cmd="" @@ -1520,7 +1594,7 @@ class vim_db(): net_dataplane_list.append(net[0]) # get ovs manangement nets - cmd = "SELECT DISTINCT net_id, vlan FROM ports WHERE instance_id='{}' AND net_id is not Null AND "\ + cmd = "SELECT DISTINCT net_id, vlan, ip_address, mac FROM ports WHERE instance_id='{}' AND net_id is not Null AND "\ "type='instance:ovs'".format(instance_id) self.logger.debug(cmd) self.cur.execute(cmd)