+ def new_or_update_sdn_net(self, task):
+ wimconn_net_id = task["vim_id"]
+ created_items = task["extra"].get("created_items")
+ connected_ports = task["extra"].get("connected_ports", [])
+ new_connected_ports = []
+ last_update = task["extra"].get("last_update", 0)
+ sdn_status = "BUILD"
+ sdn_info = None
+
+ task_id = task["instance_action_id"] + "." + str(task["task_index"])
+ error_list = []
+ try:
+ # FIND
+ if task["extra"].get("find"):
+ wimconn_id = task["extra"]["find"][0]
+ try:
+ instance_element_update = self.sdnconnector.get_connectivity_service_status(wimconn_id)
+ wimconn_net_id = wimconn_id
+ instance_element_update = {"wim_internal_id": wimconn_net_id, "created": False, "status": "BUILD",
+ "error_msg": None, }
+ return instance_element_update
+ except Exception as e:
+ if isinstance(e, SdnConnectorError) and e.http_error == HTTPStatus.NOT_FOUND.value:
+ pass
+ else:
+ self._proccess_sdn_exception(e)
+
+ params = task["params"]
+ # CREATE
+ # 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
+ 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 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"):
+ pmap = {
+ "service_endpoint_id": "{}:{}".format(port["compute_node"], port["pci"]),
+ "service_endpoint_encapsulation_info": {
+ "vlan": port["vlan"],
+ "mac": port["mac_address"],
+ "device_id": port["compute_node"],
+ "device_interface_id": port["pci"]
+ }
+ }
+ else:
+ pmap = None
+ error_list.append("Port mapping not found for compute_node={} pci={}".format(
+ port["compute_node"], port["pci"]))
+
+ if pmap:
+ if port["modified_at"] > last_update:
+ sdn_need_update = True
+ new_connected_ports.append(port["uuid"])
+ sdn_ports.append({
+ "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": 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"),
+ }
+ })
+
+ else:
+ pending_ports += 1
+ 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
+ try:
+ 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"
+ elif params[0] == "ptp":
+ net_type = "ELINE"
+ else:
+ net_type = "L3"
+
+ wimconn_net_id, created_items = self.sdnconnector.create_connectivity_service(
+ net_type, sdn_ports)
+ else:
+ created_items = self.sdnconnector.edit_connectivity_service(
+ wimconn_net_id, conn_info=created_items, connection_points=sdn_ports)
+ connected_ports = new_connected_ports
+ elif wimconn_net_id:
+ wim_status_dict = self.sdnconnector.get_connectivity_service_status(wimconn_net_id,
+ conn_info=created_items)
+ sdn_status = wim_status_dict["sdn_status"]
+ if wim_status_dict.get("error_msg"):
+ error_list.append(wim_status_dict.get("error_msg"))
+ if wim_status_dict.get("sdn_info"):
+ sdn_info = str(wim_status_dict.get("sdn_info"))
+ except Exception as e:
+ self._proccess_sdn_exception(e)
+
+ task["status"] = "DONE"
+ task["extra"]["vim_info"] = {}
+ # task["extra"]["sdn_net_id"] = sdn_net_id
+ task["extra"]["vim_status"] = sdn_status
+ task["extra"]["created"] = True
+ task["extra"]["created_items"] = created_items
+ task["extra"]["connected_ports"] = connected_ports
+ task["extra"]["last_update"] = last_update
+ task["error_msg"] = self._format_vim_error_msg(" ; ".join(error_list))
+ task["vim_id"] = wimconn_net_id
+ instance_element_update = {"wim_internal_id": wimconn_net_id, "status": sdn_status,
+ "created": True, "error_msg": task["error_msg"] or None}
+ except (vimconn.vimconnException, SdnConnectorError) as e:
+ self.logger.error("task={} new-sdn-net: Error: {}".format(task_id, e))
+ task["status"] = "FAILED"
+ task["vim_id"] = wimconn_net_id
+ task["error_msg"] = self._format_vim_error_msg(str(e))
+ # task["extra"]["sdn_net_id"] = sdn_net_id
+ instance_element_update = {"wim_internal_id": wimconn_net_id, "status": "WIM_ERROR",
+ "error_msg": task["error_msg"]}
+
+ if sdn_info:
+ instance_element_update["wim_info"] = sdn_info
+ return instance_element_update
+
+ def del_sdn_net(self, task):
+ wimconn_net_id = task["vim_id"]
+ try:
+ try:
+ if wimconn_net_id:
+ self.sdnconnector.delete_connectivity_service(wimconn_net_id, task["extra"].get("created_items"))
+ task["status"] = "FINISHED" # with FINISHED instead of DONE it will not be refreshing
+ task["error_msg"] = None
+ return None
+ except Exception as e:
+ self._proccess_sdn_exception(e)
+ except SdnConnectorError as e:
+ task["error_msg"] = self._format_vim_error_msg(str(e))
+ if e.http_code == HTTPStatus.NOT_FOUND.value:
+ # If not found mark as Done and fill error_msg
+ task["status"] = "FINISHED" # with FINISHED instead of DONE it will not be refreshing
+ task["error_msg"] = None
+ return None
+ task["status"] = "FAILED"
+ return None
+