Modify http get/clear openflows to handle n ofc_id 99/1299/4
authormirabal <leonardo.mirabal@altran.com>
Wed, 15 Mar 2017 11:42:27 +0000 (12:42 +0100)
committermirabal <leonardo.mirabal@altran.com>
Thu, 16 Mar 2017 11:21:54 +0000 (12:21 +0100)
- Add ofc_id to http_get_openflow_ports
- Add ofc_id http_clear_openflow_rules
- Both http service will handle multimple ofc thread and the task will be injected in a thread nu ofc_id
- ofc_id Added to of_flow table to of_flows

Change-Id: Id9b1ec67341d70eaea8b678fa4ef34c5a81a3c21
Signed-off-by: mirabal <leonardo.mirabal@altran.com>
database_utils/migrate_vim_db.sh
httpserver.py
openflow_thread.py
openvimd.py
ovim.py

index 8def5cb..a3d96e8 100755 (executable)
@@ -182,6 +182,7 @@ DATABASE_TARGET_VER_NUM=0
 [ $OPENVIM_VER_NUM -ge 5005 ] && DATABASE_TARGET_VER_NUM=12  #0.5.5   => 12
 [ $OPENVIM_VER_NUM -ge 5006 ] && DATABASE_TARGET_VER_NUM=13  #0.5.6   => 13
 [ $OPENVIM_VER_NUM -ge 5007 ] && DATABASE_TARGET_VER_NUM=14  #0.5.7   => 14
