OF controller port mapping 30/1230/6
authormirabal <leonardo.mirabal@altran.com>
Mon, 6 Mar 2017 10:36:55 +0000 (11:36 +0100)
committermirabal <leonardo.mirabal@altran.com>
Thu, 9 Mar 2017 10:08:54 +0000 (11:08 +0100)
- Add of_port_mappings DB entry
- Add interface to ovim.py to handle of port mapping per datacenter

Change-Id: I4248c89c3b951f075d4f75d5bb79cdabe87b866c
Signed-off-by: mirabal <leonardo.mirabal@altran.com>
database_utils/migrate_vim_db.sh
httpserver.py
openvimd.py
ovim.py
templates/of_port_mapping.yaml [new file with mode: 0644]
vim_schema.py

index 137bbf9..e465e68 100755 (executable)
@@ -180,6 +180,7 @@ DATABASE_TARGET_VER_NUM=0
 [ $OPENVIM_VER_NUM -ge 5002 ] && DATABASE_TARGET_VER_NUM=10  #0.5.2   => 10
 [ $OPENVIM_VER_NUM -ge 5004 ] && DATABASE_TARGET_VER_NUM=11  #0.5.4   => 11
 [ $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   => 12
 #TODO ... put next versions here
 
 function upgrade_to_1(){
@@ -524,6 +525,34 @@ function downgrade_from_12(){
     echo "ALTER TABLE uuids  CHANGE COLUMN used_at used_at ENUM('flavors', 'hosts', 'images', 'instances', 'nets', 'ports', 'tenants') NULL DEFAULT NULL COMMENT 'Table that uses this UUID' ;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
     echo "DELETE FROM schema_version WHERE version_int = '12';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
 }
+function upgrade_to_13(){
+    echo "    upgrade database from version 0.12 to version 0.13"
+    echo "    Create of_port_mapings table "
+    echo "CREATE TABLE of_port_mappings (
+       uuid VARCHAR(36) NOT NULL,
+       ofc_id VARCHAR(36) NULL DEFAULT NULL,
+       region VARCHAR(64) NULL DEFAULT NULL,
+       compute_node VARCHAR(64) NULL DEFAULT NULL,
+       pci VARCHAR(50) NULL DEFAULT NULL,
+       switch_dpid VARCHAR(64) NULL DEFAULT NULL,
+       switch_port VARCHAR(64) NULL DEFAULT NULL,
+       switch_mac CHAR(18) NULL DEFAULT NULL,
+       UNIQUE INDEX switch_dpid_switch_port (switch_dpid, switch_port),
+       UNIQUE INDEX switch_dpid_switch_mac (switch_dpid, switch_mac),
+       UNIQUE INDEX region_compute_node_pci (region, compute_node, pci),
+       INDEX FK_of_port_mappings_ofcs (ofc_id),
+       CONSTRAINT FK_of_port_mappings_ofcs FOREIGN KEY (ofc_id) REFERENCES ofcs (uuid) ON UPDATE CASCADE ON DELETE CASCADE)
+    COLLATE='utf8_general_ci'
+    ENGINE=InnoDB;"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "INSERT INTO schema_version (version_int, version, openvim_ver, comments, date) VALUES (13, '0.13', '0.5.6', 'Add of_port_mapings table', '2017-03-09');"| $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
+function downgrade_from_13(){
+    echo "    downgrade database from version 0.13 to version 0.12"
+    echo "    Delete of_port_mappings table"
+    echo "DROP TABLE of_port_mappings;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+    echo "DELETE FROM schema_version WHERE version_int = '13';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
 #TODO ... put funtions here
 
 echo "db version = "${DATABASE_VER_NUM}
index 3e89073..7ef02f4 100644 (file)
@@ -47,7 +47,7 @@ from vim_schema import host_new_schema, host_edit_schema, tenant_new_schema, \
     flavor_new_schema, flavor_update_schema, \
     image_new_schema, image_update_schema, \
     server_new_schema, server_action_schema, network_new_schema, network_update_schema, \
-    port_new_schema, port_update_schema, openflow_controller_schema
+    port_new_schema, port_update_schema, openflow_controller_schema, of_port_map_new_schema
 import ovim
 import logging
 
@@ -147,6 +147,7 @@ def check_extended(extended, allow_net_attach=False):
 #
 # dictionaries that change from HTTP API to database naming
 #
+http2db_id={'id':'uuid'}
 http2db_host={'id':'uuid'}
 http2db_tenant={'id':'uuid'}
 http2db_flavor={'id':'uuid','imageRef':'image_id'}
@@ -2340,3 +2341,77 @@ def http_delete_port_id(port_id):
         bottle.abort(HTTP_Bad_Request, str(e))
 
 
+@bottle.route(url_base + '/openflow/mapping', method='POST')
+def http_of_port_mapping():
+    """
+    Insert a tenant into the database.
+    :return:
+    """
+    my = config_dic['http_threads'][threading.current_thread().name]
+
+    try:
+        http_content = format_in(of_port_map_new_schema)
+        r = remove_extra_items(http_content, of_port_map_new_schema)
+        if r is not None:
+            my.logger.error("http_of_port_mapping: Warning: remove extra items " + str(r), exc_info=True)
+
+        # insert in data base
+        port_mapping = my.ovim.set_of_port_mapping(http_content['of_port_mapings'])
+        change_keys_http2db(port_mapping, http2db_id, reverse=True)
+        delete_nulls(port_mapping)
+        data = {'of_port_mappings': port_mapping}
+        return format_out(data)
+    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))
+
+
+@bottle.route(url_base + '/openflow/mapping', method='GET')
+def get_of_port_mapping():
+    """
+    Insert a tenant into the database.
+    :return:
+    """
+    my = config_dic['http_threads'][threading.current_thread().name]
+
+    try:
+        select_, where_, limit_ = filter_query_string(bottle.request.query, http2db_id,
+                                                      ('id', 'ofc_id', 'region', 'compute_node', 'pci',
+                                                       'switch_dpid', 'switch_port', 'switch_mac'))
+        # insert in data base
+        port_mapping = my.ovim.get_of_port_mappings(select_, where_)
+        change_keys_http2db(port_mapping, http2db_id, reverse=True)
+        delete_nulls(port_mapping)
+        data = {'of_port_mappings': port_mapping}
+        return format_out(data)
+    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))
+
+
+@bottle.route(url_base + '/openflow/mapping/<region>', method='DELETE')
+def delete_of_port_mapping(region):
+    """
+    Insert a tenant into the database.
+    :return:
+    """
+    my = config_dic['http_threads'][threading.current_thread().name]
+
+    try:
+        # insert in data base
+        db_filter = {'region': region}
+        result = my.ovim.clear_of_port_mapping(db_filter)
+        data = {'result': result}
+        return format_out(data)
+    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))
index 923ad16..5441f4d 100755 (executable)
@@ -30,9 +30,9 @@ and host controllers
 
 __author__ = "Alfonso Tierno"
 __date__ = "$10-jul-2014 12:07:15$"
