+ def new_external_port(self, port_data):
+ """
+ Create new external port and check port mapping correspondence
+ :param port_data: port_data = {
+ 'region': 'datacenter region',
+ 'compute_node': 'compute node id',
+ 'pci': 'pci port address',
+ 'vlan': 'net vlan',
+ 'net_id': 'net id',
+ 'tenant_id': 'tenant id',
+ 'mac': 'switch mac',
+ 'name': 'port name'
+ 'ip_address': 'ip address - optional'}
+ :return:
+ """
+
+ port_data['type'] = 'external'
+
+ if port_data.get('net_id'):
+ # check that new net has the correct type
+ result, new_net = self.db.check_target_net(port_data['net_id'], None, 'external')
+ if result < 0:
+ raise ovimException(str(new_net), -result)
+ # insert in data base
+ db_filter = {}
+
+ if port_data.get('region'):
+ db_filter['region'] = port_data['region']
+ if port_data.get('pci'):
+ db_filter['pci'] = port_data['pci']
+ if port_data.get('compute_node'):
+ db_filter['compute_node'] = port_data['compute_node']
+
+ columns = ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
+ port_mapping_data = self.get_of_port_mappings(columns, db_filter)
+
+ if not len(port_mapping_data):
+ raise ovimException("No port mapping founded for '{}'".format(str(db_filter)),
+ HTTP_Not_Found)
+ elif len(port_mapping_data) > 1:
+ raise ovimException("Wrong port data was given, please check pci, region & compute id data",
+ HTTP_Conflict)
+
+ port_data['ofc_id'] = port_mapping_data[0]['ofc_id']
+ port_data['switch_dpid'] = port_mapping_data[0]['switch_dpid']
+ port_data['switch_port'] = port_mapping_data[0]['switch_port']
+ port_data['switch_mac'] = port_mapping_data[0]['switch_mac']
+
+ # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
+ if 'region' in port_data:
+ del port_data['region']
+ if 'pci' in port_data:
+ del port_data['pci']
+ if 'compute_node' in port_data:
+ del port_data['compute_node']
+
+ result, uuid = self.db.new_row('ports', port_data, True, True)
+ if result > 0:
+ try:
+ self.net_update_ofc_thread(port_data['net_id'], port_data['ofc_id'])
+ except ovimException as e:
+ raise ovimException("Cannot insert a task for updating network '{}' {}".
+ format(port_data['net_id'], str(e)), HTTP_Internal_Server_Error)
+ except Exception as e:
+ raise ovimException("Cannot insert a task for updating network '{}' {}"
+ .format(port_data['net_id'], e), HTTP_Internal_Server_Error)
+ return uuid
+ else:
+ raise ovimException(str(uuid), -result)
+
+ def net_update_ofc_thread(self, net_id, ofc_id=None, switch_dpid=None):
+ """
+ Insert a update net task by net id or ofc_id for each ofc thread
+ :param net_id: network id
+ :param ofc_id: openflow controller id
+ :param switch_dpid: switch dpid
+ :return:
+ """
+ if not net_id:
+ raise ovimException("No net_id received", HTTP_Internal_Server_Error)
+
+ r = -1
+ c = 'No valid ofc_id or switch_dpid received'
+
+ if not ofc_id:
+ ports = self.get_ports(filter={"net_id": net_id})
+ for port in ports:
+ port_ofc_id = port.get('ofc_id', None)
+ if port_ofc_id:
+ ofc_id = port['ofc_id']
+ switch_dpid = port['switch_dpid']
+ break
+ #TODO if not ofc_id: look at database table ofcs
+
+
+ # If no ofc_id found it, default ofc_id is used.
+ if not ofc_id and not switch_dpid:
+ ofc_id = "Default"
+
+ if ofc_id and ofc_id in self.config['ofcs_thread']:
+ r, c = self.config['ofcs_thread'][ofc_id].insert_task("update-net", net_id)
+ elif switch_dpid:
+
+ ofcs_dpid_list = self.config['ofcs_thread_dpid']
+ for ofc_t in ofcs_dpid_list:
+ if switch_dpid in ofc_t:
+ r, c = ofc_t[switch_dpid].insert_task("update-net", net_id)
+
+ if r < 0:
+ message = "Cannot insert a task for updating network '{}', {}".format(net_id, c)
+ self.logger.error(message)
+ raise ovimException(message, HTTP_Internal_Server_Error)
+