+[ $OPENVIM_VER_NUM -ge 5008 ] && DATABASE_TARGET_VER_NUM=15  #0.5.8   => 15
 #TODO ... put next versions here
 
 function upgrade_to_1(){
@@ -584,6 +585,24 @@ function downgrade_from_14(){
     echo "DELETE FROM schema_version WHERE version_int = '14';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
 }
 
+function upgrade_to_15(){
+    echo "    upgrade database from version 0.14 to version 0.15"
+    echo "    Add ofc_id colum to 'of_flows'"
+    echo "ALTER TABLE of_flows
+       ADD COLUMN ofc_id VARCHAR(36) NULL DEFAULT NULL AFTER net_id,
+       ADD CONSTRAINT FK_of_flows_ofcs FOREIGN KEY (ofc_id) REFERENCES ofcs (uuid) ON UPDATE CASCADE ON DELETE SET NULL;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "INSERT INTO schema_version (version_int, version, openvim_ver, comments, date) VALUES (15, '0.15', '0.5.8', 'Add ofc_id colum to of_flows', '2017-03-15');"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
+function downgrade_from_15(){
+    echo "    downgrade database from version 0.15 to version 0.14"
+    echo "    Delete ofc_id to 'of_flows'"
+    echo "ALTER TABLE of_flows
+       DROP COLUMN ofc_id,
+       DROP FOREIGN KEY FK_of_flows_ofcs;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "DELETE FROM schema_version WHERE version_int = '15';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
 #TODO ... put funtions here
 
 echo "db version = "${DATABASE_VER_NUM}
index e35daf0..6a16f39 100644 (file)
@@ -2196,9 +2196,9 @@ def http_put_openflow_id(network_id):
     data = {'result': str(result) + " nets updates"}
     return format_out(data)
 
-
+@bottle.route(url_base + '/networks/clear/openflow/<ofc_id>', method='DELETE')
 @bottle.route(url_base + '/networks/clear/openflow', method='DELETE')
-def http_clear_openflow_rules():
+def http_clear_openflow_rules(ofc_id=None):
     """
     To make actions over the net. The action is to delete ALL openflow rules
     :return:
@@ -2208,7 +2208,7 @@ def http_clear_openflow_rules():
     if not my.admin:
         bottle.abort(HTTP_Unauthorized, "Needed admin privileges")
     try:
-        my.ovim.delete_openflow_rules()
+        my.ovim.delete_openflow_rules(ofc_id)
     except ovim.ovimException as e:
         my.logger.error(str(e), exc_info=True)
         bottle.abort(e.http_code, str(e))
@@ -2219,16 +2219,25 @@ def http_clear_openflow_rules():
     data = {'result': " Clearing openflow rules in process"}
     return format_out(data)
 
-
+@bottle.route(url_base + '/networks/openflow/ports/<ofc_id>', method='GET')
 @bottle.route(url_base + '/networks/openflow/ports', method='GET')
-def http_get_openflow_ports():
+def http_get_openflow_ports(ofc_id=None):
     """
     Obtain switch ports names of openflow controller
     :return:
     """
     my = config_dic['http_threads'][threading.current_thread().name]
-    ports = my.ovim.get_openflow_ports()
-    data = {'ports': ports}
+
+    try:
+        ports = my.ovim.get_openflow_ports(ofc_id)
+        data = {'ports': ports}
+    except ovim.ovimException as e:
+        my.logger.error(str(e), exc_info=True)
+        bottle.abort(e.http_code, str(e))
+    except Exception as e:
+        my.logger.error(str(e), exc_info=True)
+        bottle.abort(HTTP_Bad_Request, str(e))
+
     return format_out(data)
 #
 # PORTS
index 638ab19..b797f2d 100644 (file)
@@ -95,11 +95,14 @@ class of_test_connector():
         self.rules= {}
         self.logger = logging.getLogger('vim.OF.TEST')
         self.logger.setLevel(getattr(logging, params.get("of_debug", "ERROR")))
+        self.pp2ofi = {}
 
     def get_of_switches(self):
         return 0, ()
+
     def obtain_port_correspondence(self):
         return 0, ()
+
     def del_flow(self, flow_name):
         if flow_name in self.rules:
             self.logger.debug("del_flow OK")
@@ -108,10 +111,12 @@ class of_test_connector():
         else:
             self.logger.warning("del_flow not found")
             return -1, "flow %s not found"
+
     def new_flow(self, data):
         self.rules[ data["name"] ] = data
         self.logger.debug("new_flow OK")
         return 0, None
+
     def get_of_rules(self, translate_of_ports=True):
         return 0, self.rules
 
index 8fe3843..6090741 100755 (executable)
@@ -30,9 +30,9 @@ and host controllers
 
 __author__ = "Alfonso Tierno"
 __date__ = "$10-jul-2014 12:07:15$"
-__version__ = "0.5.7-r524"
-version_date = "Feb 2017"
-database_version = "0.14"      #expected database schema version
+__version__ = "0.5.8-r524"
+version_date = "March 2017"
+database_version = "0.15"      #expected database schema version
 
 import httpserver
 import auxiliary_functions as af
diff --git a/ovim.py b/ovim.py
index 16b3f03..5b36b73 100644 (file)
--- a/ovim.py
+++ b/ovim.py
@@ -316,7 +316,7 @@ class ovim():
     def _load_of_module(self, db_config):
         """
         import python module for each SDN controller supported
-        :param default: SDN dn information
+        :param db_config: SDN dn information
         :return: Module
         """
         if not db_config:
@@ -326,8 +326,8 @@ class ovim():
 
         try:
             if self.of_test_mode:
-                return  oft.of_test_connector({"name": db_config['type'], "dpid": db_config['dpid'],
-                                               "of_debug": self.config['log_level_of']})
+                return oft.of_test_connector({"name": db_config['type'], "dpid": db_config['dpid'],
+                                              "of_debug": self.config['log_level_of']})
             temp_dict = {}
 
             if db_config:
@@ -719,9 +719,8 @@ class ovim():
             where_ = {}
         else:
             where_ = {"net_id": network_id}
-
         result, content = self.db.get_table(
-            SELECT=("name", "net_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
+            SELECT=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
             WHERE=where_, FROM='of_flows')
 
         if result < 0:
@@ -763,24 +762,44 @@ class ovim():
 
         return result
 
-    def delete_openflow_rules(self):
+    def delete_openflow_rules(self, ofc_id=None):
         """
         To make actions over the net. The action is to delete ALL openflow rules
         :return: return operation result
         """
-        # ignore input data
-        r, c = self.config['of_thread'].insert_task("clear-all")
-        if r < 0:
-            raise ovimException(str(c), -r)
+
+        if not ofc_id:
+            if 'Default' in self.config['ofcs_thread']:
+                r, c = self.config['ofcs_thread']['Default'].insert_task("clear-all")
+            else:
+                raise ovimException("Default Openflow controller not not running", HTTP_Not_Found)
+
+        elif ofc_id in self.config['ofcs_thread']:
+            r, c = self.config['ofcs_thread'][ofc_id].insert_task("clear-all")
+
+            # ignore input data
+            if r < 0:
+                raise ovimException(str(c), -r)
+        else:
+            raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id), HTTP_Not_Found)
         return r
 
-    def get_openflow_ports(self):
+    def get_openflow_ports(self, ofc_id=None):
         """
         Obtain switch ports names of openflow controller
         :return: Return flow ports in DB
         """
-        data = {'ports': self.config['of_thread'].OF_connector.pp2ofi}
-        return data
+        if not ofc_id:
+            if 'Default' in self.config['ofcs_thread']:
+                conn = self.config['ofcs_thread']['Default'].OF_connector
+            else:
+                raise ovimException("Default Openflow controller not not running", HTTP_Not_Found)
+
+        if ofc_id in self.config['ofcs_thread']:
+            conn = self.config['ofcs_thread'][ofc_id].OF_connector
+        else:
+            raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id), HTTP_Not_Found)
+        return conn.pp2ofi
 
     def get_ports(self, columns=None, filter={}, limit=None):
         # result, content = my.db.get_ports(where_)