def __init__(self, host_name='127.0.0.1', port_number=7878, tx_port_list=None, rx_port_list=None): self.__drone = DroneProxy(host_name, port_number) if tx_port_list: self.__tx_port_list = tx_port_list.all_ports else: self.__tx_port_list = None if rx_port_list: self.__rx_port_list = rx_port_list.all_ports else: self.__rx_port_list = None
def __init__(self): self.drone = DroneProxy('127.0.0.1') self.drone.connect() self.port_id_list = self.drone.getPortIdList() self.port_config_list = self.drone.getPortConfig(self.port_id_list) self.tx_port = ost_pb.PortIdList() self.rx_port = ost_pb.PortIdList() self.interfaces = self._getInterfaces() self.addedInterfaces = [] self.tx_stats = None
class Drone(): def __init__(self, host_name='127.0.0.1', port_number=7878, tx_port_list=None, rx_port_list=None): self.__drone = DroneProxy(host_name, port_number) if tx_port_list: self.__tx_port_list = tx_port_list.all_ports else: self.__tx_port_list = None if rx_port_list: self.__rx_port_list = rx_port_list.all_ports else: self.__rx_port_list = None def connect(self): self.__drone.connect() self.tx_port_clear_stats() self.rx_port_clear_stats() return self def disconnect(self): self.__drone.disconnect() return self def add_stream_list(self, stream_list): self.current_stream_list = stream_list self.__drone.addStream(stream_list.all_streams) self.__drone.modifyStream(stream_list.all_streams_configurations) return self def remove_stream_list(self, stream_id_list): self.__drone.deleteStream(stream_id_list) return self def remove_current_stream_list(self): assert(self.current_stream_list) self.__drone.deleteStream(self.current_stream_list.all_streams) return self def fetch_stream_id_list(self): assert(self.__tx_port_list) stream_id_list = self.__drone.getStreamIdList(self.__tx_port_list.port_id[0]) return stream_id_list def fetch_port_id_list(self): port_id_list = self.__drone.getPortIdList() return port_id_list def get_port_config_list(self): port_config_list = self.__drone.getPortConfig(self.fetch_port_id_list()) return port_config_list def start_transmit(self): assert(self.__tx_port_list) self.tx_port_clear_stats() self.__drone.startTransmit(self.__tx_port_list) return self def wait_for_transmission_complete(self, time_out=None): time_start = time.time() while True: time.sleep(1) tx_stats = self.fetch_stats_tx_port() print('transmit rate %s bps' % (tx_stats.tx_bps * 8)) if (not tx_stats.state.is_transmit_on)\ or (time_out and (time.time() - time_start > time_out)): break else: print('waiting for transmit to finish ,elapsed time %s seconds' % (time.time() - time_start)) print('transmit total time %s seconds' % (time.time() - time_start)) return self def stop_transmit(self): assert(self.__tx_port_list) self.__drone.stopTransmit(self.__tx_port_list) return self def __start_capture(self, port_list): assert(port_list) self.__drone.startCapture(port_list) def __stop_capture(self, port_list): assert(port_list) self.__drone.stopCapture(port_list) def __clear_stats(self, port_list): # assert(port) if port_list: self.__drone.clearStats(port_list) def __fetch_stats_port(self, port_list): assert(port_list) stats = self.__drone.getStats(port_list) return stats.port_stats[0] def __fetch_capture_buffer(self, port_list, buffer_file_name='capture.pcap'): assert(port_list) buffer = self.__drone.getCaptureBuffer(port_list.port_id[0]) self.__drone.saveCaptureBuffer(buffer, buffer_file_name) # os.system('tshark -r ' + buffer_file_name) # os.remove(buffer_file_name) def tx_port_start_capture(self): self.__start_capture(self.__tx_port_list) return self def tx_port_stop_capture(self): self.__stop_capture(self.__tx_port_list) return self def tx_port_clear_stats(self): self.__clear_stats(self.__tx_port_list) return self def rx_port_start_capture(self): self.__start_capture(self.__rx_port_list) return self def rx_port_stop_capture(self): self.__stop_capture(self.__rx_port_list) return self def rx_port_clear_stats(self): self.__clear_stats(self.__rx_port_list) return self def fetch_stats_tx_port(self): return self.__fetch_stats_port(self.__tx_port_list) def fetch_capture_buffer_tx_port(self): self.__fetch_capture_buffer(self.__tx_port_list, buffer_file_name='tx_port_capture.pcap') def fetch_stats_rx_port(self): return self.__fetch_stats_port(self.__rx_port_list) def fetch_capture_buffer_rx_port(self): self.__fetch_capture_buffer(self.__rx_port_list, buffer_file_name='rx_port_capture.pcap')
# initialize the below variables host_name = '127.0.0.1' port_number = 8080 tx_port_number = 1 rx_port_number = 7 # setup logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) drone = DroneProxy(host_name, port_number) try: # connect to drone log.info('connecting to drone(%s:%d)' % (drone.hostName(), drone.portNumber())) drone.connect() # setup tx port list tx_port = ost_pb.PortIdList() tx_port.port_id.add().id = tx_port_number; rx_port = ost_pb.PortIdList() rx_port.port_id.add().id = rx_port_number; stream_id = ost_pb.StreamIdList()
class Traffic(object): """Class for traffic streams""" def __init__(self): self.drone = DroneProxy('127.0.0.1') self.drone.connect() self.port_id_list = self.drone.getPortIdList() self.port_config_list = self.drone.getPortConfig(self.port_id_list) self.tx_port = ost_pb.PortIdList() self.rx_port = ost_pb.PortIdList() self.interfaces = self._getInterfaces() self.addedInterfaces = [] self.tx_stats = None def __del__(self): """Cleanup the streams""" for interface in self.interfaces: self.drone.deleteStream(interface['stream_id_list']) self.drone.disconnect() def _getInterfaces(self): """Create a list of interface dicts which can be used for streams""" interfaces = [] for port in self.port_config_list.port: stream_id_list = ost_pb.StreamIdList() stream_id_list.stream_id.add().id = 1 stream_id_list.stream_id.add().id = 2 stream_id_list.stream_id.add().id = 3 stream_id_list.stream_id.add().id = 4 stream_id_list.stream_id.add().id = 5 stream_id_list.port_id.id = port.port_id.id self.drone.addStream(stream_id_list) stream_cfg = ost_pb.StreamConfigList() stream_cfg.port_id.id = port.port_id.id interface = { 'name': port.name, 'port_id': port.port_id, 'port_id_id': port.port_id.id, 'stream_id_list': stream_id_list, 'stream_cfg': stream_cfg, 'stream_id': 1, } interfaces.append(interface) return interfaces def _cleanupRun(self): """Delete all current streams, so that we can create new once for the next run""" for interface in self.interfaces: stream_id_list = interface['stream_id_list'] port_id = interface['port_id_id'] self.drone.deleteStream(stream_id_list) self.drone.addStream(stream_id_list) stream_cfg = ost_pb.StreamConfigList() stream_cfg.port_id.id = port_id interface['stream_cfg'] = stream_cfg interface['stream_id'] = 1 def _getInterfaceByName(self, interface_name): """Return the interface dict for a given interface name""" for interface in self.interfaces: if interface['name'] == interface_name: return interface raise NameError('getInterface called for unknown interface name') def _getInterfaceByPortId(self, port_id): """Return the interface dict for a given interface name""" for interface in self.interfaces: if interface['port_id_id'] == port_id: return interface raise NameError('getInterface called for unknown interface name') def _getInterfaceId(self, interface_name): """Return the Ostinato ID for an interface name""" for interface in self.interfaces: if interface['name'] == interface_name: return interface['port_id_id'] raise NameError('getInterfaceId called for unknown interface {0}'. format(interface_name)) def getInterfaceNames(self): """Return a list of interface names which can be used for streams""" return [interface['name'] for interface in self.interfaces] def addInterface(self, interface_name): """Add an interface to the configuration. It will then be used for transmit and receive""" dbg_print('addInterface({0})'.format(interface_name)) self.addedInterfaces.append(interface_name) port_id = self._getInterfaceId(interface_name) self.rx_port.port_id.add().id = port_id self.tx_port.port_id.add().id = port_id def _getInterfaceMacAddress(self, interface): """Return the MAC address of an interface""" return 0x001020304000 + interface['port_id_id'] def _getInterfaceIPAddress(self, interface): """Return the IP address of an interface""" return 0xc0a83a0a + interface['port_id_id'] def _addEthernetHeader(self, stream, src_mac, dst_mac): """Add an Ethernet header to a stream""" proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kMacFieldNumber proto.Extensions[mac].src_mac = src_mac proto.Extensions[mac].dst_mac = dst_mac def _addEthertypeIP(self, stream): """Add an Ethernet Type header for IP to a stream""" proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber proto.Extensions[eth2].type = 0x0800 proto.Extensions[eth2].is_override_type = True def _addIPHeader(self, stream, src_ip, dst_ip): """Add an IP header to a stream""" proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber proto.Extensions[ip4].src_ip = src_ip proto.Extensions[ip4].dst_ip = dst_ip def _addUdpHeader(self, stream, src_port, dst_port): """Add a UDP header to a stream""" proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kUdpFieldNumber proto.Extensions[udp].is_override_src_port = True proto.Extensions[udp].is_override_dst_port = True proto.Extensions[udp].src_port = src_port proto.Extensions[udp].dst_port = dst_port def _addIGMPHeader(self, stream, igmp_type, group): """Add an IGMP header to a stream""" proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kIgmpFieldNumber proto.Extensions[igmp].type = igmp_type proto.Extensions[igmp].group_address.v4 = group def _addIGMPRequestHeader(self, stream, group): """Add an IGMP Request header to a stream""" self._addIGMPHeader(stream, IGMPv2_REQUEST, group) def _addStream(self, stream_cfg, interface, num_packets, packets_per_sec): """Add a stream to an interface, and return it""" stream = stream_cfg.stream.add() stream.stream_id.id = interface['stream_id'] interface['stream_id'] = interface['stream_id'] + 1 stream.core.is_enabled = True stream.core.frame_len = 128 stream.control.num_packets = num_packets stream.control.packets_per_sec = packets_per_sec return stream def _addUDPPacketStream(self, stream, src_mac, dst_mac, src_ip, dst_ip): """Add a UDP packets to a stream""" self._addEthernetHeader(stream, src_mac=src_mac, dst_mac=dst_mac) self._addEthertypeIP(stream) self._addIPHeader(stream, src_ip=src_ip, dst_ip=dst_ip) self._addUdpHeader(stream, 0x1234, 0x4321) proto = stream.protocol.add() proto.protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber def addUDPStream(self, src_interface_name, dst_interface_name, num_packets, packets_per_sec): """Add a UDP stream from the source interface to the destination interface""" dbg_print('addUDPStream({0} {1} {2} {3})'.format(src_interface_name, dst_interface_name, num_packets, packets_per_sec)) src_interface = self._getInterfaceByName(src_interface_name) dst_interface = self._getInterfaceByName(dst_interface_name) stream_cfg = src_interface['stream_cfg'] stream = self._addStream(stream_cfg, src_interface, num_packets, packets_per_sec) src_mac = self._getInterfaceMacAddress(src_interface) dst_mac = self._getInterfaceMacAddress(dst_interface) src_ip = self._getInterfaceIPAddress(src_interface) dst_ip = self._getInterfaceIPAddress(dst_interface) self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip) self.drone.modifyStream(stream_cfg) def addUDPBroadcastStream(self, src_interface_name, num_packets, packets_per_sec): """Add a UDP broadcast stream from the source interface to the broadcast address""" dbg_print('addUDPBroadcastStream({0} {1} {2})'. format(src_interface_name, num_packets, packets_per_sec)) src_interface = self._getInterfaceByName(src_interface_name) stream_cfg = src_interface['stream_cfg'] stream = self._addStream(stream_cfg, src_interface, num_packets, packets_per_sec) src_mac = self._getInterfaceMacAddress(src_interface) dst_mac = 0xffffffffffff src_ip = self._getInterfaceIPAddress(src_interface) dst_ip = 0xc0a82aff self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip) self.drone.modifyStream(stream_cfg) def addUDPMulticastStream(self, src_interface_name, group_str, num_packets, packets_per_sec): """Add a UDP multicast stream from the source interface to the group address""" dbg_print('addUDPMulticastStream({0} {1} {2} {3})'. format(src_interface_name, group_str, num_packets, packets_per_sec)) src_interface = self._getInterfaceByName(src_interface_name) stream_cfg = src_interface['stream_cfg'] stream = self._addStream(stream_cfg, src_interface, num_packets, packets_per_sec) src_mac = self._getInterfaceMacAddress(src_interface) group = ipaddress.ip_address(group_str.decode()) dst_mac = 0x01005e000000 + (int(group) & 0x07fffff) src_ip = self._getInterfaceIPAddress(src_interface) dst_ip = int(group) self._addUDPPacketStream(stream, src_mac, dst_mac, src_ip, dst_ip) self.drone.modifyStream(stream_cfg) def addIGMPRequestStream(self, src_interface_name, group, num_packets, packets_per_sec): """Add a IGMP request stream from the source interface to the group address""" dbg_print('addIGMPStream({0} {1} {2})'. format(src_interface_name, group, num_packets)) src_interface = self._getInterfaceByName(src_interface_name) stream_cfg = src_interface['stream_cfg'] stream = self._addStream(stream_cfg, src_interface, num_packets, packets_per_sec) src_mac = self._getInterfaceMacAddress(src_interface) dst_mac = 0x01005e00001 src_ip = self._getInterfaceIPAddress(src_interface) dst_ip = group self._addEthernetHeader(stream, src_mac=src_mac, dst_mac=dst_mac) self._addEthertypeIP(stream) self._addIPHeader(stream, src_ip=src_ip, dst_ip=dst_ip) self._addIGMPRequestHeader(stream, group) self.drone.modifyStream(stream_cfg) def learningStream(self, interface_name): """Create a stream on the interface for bridge learning. Two broadcast packets will be sent, so allowing the switch to learn the source MAC address on the interface.""" dbg_print('learningStream({0})'.format(interface_name)) self.addUDPBroadcastStream(interface_name, 2, 1) def learning(self): """Perform learning on each port, by sending a couple of packet, so that the bridge learns the address on the interface""" dbg_print('learning') for interface_name in self.addedInterfaces: self.learningStream(interface_name) frame = inspect.stack()[1][0] method = inspect.stack()[1][3] test = get_class_from_frame(frame).__name__ self._run(test, method) def _saveCapture(self, testname, methodname, interface_name): """Save the capture file for one interface""" filename = "{0}-{1}-{2}.pcap".format(testname, methodname, interface_name) interface = self._getInterfaceByName(interface_name) buff = self.drone.getCaptureBuffer(interface['port_id']) self.drone.saveCaptureBuffer(buff, filename) def _saveCaptures(self, testname, methodname): """Save the capture files, using the test name as a prefix""" for interface_name in self.addedInterfaces: self._saveCapture(testname, methodname, interface_name) def _run(self, test, method): """Do the real work""" self.drone.clearStats(self.tx_port) self.drone.clearStats(self.rx_port) self.drone.startCapture(self.rx_port) self.drone.startTransmit(self.tx_port) done = False while not done: done = True tx_stats = self.drone.getStats(self.tx_port) for port_stats in tx_stats.port_stats: if port_stats.state.is_transmit_on: done = False time.sleep(1) self.drone.stopTransmit(self.tx_port) self.drone.stopCapture(self.rx_port) self.tx_stats = self.drone.getStats(self.tx_port) self._saveCaptures(test, method) self._cleanupRun() def run(self): """Run the streams""" dbg_print('run') frame = inspect.stack()[1][0] method = inspect.stack()[1][3] test = get_class_from_frame(frame).__name__ self._run(test, method) def getStats(self, interface_name): """Return the interface statistics""" dbg_print('getStats({0})'.format(interface_name)) port_id = self._getInterfaceId(interface_name) for port_stats in self.tx_stats.port_stats: if port_stats.port_id.id == port_id: stats = { 'rx_pkts': port_stats.rx_pkts, 'rx_pps': port_stats.rx_pps, 'rx_bps': port_stats.rx_bps, 'tx_pkts': port_stats.tx_pkts, 'tx_pps': port_stats.tx_pps, 'tx_bps': port_stats.tx_bps, 'rx_drops': port_stats.rx_drops, 'rx_errors': port_stats.rx_errors, 'rx_fifo_errors': port_stats.rx_fifo_errors, 'rx_frame_errors': port_stats.rx_frame_errors, } return stats
def main(): # initialize defaults use_defaults = False host_name = '127.0.0.1' # default drone host name tx_port_number = 0 src_mac = 0x000c292eba20 # pkt src mac, modify it dst_mac = 0x18b169091010 # pkt dst mac, modify it src_ip = ipstr2long('192.168.168.2') # pkt scr ip, modify it dst_ip = ipstr2long('192.168.166.2') # pkt dst ip, modify it # compute total num of streams total_streams = sum([x[1] for x in ICMP_TYPE_CODE]) print 'Total number of streams: %d' %total_streams # setup logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) # command-line option/arg processing if len(sys.argv) > 1: if sys.argv[1] in ('-d', '--use-defaults'): use_defaults = True if sys.argv[1] in ('-h', '--help'): print('%s [OPTION]...' % (sys.argv[0])) print('Options:') print(' -d --use-defaults run using default values') print(' -h --help show this help') sys.exit(0) if not use_defaults: s = raw_input('Drone\'s Hostname/IP [%s]: ' % (host_name)) host_name = s or host_name drone = DroneProxy(host_name) drone.TransmitMode = 'sequential' try: # connect to drone log.info('connecting to drone(%s:%d)' % (drone.hostName(), drone.portNumber())) drone.connect() # retreive port id list log.info('retreiving port list') port_id_list = drone.getPortIdList() # retreive port config list log.info('retreiving port config for all ports') port_config_list = drone.getPortConfig(port_id_list) if len(port_config_list.port) == 0: log.warning('drone has no ports!') sys.exit(1) print('Port List') print('---------') print (port_config_list) for port in port_config_list.port: print('%d.%s (%s)' % (port.port_id.id, port.name, port.description)) # use a loopback port as default tx/rx port if ('lo' in port.name or 'loopback' in port.description.lower()): tx_port_number = port.port_id.id if not use_defaults: p = raw_input('Tx Port Id [%d]: ' % (tx_port_number)) if p: tx_port_number = int(p) tx_port = ost_pb.PortIdList() tx_port.port_id.add().id = tx_port_number; sid = 1 for icmp_stream in ICMP_TYPE_CODE: stype = icmp_stream[0] for scode in range(icmp_stream[1]): # add a stream print 'icmp (type, code) = (%d, %d)' %(stype, scode) stream_id = ost_pb.StreamIdList() stream_id.port_id.CopyFrom(tx_port.port_id[0]) stream_id.stream_id.add().id = sid log.info('adding tx_stream %d' % stream_id.stream_id[0].id) drone.addStream(stream_id) # configure the stream stream_cfg = ost_pb.StreamConfigList() stream_cfg.port_id.CopyFrom(tx_port.port_id[0]) s = stream_cfg.stream.add() s.stream_id.id = stream_id.stream_id[0].id s.core.is_enabled = True s.control.num_packets = 1 # setup stream protocols as mac:eth2:ip4:icmp # setup mac header p = s.protocol.add() p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber p.Extensions[mac].dst_mac = dst_mac p.Extensions[mac].src_mac = src_mac p = s.protocol.add() p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber #setup ip header p = s.protocol.add() p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber ip = p.Extensions[ip4] ip.src_ip = src_ip ip.dst_ip = dst_ip ip.dst_ip_mode = Ip4.e_im_fixed # setup icmp header p = s.protocol.add() p.protocol_id.id = ost_pb.Protocol.kIcmpFieldNumber icmp_va = p.Extensions[icmp] icmp_va.icmp_version = Icmp.kIcmp4 # icmp version icmp_va.type = stype # icmp type icmp_va.code = scode # icmp code s.protocol.add().protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber s.control.unit = ost_pb.StreamControl.e_su_packets # Send: Packets s.control.mode = ost_pb.StreamControl.e_sm_fixed # Mode: Fixed if sid < total_streams: s.control.next = ost_pb.StreamControl.e_nw_goto_next else: s.control.next = ost_pb.StreamControl.e_nw_goto_id # e_nw_stop s.core.ordinal = sid - 1 # keep stream transmitted in order sid += 1 s.control.packets_per_sec = 20 # transmit rate: pkts per second log.info('configuring tx_stream %d' % stream_id.stream_id[0].id) drone.modifyStream(stream_cfg) log.info('clearing tx stats') drone.clearStats(tx_port) # start transmit log.info('starting transmit') drone.startTransmit(tx_port) # wait for transmit to finish log.info('waiting for transmit to finish ...') while True: try: time.sleep(5) tx_stats = drone.getStats(tx_port) if tx_stats.port_stats[0].state.is_transmit_on == False: break except KeyboardInterrupt: log.info('Transmit terminated by user!!!') break # stop transmit and capture log.info('stopping transmit') drone.stopTransmit(tx_port) # get tx/rx stats log.info('retreiving stats') tx_stats = drone.getStats(tx_port) log.info('tx pkts = %d' % (tx_stats.port_stats[0].tx_pkts)) # retrieve and dump received packets #log.info('getting Rx capture buffer') #drone.saveCaptureBuffer(buff, 'capture.pcap') #log.info('dumping Rx capture buffer') #os.system('tshark -r capture.pcap') #os.remove('capture.pcap') # delete streams log.info('deleting tx_stream %d' % stream_id.stream_id[0].id) drone.deleteStream(stream_id) # desconnect drone drone.disconnect() except Exception as ex: log.exception(ex) sys.exit(1)
def __init__(self, host, connect=True): self._drone = DroneProxy(host) if connect is True: self.connect() self.ports = []
class Drone(object): """Wrapper for ``ostinato.core.DroneProxy``. All the protocol buffer related methods are prefixed with ``_o_`` and are for internal use only. Args: host (str): ip address or hostname of the host running the drone instance you want to connect to. connect (bool): if True, attempt to connect to the remote instance when the object is initialized. Otherwise, it can be done manually later with :meth:`connect()` """ def __init__(self, host, connect=True): self._drone = DroneProxy(host) if connect is True: self.connect() self.ports = [] def connect(self): """ Connect to the remote drone instance. By default, it is already called when the object is created. """ self._drone.connect() def disconnect(self): """ Disconnect from the remote drone instance. """ self._drone.disconnect() def reconnect(self): """ Reconnect to the remote drone instance. """ self._drone.disconnect() self._drone.connect() def fetch_ports(self): """ Get the list of all the ports on the remote host. They are stored in the :attr:`ports` dictionnary. """ o_ports = self._drone.getPortConfig(self._drone.getPortIdList()) for o_port in o_ports.port: port_id = o_port.port_id.id port = self.get_port_by_id(port_id) if port is None: self.ports.append(Port(self, port_id)) else: port.fetch() def get_port_by_id(self, port_id): for port in self.ports: if port.port_id == port_id: return port def get_port(self, name): """ Get ports from :attr:`ports` by name. If the port is not found, ``None`` is returned. """ for port in self.ports: if port.name == name: return port def __str__(self): return 'drone({})'.format(self._drone.host)
print(' | Drone | | DUT |') print(' | |Rx---<----| |') print(' +-------+ +-------+') print('') print('Drone has 2 ports connected to DUT. Packets sent on the Tx port') print('are expected to be received back on the Rx port') print('') print('An easy way to simulate the above topology is to select the loopback') print('port as both Tx and Rx ports') print('') if not use_defaults: s = raw_input('Drone\'s Hostname/IP [%s]: ' % (host_name)) host_name = s or host_name drone = DroneProxy(host_name) try: # connect to drone log.info('connecting to drone(%s:%d)' % (drone.hostName(), drone.portNumber())) drone.connect() # retreive port id list log.info('retreiving port list') port_id_list = drone.getPortIdList() # retreive port config list log.info('retreiving port config for all ports') port_config_list = drone.getPortConfig(port_id_list)