Fix update SDN net on scale 70/8670/3
authortierno <alfonso.tiernosepulveda@telefonica.com>
Mon, 9 Mar 2020 08:40:59 +0000 (08:40 +0000)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Thu, 19 Mar 2020 12:14:00 +0000 (12:14 +0000)
allow external port for SDN net

Change-Id: Ie4665397f8cbe9dfa5a2b026c36016e5fafaa722
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
RO/osm_ro/db_base.py
RO/osm_ro/nfvo.py
RO/osm_ro/nfvo_db.py
RO/osm_ro/vim_thread.py

index 9c13133..1db72e9 100644 (file)
@@ -525,8 +525,8 @@ class db_base():
         # gettting uuid
         values = ",".join(map(self.__tuple2db_format_set, UPDATE.items() ))
         if modified_time:
-            values += ",modified_at={:f}".format(modified_time)
-        cmd= "UPDATE " + table + " SET " + values + " WHERE " + self.__create_where(WHERE)
+            values += "{}modified_at={:f}".format("," if values else "", modified_time)
+        cmd = "UPDATE " + table + " SET " + values + " WHERE " + self.__create_where(WHERE)
         self.logger.debug(cmd)
         self.cur.execute(cmd)
         return self.cur.rowcount
index 4d78e44..25d8cc6 100644 (file)
@@ -3229,12 +3229,12 @@ def create_instance(mydb, tenant_id, instance_dict):
                     else:
                         update(scenario_net['ip_profile'], ipprofile_db)
 
-                if 'provider-network' in net_instance_desc:
-                        provider_network_db = net_instance_desc['provider-network']
-                        if 'provider-network' not in scenario_net:
-                            scenario_net['provider-network'] = provider_network_db
-                        else:
-                            update(scenario_net['provider-network'], provider_network_db)
+                if net_instance_desc.get('provider-network'):
+                    provider_network_db = net_instance_desc['provider-network']
+                    if 'provider_network' not in scenario_net:
+                        scenario_net['provider_network'] = provider_network_db
+                    else:
+                        update(scenario_net['provider_network'], provider_network_db)
 
             for vdu_id, vdu_instance_desc in vnf_instance_desc.get("vdus", {}).items():
                 for scenario_vm in scenario_vnf['vms']:
@@ -3481,7 +3481,11 @@ def create_instance(mydb, tenant_id, instance_dict):
                         "created": create_network, # TODO py3
                         "sdn": True,
                     })
+
                     task_wim_extra = {"params": [net_type, wim_account_name]}
+                    # add sdn interfaces
+                    if sce_net.get('provider_network') and sce_net['provider_network'].get("sdn-ports"):
+                        task_wim_extra["sdn-ports"] = sce_net['provider_network'].get("sdn-ports")
                     db_vim_action = {
                         "instance_action_id": instance_action_id,
                         "status": "SCHEDULED",
@@ -4821,6 +4825,16 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict):
                         "extra": yaml.safe_dump({"params": vm_interfaces},
                                                 default_flow_style=True, width=256)
                     }
+                    # get affected instance_interfaces (deleted on cascade) to check if a wim_network must be updated
+                    deleted_interfaces = mydb.get_rows(
+                        SELECT=("instance_wim_net_id", ),
+                        FROM="instance_interfaces",
+                        WHERE={"instance_vm_id": vdu_id, "instance_wim_net_id<>": None},
+                    )
+                    for deleted_interface in deleted_interfaces:
+                        db_vim_actions.append({"TO-UPDATE": {}, "WHERE": {
+                            "item": "instance_wim_nets", "item_id": deleted_interface["instance_wim_net_id"]}})
+
                     task_index += 1
                     db_vim_actions.append(db_vim_action)
                     vm_result["deleted"].append(vdu_id)
@@ -4887,6 +4901,9 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict):
                             'port_security': vm_iface['port_security']
                         }
                         db_instance_interfaces.append(db_vm_iface)
+                        if db_vm_iface["instance_wim_net_id"]:
+                            db_vim_actions.append({"TO-UPDATE": {}, "WHERE": {
+                                "item": "instance_wim_nets", "item_id": db_vm_iface["instance_wim_net_id"]}})
                     task_params_copy = deepcopy(task_params)
                     for iface in task_params_copy[5]:
                         iface["uuid"] = iface2iface[iface["uuid"]]
index df4f161..9ae26c4 100644 (file)
@@ -784,6 +784,10 @@ class nfvo_db(db_base.db_base):
                     if "TO-DELETE" in row:
                         self._delete_row_by_id_internal(table_name, row["TO-DELETE"])
                         continue
+                    if "TO-UPDATE" in row:
+                        self._update_rows(table_name, UPDATE=row["TO-UPDATE"], WHERE=row["WHERE"],
+                                          modified_time=created_time)
+                        continue
                     if table_name in self.tables_with_created_field:
                         if "created_at" in row:
                             created_time_param = created_time + (index + row.pop("created_at"))*0.00001
index d0b8dc9..622cccb 100644 (file)
@@ -320,6 +320,8 @@ class vim_thread(threading.Thread):
                 copy_to["sdn_net_id"] = copy_from["sdn_net_id"]
             if copy_from.get("interfaces"):
                 copy_to["interfaces"] = copy_from["interfaces"]