-__version__ = "0.5.5-r522"
+__version__ = "0.5.6-r523"
 version_date = "Feb 2017"
-database_version = "0.12"      #expected database schema version
+database_version = "0.13"      #expected database schema version
 
 import httpserver
 import auxiliary_functions as af
diff --git a/ovim.py b/ovim.py
index 02114a1..02f52e0 100644 (file)
--- a/ovim.py
+++ b/ovim.py
@@ -1073,6 +1073,63 @@ class ovim():
         else:
             raise ovimException(str(content), -result)
 
+    def set_of_port_mapping(self, of_maps, ofc_id=None, switch_dpid=None, region=None):
+        """
+        Create new port mapping entry
+        :param of_maps: List with port mapping information
+        # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
+                "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
+        :param ofc_id: ofc id
+        :param switch_dpid: switch  dpid
+        :param region: datacenter region id
+        :return:
+        """
+
+        for map in of_maps:
+            if ofc_id:
+                map['ofc_id'] = ofc_id
+            if switch_dpid:
+                map['switch_dpid'] = switch_dpid
+            if region:
+                map['region'] = region
+
+        for of_map in of_maps:
+            result, uuid = self.db.new_row('of_port_mappings', of_map, True)
+            if result > 0:
+                of_map["uuid"] = uuid
+            else:
+                raise ovimException(str(uuid), -result)
+        return of_maps
+
+    def clear_of_port_mapping(self, db_filter={}):
+        """
+        Clear port mapping filtering using db_filter dict
+        :param db_filter: Parameter to filter during remove process
+        :return:
+        """
+        result, content = self.db.delete_row_by_dict(FROM='of_port_mappings', WHERE=db_filter)
+        # delete_row_by_key
+        if result >= 0:
+            return content
+        else:
+            raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter)),
+                                HTTP_Internal_Server_Error)
+
+    def get_of_port_mappings(self, column=None, db_filter=None, db_limit=None):
+        """
+        Retrive port mapping from DB
+        :param column:
+        :param db_filter:
+        :return:
+        """
+        result, content = self.db.get_table(SELECT=column, WHERE=db_filter, FROM='of_port_mappings', LIMIT=db_limit)
+
+        if result < 0:
+            self.logger.error("get_of_port_mappings Error %d %s", result, content)
+            raise ovimException(str(content), -result)
+        else:
+            return content
+
     def get_dhcp_controller(self):
         """
         Create an host_thread object for manage openvim controller and not create a thread for itself
diff --git a/templates/of_port_mapping.yaml b/templates/of_port_mapping.yaml
new file mode 100644 (file)
index 0000000..a8c1eff
--- /dev/null
@@ -0,0 +1,32 @@
+##
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+
+of_port_mapings:
+    - region:         spain                                   # Region name as e.g. Datacenter id
+      # ofc_id:         f6fb715a-03f0-11e7-9460-080027d220d5   # Openflow controller uuid, must exist
+      compute_node:   35f9de96-040a-11e7-93ae-92361f002671    # Compute node id
+      pci:            "0000:00:10.1"                          # PCI address port of the computer node
+      switch_dpid:    "11:22:33:44:55:66:77:88"               # Swicth DPID
+      switch_port:    "port-1/1"                              # Switch port name
+      switch_mac:     "5E:64:A2:86:06:46"                     # Switch port MAC
+    - region:         spain                                   # Region name as e.g. Datacenter id
+      # ofc_id:         f6fb715a-03f0-11e7-9460-080027d220d5   # Openflow controller uuid, must exist
+      compute_node:   35f9de96-040a-11e7-93ae-92361f002671    # Compute node id
+      pci:            "0000:00:10.2"                          # PCI address port of the computer node
+      switch_dpid:    "11:22:33:44:55:66:77:88"               # Swicth DPID
+      switch_port:    "port-1/2"                              # Switch port name
+      switch_mac:     "5E:64:A2:86:06:47"                     # Switch port MAC
index 1dbd53c..c2dc1e2 100644 (file)
@@ -165,6 +165,7 @@ tenant_new_schema = {
     "required": ["tenant"],
     "additionalProperties": False
 }
+
 tenant_edit_schema = {
     "title":"tenant edition information schema",
     "$schema": "http://json-schema.org/draft-04/schema#",
@@ -736,4 +737,31 @@ openflow_controller_schema = {
     },
     "required": ["ofc"],
     "additionalProperties": False
+}
+
+of_port_new_schema = {
+    "title": "OF port mapping",
+    "type": "object",
+    "properties": {
+        "ofc_id": id_schema,
+        "region": nameshort_schema,
+        "compute_node": nameshort_schema,
+        "pci": pci_schema,
+        "switch_dpid": nameshort_schema,
+        "switch_port": nameshort_schema,
+        "switch_mac": mac_schema
+    },
+    "required": ["region", "compute_node",  "pci", "switch_dpid"]
+}
+
+of_port_map_new_schema = {
+    "title": "OF port mapping",
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "type": "object",
+    "properties": {
+        "of_port_mapings": {"type": "array", "items": of_port_new_schema, "minLenght":1},
+    },
+    "required": ["of_port_mapings"],
+    "additionalProperties": False
+
 }
\ No newline at end of file