Add region to nets and allow ovelapping vlan at each region 46/1746/2
authortierno <alfonso.tiernosepulveda@telefonica.com>
Wed, 3 May 2017 15:42:52 +0000 (17:42 +0200)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Thu, 4 May 2017 13:21:01 +0000 (15:21 +0200)
Change-Id: If5ee574394796c6b6d52d07ec5929851cfd6e813
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
database_utils/migrate_vim_db.sh
osm_openvim/ovim.py
osm_openvim/vim_db.py
osm_openvim/vim_schema.py

index a5ff836..a56ede0 100755 (executable)
@@ -33,7 +33,7 @@ DBPORT="3306"
 DBNAME="vim_db"
 QUIET_MODE=""
 #TODO update it with the last database version
-LAST_DB_VERSION=17
+LAST_DB_VERSION=18
 
 # Detect paths
 MYSQL=$(which mysql)
@@ -185,6 +185,7 @@ fi
 #[ $OPENVIM_VER_NUM -ge 5008 ] && DATABASE_TARGET_VER_NUM=15  #0.5.8   => 15
 #[ $OPENVIM_VER_NUM -ge 5009 ] && DATABASE_TARGET_VER_NUM=16  #0.5.9   => 16
 #[ $OPENVIM_VER_NUM -ge 5010 ] && DATABASE_TARGET_VER_NUM=17  #0.5.10  => 17
+#[ $OPENVIM_VER_NUM -ge 5013 ] && DATABASE_TARGET_VER_NUM=18  #0.5.13  => 18
 #TODO ... put next versions here
 
 function upgrade_to_1(){
@@ -646,6 +647,29 @@ function downgrade_from_17(){
     echo "DELETE FROM schema_version WHERE version_int = '17';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
 }
 
+function upgrade_to_18(){
+    echo "    Add 'region' at 'nets' and change unique index vlan+region"
+    echo "ALTER TABLE nets ADD COLUMN region VARCHAR(64) NULL DEFAULT NULL AFTER admin_state_up, " \
+            "DROP INDEX type_vlan;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "    Fill 'region' with __OVS__/__DATA__ for OVS/openflow provider at nets"
+    echo "UPDATE nets set region='__OVS__' where provider like 'OVS%';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "UPDATE nets set region='__DATA__' where type='data' or type='ptp';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "    Create new index region_vlan at nets"
+       echo "ALTER TABLE nets ADD UNIQUE INDEX region_vlan (region, vlan);" \
+            | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "INSERT INTO schema_version (version_int, version, openvim_ver, comments, date) "\
+            "VALUES (18, '0.18', '0.5.13', 'Add region to nets, change vlan unique index', '2017-05-03');"\
+         | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
+function downgrade_from_18(){
+    echo "    Delete 'region' at 'nets' and change back unique index vlan+type"
+    echo "ALTER TABLE nets DROP INDEX region_vlan, DROP COLUMN region;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "    Create back index type_vlan at nets"
+       echo "ALTER TABLE nets ADD UNIQUE INDEX type_vlan (type, vlan);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "DELETE FROM schema_version WHERE version_int = '18';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
 #TODO ... put funtions here
 
 # echo "db version = "${DATABASE_VER_NUM}
index e7a8b49..c79f86a 100755 (executable)
@@ -42,9 +42,9 @@ import openflow_conn
 
 __author__ = "Alfonso Tierno, Leonardo Mirabal"
 __date__ = "$06-Feb-2017 12:07:15$"
-__version__ = "0.5.12-r528"
+__version__ = "0.5.13-r529"
 version_date = "May 2017"
-database_version = 17      #needed database schema version
+database_version = 18      #needed database schema version
 
 HTTP_Bad_Request =          400
 HTTP_Unauthorized =         401
@@ -507,6 +507,7 @@ class ovim():
         net_vlan = network.get("vlan")
         net_bind_net = network.get("bind_net")
         net_bind_type = network.get("bind_type")
+        net_region = network.get("region")
         name = network["name"]
 
         # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
@@ -602,8 +603,13 @@ class ovim():
                 net_vlan = bridge_net[1]
         elif net_type == 'bridge_data' or net_type == 'bridge_man' and self.config['network_type'] == 'ovs':
             net_provider = 'OVS'
+        if not net_region:
+            if net_type == "data" or net_type == "ptp":
+                net_region = "__DATA__"
+            elif net_provider == "OVS":
+                net_region = "__OVS__"
         if not net_vlan and (net_type == "data" or net_type == "ptp" or net_provider == "OVS"):
-            net_vlan = self.db.get_free_net_vlan()
+            net_vlan = self.db.get_free_net_vlan(net_region)
             if net_vlan < 0:
                 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error)
         if net_provider == 'OVS':
@@ -612,6 +618,7 @@ class ovim():
         network['provider'] = net_provider
         network['type'] = net_type
         network['vlan'] = net_vlan
+        network['region'] = net_region
         dhcp_integrity = True
         if 'enable_dhcp' in network and network['enable_dhcp']:
             dhcp_integrity = self._check_dhcp_data_integrity(network)
index c34160d..f69c305 100644 (file)
@@ -56,8 +56,7 @@ class vim_db():
         ''' 
         #initialization
         self.net_vlan_range = vlan_range
-        self.net_vlan_usedlist = None
-        self.net_vlan_lastused = self.net_vlan_range[0] -1
+        self.vlan_config = {}
         self.debug=debug
         if logger_name:
             self.logger_name = logger_name
@@ -176,43 +175,49 @@ class vim_db():
         else:
             return json.dumps(out)
     
-    def __get_used_net_vlan(self):
+    def __get_used_net_vlan(self, region=None):
         #get used from database if needed
+        vlan_region = self.vlan_config[region]
         try:
-            cmd = "SELECT vlan FROM nets WHERE vlan>='%s' ORDER BY vlan LIMIT 25" % self.net_vlan_lastused
+            cmd = "SELECT vlan FROM nets WHERE vlan>='{}' and region{} ORDER BY vlan LIMIT 25".format(
+                vlan_region["lastused"], "='"+region+"'" if region else " is NULL")
             with self.con:
                 self.cur = self.con.cursor()
                 self.logger.debug(cmd)
                 self.cur.execute(cmd)
                 vlan_tuple = self.cur.fetchall()
-                #convert a tuple of tuples in a list of numbers
-                self.net_vlan_usedlist = []
+                # convert a tuple of tuples in a list of numbers
+                vlan_region["usedlist"] = []
                 for k in vlan_tuple:
-                    self.net_vlan_usedlist.append(k[0])
-            return 0
+                    vlan_region["usedlist"].append(k[0])
         except (mdb.Error, AttributeError) as e:
             return self.format_error(e, "get_free_net_vlan", cmd)
     
-    def get_free_net_vlan(self):
+    def get_free_net_vlan(self, region=None):
         '''obtain a vlan not used in any net'''
-        
+        if region not in self.vlan_config:
+            self.vlan_config[region] = {
+                "usedlist": None,
+                "lastused": self.net_vlan_range[0] - 1
+            }
+        vlan_region = self.vlan_config[region]
+
         while True:
-            self.logger.debug("net_vlan_lastused:%d  net_vlan_range:%d-%d  net_vlan_usedlist:%s", 
-                            self.net_vlan_lastused, self.net_vlan_range[0], self.net_vlan_range[1], str(self.net_vlan_usedlist))
-            self.net_vlan_lastused += 1
-            if self.net_vlan_lastused ==  self.net_vlan_range[1]:
-                #start from the begining
-                self.net_vlan_lastused =  self.net_vlan_range[0]
-                self.net_vlan_usedlist = None
-            if self.net_vlan_usedlist is None \
-            or (len(self.net_vlan_usedlist)>0 and self.net_vlan_lastused >= self.net_vlan_usedlist[-1] and len(self.net_vlan_usedlist)==25):
-                r = self.__get_used_net_vlan()
-                if r<0: return r
-                self.logger.debug("new net_vlan_usedlist %s", str(self.net_vlan_usedlist))
-            if self.net_vlan_lastused in self.net_vlan_usedlist:
+            self.logger.debug("get_free_net_vlan() region[{}]={}, net_vlan_range:{}-{} ".format(region, vlan_region,
+                            self.net_vlan_range[0], self.net_vlan_range[1]))
+            vlan_region["lastused"] += 1
+            if vlan_region["lastused"] ==  self.net_vlan_range[1]:
+                # start from the begining
+                vlan_region["lastused"] =  self.net_vlan_range[0]
+                vlan_region["usedlist"] = None
+            if vlan_region["usedlist"] is None or \
+                    (len(vlan_region["usedlist"])==25 and vlan_region["lastused"] >= vlan_region["usedlist"][-1]):
+                self.__get_used_net_vlan(region)
+                self.logger.debug("new net_vlan_usedlist %s", str(vlan_region["usedlist"]))
+            if vlan_region["lastused"] in vlan_region["usedlist"]:
                 continue
             else:
-                return self.net_vlan_lastused
+                return vlan_region["lastused"]
                 
     def get_table(self, **sql_dict):
         ''' Obtain rows from a table.
index c2dc1e2..69d6a0c 100644 (file)
@@ -583,27 +583,28 @@ server_action_schema = {
 }
 
 network_new_schema = {
-    "title":"network creation information schema",
+    "title": "network creation information schema",
     "$schema": "http://json-schema.org/draft-04/schema#",
-    "type":"object",
-    "properties":{
-        "network":{
-            "type":"object",
+    "type": "object",
+    "properties": {
+        "network": {
+            "type": "object",
             "properties":{
-                "id":id_schema,
-                "name":name_schema,
-                "type":{"type":"string", "enum":["bridge_man","bridge_data","data", "ptp"]},
-                "shared":{"type":"boolean"},
-                "tenant_id":id_schema,
-                "admin_state_up":{"type":"boolean"},
-                "provider:vlan":vlan_schema,
-                "provider:physical":net_bind_schema,
-                "cidr":cidr_schema,
-                "enable_dhcp": {"type":"boolean"},
+                "id": id_schema,
+                "name": name_schema,
+                "type": {"type":"string", "enum": ["bridge_man", "bridge_data", "data", "ptp"]},
+                "shared": {"type": "boolean"},
+                "tenant_id": id_schema,
+                "admin_state_up": {"type": "boolean"},
+                "provider:vlan": vlan_schema,
+                "provider:physical": net_bind_schema,
+                "region": nameshort_schema,
+                "cidr": cidr_schema,
+                "enable_dhcp": {"type": "boolean"},
                 "dhcp_first_ip": ip_schema,
                 "dhcp_last_ip": ip_schema,
-                "bind_net":name_schema, #can be name, or uuid
-                "bind_type":{"oneOf":[{"type":"null"},{"type":"string", "pattern":"^vlan:[0-9]{1,4}$"}]}
+                "bind_net": name_schema,   # can be name, or uuid
+                "bind_type": {"oneOf": [{"type": "null"}, {"type": "string", "pattern": "^vlan:[0-9]{1,4}$"}]}
             },
             "required": ["name"]
         }