+            if copy_from.get("sdn-ports"):
+                copy_to["sdn-ports"] = copy_from["sdn-ports"]
             if copy_from.get("created_items"):
                 if not copy_to.get("created_items"):
                     copy_to["created_items"] = {}
@@ -1138,21 +1140,21 @@ class vim_thread(threading.Thread):
             # look for ports
             sdn_ports = []
             pending_ports = 0
+            vlan_used = None
 
             ports = self.db.get_rows(FROM='instance_interfaces', WHERE={'instance_wim_net_id': task["item_id"]})
             sdn_need_update = False
-            if len(ports) != len(connected_ports):
-                sdn_need_update = True
             for port in ports:
+                vlan_used = port.get("vlan") or vlan_used
                 # TODO. Do not connect if already done
                 if port.get("compute_node") and port.get("pci"):
-                    for map in self.port_mappings:
-                        if map.get("device_id") == port["compute_node"] and \
-                                map.get("device_interface_id") == port["pci"]:
+                    for pmap in self.port_mappings:
+                        if pmap.get("device_id") == port["compute_node"] and \
+                                pmap.get("device_interface_id") == port["pci"]:
                             break
                     else:
                         if self.sdnconn_config.get("mapping_not_needed"):
-                            map = {
+                            pmap = {
                                 "service_endpoint_id": "{}:{}".format(port["compute_node"], port["pci"]),
                                 "service_endpoint_encapsulation_info": {
                                     "vlan": port["vlan"],
@@ -1162,25 +1164,25 @@ class vim_thread(threading.Thread):
                                 }
                             }
                         else:
-                            map = None
+                            pmap = None
                             error_list.append("Port mapping not found for compute_node={} pci={}".format(
                                 port["compute_node"], port["pci"]))
 
-                    if map:
-                        if port["uuid"] not in connected_ports or port["modified_at"] > last_update:
+                    if pmap:
+                        if port["modified_at"] > last_update:
                             sdn_need_update = True
                         new_connected_ports.append(port["uuid"])
                         sdn_ports.append({
-                            "service_endpoint_id": map["service_endpoint_id"],
+                            "service_endpoint_id": pmap["service_endpoint_id"],
                             "service_endpoint_encapsulation_type": "dot1q" if port["model"] == "SR-IOV" else None,
                             "service_endpoint_encapsulation_info": {
                                 "vlan": port["vlan"],
                                 "mac": port["mac_address"],
-                                "device_id": map.get("device_id"),
-                                "device_interface_id": map.get("device_interface_id"),
-                                "switch_dpid": map.get("switch_dpid"),
-                                "switch_port": map.get("switch_port"),
-                                "service_mapping_info": map.get("service_mapping_info"),
+                                "device_id": pmap.get("device_id"),
+                                "device_interface_id": pmap.get("device_interface_id"),
+                                "switch_dpid": pmap.get("switch_dpid"),
+                                "switch_port": pmap.get("switch_port"),
+                                "service_mapping_info": pmap.get("service_mapping_info"),
                             }
                         })
 
@@ -1189,8 +1191,28 @@ class vim_thread(threading.Thread):
             if pending_ports:
                 error_list.append("Waiting for getting interfaces location from VIM. Obtained '{}' of {}"
                                   .format(len(ports)-pending_ports, len(ports)))
+
+            # connect external ports
+            for index, external_port in enumerate(task["extra"].get("sdn-ports") or ()):
+                external_port_id = external_port.get("service_endpoint_id") or str(index)
+                sdn_ports.append({
+                    "service_endpoint_id": external_port_id,
+                    "service_endpoint_encapsulation_type": external_port.get("service_endpoint_encapsulation_type",
+                                                                             "dot1q"),
+                    "service_endpoint_encapsulation_info": {
+                        "vlan": external_port.get("vlan") or vlan_used,
+                        "mac": external_port.get("mac_address"),
+                        "device_id": external_port.get("device_id"),
+                        "device_interface_id": external_port.get("device_interface_id"),
+                        "switch_dpid": external_port.get("switch_dpid") or external_port.get("switch_id"),
+                        "switch_port": external_port.get("switch_port"),
+                        "service_mapping_info": external_port.get("service_mapping_info"),
+                    }})
+                new_connected_ports.append(external_port_id)
+
             # if there are more ports to connect or they have been modified, call create/update
-            if sdn_need_update and len(sdn_ports) >= 2:
+            if (set(connected_ports) != set(new_connected_ports) or sdn_need_update) and len(sdn_ports) >= 2:
+                last_update = time.time()
                 if not wimconn_net_id:
                     if params[0] == "data":
                         net_type = "ELAN"
@@ -1203,7 +1225,6 @@ class vim_thread(threading.Thread):
                 else:
                     created_items = self.sdnconnector.edit_connectivity_service(wimconn_net_id, conn_info=created_items,
                                                                                 connection_points=sdn_ports)
-                last_update = time.time()
                 connected_ports = new_connected_ports
             elif wimconn_net_id:
                 try: