def get_double_parked_portgroup(self, hostname, inline_prefix='va'): """ method that gives name of double parked portgroup. Args: :hostname(str): name of host on user wants to check doubleparking. Returns: :portgroup(list): name of double parked portgroup. """ host_obj = self._get_host_object_by_name(hostname) netObjs = host_obj.network double_parked_portgroup = [] for network in netObjs: if (inline_prefix+"-" in network.name) \ and ("overflow" not in network.name) \ and ("quarantine" not in network.name)\ and ('epi' not in network.name): if len(network.vm) >= 2: connected_host = [] for vms in network.vm: if vms.summary.runtime.host.name \ not in connected_host: connected_host.append( vms.summary.runtime.host.name) else: logger.debug("Double Parking found in host"\ "{} and portgroup {}".format( hostname, network.name)) double_parked_portgroup.append(network.name) return double_parked_portgroup
def is_double_parking_in_host(self, hostname, inline_prefix='va'): """ method that check double parking issue in a given host. Args: :hostname(str): name of host on user wants to check doubleparking. Returns: :True(boolean): if double parking found on host :False(boolean): if double parking not found on host """ host_obj = self._get_host_object_by_name(hostname) netObjs = host_obj.network for network in netObjs: if (inline_prefix+"-" in network.name) and \ ("overflow" not in network.name) \ and ("quarantine" not in network.name)\ and ('epi' not in network.name): if len(network.vm) >= 2: connected_host = [] for vms in network.vm: if vms.summary.runtime.host.name \ not in connected_host: connected_host.append( vms.summary.runtime.host.name) else: logger.debug("Double Parking found in host\ {} and portgroup {}".format( hostname, network.name)) return True return False
def get_sw_name(self): """ Get all switch's information Kwargs: none Returns: a list of vswitch name """ #self.log_command(self.list_vswitch_cmd) results = self._shell.exec_command(self.list_vswitch_cmd) result = results[0] logger.debug(result) buffer = re.sub("\r\n", "\n", result) linelist = re.split("\n", buffer) i = 0 switch_name = [] for line in linelist: pattern = re.compile( r'Switch Name\s+Num Ports\s+Used Ports\s+Configured Ports\s+MTU\s+Uplinks' ) info = pattern.search(line) i = i + 1 if info: nextline = linelist[i] swinfo = re.match(r'(\w+)\s+', nextline) if swinfo is not None: name = swinfo.group(1) switch_name.append(name) if len(switch_name) == 0: logger.error("Failed to get vswitch name") return False logger.info("Succeed to get vswitch name") return (switch_name)
def send_multicast(self, *args, **kwargs): """ method to send multicast traffic on client param : kwargs : dict mulcast_ip : multicast ip address, '224.0.0.4' by default interface : route device, 'eth1' by default interval : seconds between periodic bandwidth reports, 1 by default return: pid and process_file on success, False and error message on failure example : send_multicast() : send_multicast(mulcast_ip='224.0.0.4', interface='eth1') """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) mulcast_ip = kwargs.get('mulcast_ip', '224.0.0.4') interface = kwargs.get('interface', 'eth1') interval = kwargs.get('interval', 1) cmd_route = "route add -net {} netmask 255.255.255.255 dev {}".format(mulcast_ip, \ interface) output = self._access.shell(cmd_route) if re.search(r'Unknown host|No such device', output[0]) is not None: logger.error("Failed to add route") return (False, output[0]) cmd_iperf = "iperf -c {} -u -T 32 -t 3 -i {}".format( mulcast_ip, interval) pid, process_file = self.exec_background(cmd_iperf, 'iperf_client', True, search_expr='iperf') logger.info("PID: {}".format(pid)) if not pid: logger.error("Failed multicast!") self.remove_file(process_file) return (False, "Failed to call exec_background on client") cmd_cat = "cat {}".format(process_file) output = self._access.shell(cmd_cat) logger.debug('Multicast info: {}'.format(output[0])) local_ip = self.get_ip(interface).split('/')[0] reg_list = [ 'Client connecting to\s+{}'.format(mulcast_ip), 'Sending\s+(\d+)\s+byte datagrams', 'local\s+{}\s+port\s+(\d+)\s+connected\s+with\s+{}\s+port\s+(\d+)'. format(local_ip, mulcast_ip) ] for reg in reg_list: if re.search(reg, output[0]) is None: logger.error('Failed to sent multicast on client, \ expected expression: {}'.format(reg)) return (False, output[0]) logger.info("Successfully sent multicast on client") return (pid, process_file)
def log_command(self, command=None): """ Log the command and the device which executes the command Kwargs: :command (str): cli command executed """ role = self.get_name() logger.debug("[{}]: {}".format(role, command))
def receive_multicast(self, *args, **kwargs): """ method to recieve multicast traffic on server param : kwargs : dict mulcast_ip : multicast ip address, '224.0.0.4' by default interface : route device, 'eth1' by default interval : seconds between periodic bandwidth reports, 1 by default return: pid and process_file on success, False and error message on failure example : start_multicast() : start_multicast(mulcast_ip='224.0.0.4', interface='eth1') """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) mulcast_ip = kwargs.get('mulcast_ip', '224.0.0.4') interface = kwargs.get('interface', 'eth1') interval = kwargs.get('interval', 1) cmd_route = "route add -net {} netmask 255.255.255.255 dev {}".format(mulcast_ip, \ interface) output = self._access.shell(cmd_route) if re.search(r'Unknown host|No such device', output[0]) is not None: logger.error("Failed to add route") return (False, output[0]) cmd_iperf = "iperf -s -u -B {} -i {}".format(mulcast_ip, interval) pid, process_file = self.exec_background(cmd_iperf, 'iperf_server', True, search_expr='iperf') logger.info("PID: {}".format(pid)) if not pid: logger.error("Failed multicast!") self.remove_file(process_file) return (False, "Failed to call exec_background on server") cmd_cat = "cat {}".format(process_file) output = self._access.shell(cmd_cat) logger.debug('Multicast info: {}'.format(output[0])) reg_list = [ 'Server listening', 'Binding to local address\s+{}'.format(mulcast_ip), 'Joining multicast group\s+{}'.format(mulcast_ip), 'Receiving\s+(\d+)\s+byte\s+datagrams', 'local\s+%s\s+port\s+(\d+)\s+connected\s+with\s+((\d+\.){3}\d+)\s+port\s+(\d+)' % (mulcast_ip) ] for reg in reg_list: if re.search(reg, output[0]) is None: logger.error('Failed to received multicast on server, \ expected expression: {}'.format(reg)) return (False, output[0]) logger.info("Successfully received multicast on server") return (pid, process_file)
def service_running(self, service=None): """ check if the service is running on the remote machine. kwargs: :service (str): name of the service daemon on the host """ executable_service = service if service == 'tftpd-hpa': service = 'tftpd' executable_service = 'in.{}'.format(service) elif service == 'bind9': service = 'named' executable_service = '{}'.format(service) executables = [ '/usr/bin/{}'.format(executable_service), '/usr/sbin/{}'.format(executable_service) ] out_list = list() ps_cmd = "ps ax | grep {} |grep -v grep".format(service) if service == 'nfs-kernel-server': executable_service = 'Started NFS server and services' ps_cmd = '/etc/init.d/{} status'.format(service) ps_output = self._access.exec_command(ps_cmd) logger.debug('Service info: {}'.format(ps_output)) if not ps_output: logger.error('Service "{}" is not running!'.format(service)) return False if service == 'nfs-kernel-server': if re.search(r'%s' % executable_service, ps_output.splitlines()[-1]) is not None: logger.info('Service is running: \n{}'.format(ps_output)) return True else: logger.error('Service "{}" is not running!'.format(service)) return False else: for line in ps_output.splitlines(): line = line.rstrip() cmd_pos = line.find(ps_cmd) if cmd_pos >= 0: ps_out = line[0:cmd_pos].split() ps_out.append(line[cmd_pos:]) else: ps_out = line.split() out_list.append(tuple(ps_out)) for output in out_list: for service in executables: if service in output: logger.info( 'Service is running: \n{}'.format(ps_output)) return True
def start(self, *args, **kwargs): """ method used to start the Ssh traffic process in the background on the client. It does a clean up of file if existing locally. It launches the lssh client tool in the background, and gets the corresponding pid. If it cannot retrieve the pid it means the transfer is already complete or the process launch failed. kwargs: :timeout (int): ssh timeout :rcmd (str): cmds to execute on server :dest_ip (str): destination ip address, such as ip, hostname """ self._type = 'ssh' self._cmd = 'sshpass' self._timeout = 300 self._userid = self._user.get('name') self._passwd = self._user.get('password') self._rcmd = ['uname', 'pwd'] if 'timeout' in kwargs: self._timeout = kwargs.get('timeout') if 'rcmd' in kwargs: self._rcmd.append(kwargs.get('rcmd')) if 'dest_ip' in kwargs: self._dest_ip = kwargs.get('dest_ip') try: self._build_ssh_cmd() except ValueError as e: raise e client = self._conf_client pid, outfile = client.exec_background( self._cmd, redirect=True, search_expr=self._cmd.split(' ')[0]) logger.info('Ssh pid: {}'.format(pid)) logger.info('Outfile: {}'.format(outfile)) self._outfile = outfile if not pid or outfile is None: raise ValueError('Ssh traffic not started') times = 1 sleeptime = 0.2 self._stats = self.get_stats() while (self._stats == 'failed' or self._stats is None) and times <= 5: logger.debug( 'Sleeping {} seconds to start traffic'.format(sleeptime)) time.sleep(sleeptime) self._stats = self.get_stats() times += 1 if self._stats == 'failed' or self._stats is None: raise ValueError('Ssh traffic not started') logger.info('Ssh traffic started')
def _setup_server_infra(self): """ setup infra on the server for telnet service to enable a file download. """ self._service = 'xinetd' conf_file = "/etc/xinetd.d/telnet" server = self._conf_server shell = server.exec_command conf_info = \ '''service telnet { flags = REUSE socket_type = stream wait = no user = root server = /usr/sbin/in.telnetd log_on_failure += USERID disable = no }''' cmd_create = 'sudo echo \"' + conf_info + '\" > {}'.format(conf_file) logger.info('check if the telnet service is already running') cmd_cat = 'cat {}'.format(conf_file) output = shell(cmd_cat) logger.debug('server output : {}'.format(output)) if 'service telnet' in str(output): logger.info('telnet file already exists') else: output = server.exec_command(telnet_file_create_cmd) logger.debug('telnet server details ', cmd_create) cmd_chmod = ' sudo chmod -R 777 /etc/xinetd.d/telnet; \ sudo chown -R 777 /etc/xinetd.d/telnet' output = shell(cmd_chmod) times = 0 sleeptime = 0.5 service_status = server.service_running(self._service) while not service_status and times <= 3: try: server.service_start(self._service) except ValueError as e: service_status = False else: service_status = True break time.sleep(sleeptime) times += 1 if not service_status: raise ValueError(e) logger.info('Service {} is running'.format(self._service))
def revert_links(self): """ revert link according to inventory file Kwargs: None Return: True : Succeed to revert link according to inventory file. False : Failed to revert link according to inventory file. Examples: vatpobj = VaTopo(test_param_file, topo_file) vatpobj.revert_links() """ inventory_tb_data = load_yaml(self.testdata.inventory_file) swobjs = {} for dev_key in inventory_tb_data.keys(): for dev in inventory_tb_data[dev_key]: if not 'interfaces' in dev or len(dev['interfaces']) == 0: continue else: vswitches = dev['hvisor']['vswitches'] vswitches_l = vswitches.split(' ') for int in dev['interfaces']: logger.debug( 'Check switch {} if it is in hv {}'.format( int['vswitch'], dev['hvisor']['mgmt_ip'])) tag = 0 for vswname in vswitches_l: if vswname == int['vswitch']: logger.debug('check vswitch on hv.done') tag = 1 break if tag == 0: logger.error('vswitch {} is not in hv {}' . format (int['vswitch'], \ dev['hvisor']['mgmt_ip'])) return False #update vlan for each interface logger.info('Clean access vlan {} for {}:{}'\ .format(int['vlan'],dev['uniq_id'],int['phy_name'])) hv_uqid = dev['hvisor']['uniq_id'] vswobj = self.swobjs[hv_uqid][int['vswitch']] if not vswobj.update_vlan(int['port_group'], int['vlan']): return False logger.info("Completed to revert links") return True
def va_unset_interfaces(self): """ unset ip address for test interfaces according to topo file. both support vArmour device and linux pc. Kwargs: None Return: True : Succeed to unset ip address for pc or vArmour devices according to topo file. False : Failed to unset ip address for pc or vArmour devices according to topo file. Examples: vatpobj = VaTopo(test_param_file, topo_file) vatpobj.va_unset_interfaces() """ logger.info("Start to free address for device's interfaces") ints_info = self.ints_info for key in ints_info.keys(): devobj = self.testdata.va_get_by_uniq_id(key) node_type = self.testdata.va_get_by_uniq_id( key, False).get_nodetype() #linux or dir for int_info in ints_info[key]: if ((not 'auto_set' in int_info) or (int_info['auto_set'] != 1)): continue else: #if auto_set =1 , it means to config ip address for defined interface if node_type == 'linux': logger.info('Free address on {}:{}'.format( key, int_info['phy_name'])) result = devobj.unconfig_ip(int_info['ip'], int_info['phy_name']) if not result: logger.debug( devobj.show_interface(int_info['phy_name'])) return False elif node_type == 'dir': logger.info('Free address on {}:{}'.format( key, int_info['phy_name'])) result = devobj.va_unset_ipv4(int_info['ip'], int_info['phy_name'], True) if not result: return False else: #not support to config inteface for other device now continue logger.info("Completed to unset interface") return True
def service_stop(self, service=None): """ stop the service on the remote machine. kwargs: :service (str): name of the service daemon on the host """ cmd = "sudo service {} stop".format(service) out = self._access.exec_command(cmd) # NOQA logger.debug('Service info: {}'.format(out)) if self.service_running(service): raise ValueError("{} not stopped!".format(service)) logger.info("successfully stopped")
def va_get_reserved_vlan(self): """ get reserved vlan Kwargs: None Return: List : all reserved vlan Examples: vatpobj = VaTopo(test_param_file, topo_file) vatpobj.va_get_reserved_vlan() """ logger.debug("Start to get reserved vlan") return (self.testdata.va_get_network_config().get('vlan_range'))
def _verify_ip(self, interface=None, config=None): """ Helper method to compare ip address that is being configured and its actual set value. """ output = self.show_interface(interface) logger.debug('Interface info: {}'.format(output)) ip_addr = output[1][1].split(':')[1] if config and str(config.ip) == ip_addr: logger.info("ifconfig ip works") return True else: logger.info("ip address not configured") return False
def set_vlan(self, pg_name, vlan_id): """ Update portgroup to the value Kwargs: :pg_name (str): valid portgroup name of the vSwitch :vlan_id (str): valid vlan id of the vSwitch Returns: 0: failed 1: succeed """ switch_name = self._name #self.log_command(self.list_vswitch_cmd) results = self._shell.exec_command(self.list_vswitch_cmd) result = results[0] logger.debug(result) buffer = re.sub("\r\n", "\n", result) linelist = re.split("\n", buffer) for line in linelist: learned_mac = re.findall('\s+'+str(pg_name) +\ '\s+[\d]+\s+[\d]+\s+[^\s]'+'|\s+'+str(pg_name)+\ '\s+[\d]+\s+[\d]+',line) if (len(learned_mac) > 0): int_info = learned_mac[0].split(" ") for val in int_info: if val != "": int_name = val break cmd = "esxcfg-vswitch -p {} -v {} {}".format(pg_name, \ vlan_id, switch_name) self.log_command(cmd) self._shell.exec_command(cmd) if self.check_vlan(pg_name=pg_name, vlan_id=vlan_id): logger.info( "Succeed to set portgroup () to vlan {}".format( pg_name, vlan_id)) return True logger.error("Failed to set portgroup () to vlan {}".format( pg_name, vlan_id)) return False
def service_running(self, service=None): """ check if the service is running on the remote machine. kwargs: :service (str): name of the service daemon on the host """ executable_service = service if service == 'tftpd-hpa': service = 'tftpd' executable_service = 'in.{}'.format(service) executables = [ '/usr/bin/{}'.format(executable_service), '/usr/sbin/{}'.format(executable_service) ] out_list = list() ps_cmd = "ps ax | grep {} |grep -v grep".format(service) ps_output = self._access.exec_command(ps_cmd) logger.debug('Service info: {}'.format(ps_output)) if not ps_output: logger.error('Service "{}" is not running!'.format(service)) return False for line in ps_output.splitlines(): line = line.rstrip() cmd_pos = line.find(ps_cmd) if cmd_pos >= 0: ps_out = line[0:cmd_pos].split() ps_out.append(line[cmd_pos:]) else: ps_out = line.split() out_list.append(tuple(ps_out)) for output in out_list: for service in executables: if service in output: logger.info('Service is running: \n{}'.format(ps_output)) return True
def clean_vlan(self, pg_name, vlan=0): """ Update porgroup to default value. for example. if the portgroup name is vlan-20. it will update hte portgroup to vlan 20 Kwargs: :pg_name (str): valid portgroup name of the vSwitch :vlan_id (str): valid vlan id of the vSwitch Returns: 0: failed 1: succeed """ switch_name = self._name #self.log_command(self.list_vswitch_cmd) results = self._shell.exec_command(self.list_vswitch_cmd) result = results[0] logger.debug(result) buffer = re.sub("\r\n", "\n", result) linelist = re.split("\n", buffer) for line in linelist: learned_mac = re.findall('\s+'+str(pg_name) +\ '\s+[\d]+\s+[\d]+\s+[^\s]'+'|\s+'+str(pg_name)+\ '\s+[\d]+\s+[\d]+', line) if (len(learned_mac) > 0): int_info = learned_mac[0].split(" ") for val in int_info: if val != "": int_name = val vlanid = int_name.split("-") vlan = vlanid[1] break cmd = "esxcfg-vswitch -p {} -v {} {}".format(int_name, \ vlan, switch_name) self.log_command(cmd) self._shell.exec_command(cmd) logger.info("Succeed to clean vlan") return True logger.error("Failed to clean vlan") return False
def va_config_routes(self): """ add route for vArmour device and linux pc according to topo file Kwargs: None Return: True : Succeed to add route for pc or vArmour devices according to topo file. False : Failed to add route for pc or vArmour devices according to topo file. Examples: vatpobj = VaTopo(test_param_file, topo_file) vatpobj.va_config_routes() """ logger.debug("Start to config route") route_info = self.route_info for key in route_info.keys(): devobj = self.testdata.va_get_by_uniq_id(key, False) routes = route_info[key] node_type = devobj.get_nodetype() if (node_type == 'linux' or node_type == 'dir'): #only support linux pc and director now. devobj = self.testdata.va_get_by_uniq_id(key) for route in routes: if (not 'auto_set' in route) or (route['auto_set'] != 1): continue else: # if auto_set =1 , it means need to config route for defined pc if node_type == 'linux': result = devobj.config_route( route['dst'], route['netmask'], route['gateway']) if node_type == 'dir': #address netmask format. if isinstance(route['netmask'], int): address = route['dst'] + '/' + route['netmask'] else: address = route['dst'] + '/' + route['netmask'] result = devobj.va_set_route( ipaddress.IPv4Network(address), route['gateway'], True) if not result: logger.error('Failed to config route') logger.debug(devobj.show_route()) logger.debug(devobj.show_interface()) return False logger.info("Completed to config route") return True
def print_coredump_to_debug(self, corefile, *args, **kwargs): """ Print core dump information for debug. kwargs: corefile: core file name Return : None """ logger.debug("+------------------- Coredump ------------------------+") logger.debug("!") logger.debug("Corefilename: %s" % corefile) logger.debug("stack trace:") logger.debug(self.va_dump_coredump_backtrace(corefile)) logger.debug("end of stack trace") logger.debug("!") logger.debug("+------------------- End of Coredump -----------------+") return True
def va_set_debug(self, action='enable', is_reboot=True, *args, **kwargs): """ API to set debug into setup.ini file support debug for dir: 'agent', 'konfd', 'vadb', 'cn', 'chasd', 'io', 're', 'sn' support debug for cp : 'agent', 'konfd', 'vadb' support debug for ep : 'agent', 'konfd', 'vadb', 'io', 'sn' support debug for epi: 'agent', 'konfd', 'vadb', 'turbo' if 'name' is not specified, will be enable/disable all debugs based on device type param : action : enable/disable debug is_reboot : reboot device, True by default : kwargs : dict kwargs = { 'name' : name of debug switch, such as 'agent' } return: :bool - True on success or False on failure: example : va_set_debug(action=disable) va_set_debug(action=1) va_set_debug(name='vadb') """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) if action.lower() == 'enable': debug_value = 1 elif action.lower() == 'disable': debug_value = 0 else: raise ValueError( 'Action "{}" not support, should be "disable/enable"'.format( action)) set_debug_name = list() debug_map = { 'agent': 'enable_agent_debug', 'chasd': 'enable_chasd_debug', 'cn': 'enable_cn_debug', 'io': 'enable_io_debug', 'konfd': 'enable_konfd_debug', 're': 'enable_re_debug', 'sn': 'enable_sn_debug', 'turbo': 'enable_turbo_debug', 'vadb': 'enable_vadb_debug', } if 'name' in kwargs: name = kwargs.get('name') if name not in debug_map: raise ValueError('Not support debug name: {}'.format(name)) if not isinstance(name, list): set_debug_name.append(name) else: set_debug_name = name else: device_type = self._resource.get_nodetype() set_debug_name = ['agent', 'konfd', 'vadb'] if device_type == 'dir': set_debug_name.extend(['cn', 'chasd', 'io', 're', 'sn']) elif device_type == 'ep': set_debug_name.extend(['io', 'sn']) elif device_type == 'cp': pass elif device_type == 'epi': set_debug_name.extend(['turbo']) is_updated = False debug_status_before = self.va_get_debug_status() logger.debug('Start to {} debug'.format(action)) for debug_name in set_debug_name: debug_name = debug_map.get(debug_name) check_debug = int(debug_status_before.get(debug_name, -1)) if check_debug == -1 and debug_value: opt = "sed -i \'$a{}={}\'".format(debug_name, debug_value) elif check_debug != -1 and check_debug != debug_value: opt = "sed -i 's/{}={}/{}={}/g'".format(debug_name, check_debug, \ debug_name, debug_value) else: opt = None if opt is not None: setup_ini_file = '/config-varmour/configuration/varmour_conf/setup.ini' sed_output = self._access.va_shell('{} {}'.format( opt, setup_ini_file)) is_updated = True if is_reboot and is_updated: logger.warning('Device will reboot to active debug') self.va_reboot(timeout=60, persistent=True, reconnect_delay=90) elif not is_reboot: logger.warning('Device need reboot to active debug') failure_debug_name = list() debug_status_after = self.va_get_debug_status() for debug_name in set_debug_name: check_debug = int( debug_status_after.get(debug_map.get(debug_name), -1)) if debug_value: if check_debug != debug_value: failure_debug_name.append(debug_name) elif not debug_value: if check_debug != -1 and \ check_debug != 0: failure_debug_name.append(debug_name) if len(failure_debug_name) != 0: logger.error('Failed to {} debug {}'.format( action, failure_debug_name)) return False logger.info('Succeed to {} debug'.format(action)) return True
def tcpreplay(self, *args, **kwargs): """ method used to tcpreplay param : kwargs : dict : src_net : source subnet, : src_intf : source interface, : dest_obj : destination object, : dest_intf : destination interface, : path : file path of traffic packet file, : infile : traffic packet file, : pps|mbps : Replay packets at a given packets/sec|Mbps, fast as possible by default returns: :tuple - True and output on success or False and error message on failure: example : tcpreplay(**kwargs) kwargs = { 'infile' : 'google.pcap', 'src_net' : '15.15.15.0/24', 'dest_obj' : pc2, 'mbps' : 3, } """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) if 'dest_obj' not in kwargs: raise ValueError('"dest_obj" is a mandatory parameter!') dest_obj = kwargs.get('dest_obj') if 'src_net' not in kwargs: raise ValueError('"src_net" is a mandatory parameter!') src_net = kwargs.get('src_net') if 'infile' not in kwargs: raise ValueError('"infile" is a mandatory parameter!') infile = kwargs.get('infile') outfile = "tcprewrite_outfile" if outfile in kwargs: outfile = kwargs.get('outfile') path = '/tmp' if 'path' in kwargs: path = kwargs.get('path') if '/' not in infile: infile = "{}/{}".format(path, infile) if '/' not in outfile: outfile = "{}/{}".format(path, outfile) cachefile = '{}/cachefile'.format(path) src_intf = 'eth1' dest_intf = 'eth1' if 'src_intf' in kwargs: src_intf = kwargs.get('src_intf') if 'dest_intf' in kwargs: dest_intf = kwargs.get('dest_intf') src_mac = self.get_mac(src_intf) dest_mac = dest_obj.get_mac(dest_intf) enet_smac = "{},{}".format(dest_mac, src_mac) enet_dmac = "{},{}".format(src_mac, dest_mac) if 'pps' in kwargs: opt_rate = "--pps={}".format(kwargs.get('pps')) elif 'mbps' in kwargs: opt_rate = "--mbps={}".format(kwargs.get('mbps')) else: opt_rate = "--topspeed" cmd_prep = "tcpprep" cmd_rewrite = "tcprewrite" cmd_replay = "tcpreplay" cmd_prep = "{} --cidr={} --pcap={} --cachefile={}".format(cmd_prep, src_net, \ infile, cachefile) cmd_rewrite = "{} --enet-smac={} --enet-dmac={} --fixcsum --cachefile={} \ --infile={} --outfile={}" .format(cmd_rewrite, enet_smac, enet_dmac, cachefile, \ infile, outfile) cmd_replay = "{} --cachefile={} --intf1={} --intf2={} {} {}".format(cmd_replay, \ cachefile, src_intf, dest_intf, opt_rate, outfile) pattern = re.compile(r'command not found|No such file or directory') for cmd in [cmd_prep, cmd_rewrite, cmd_replay]: output = self._access.shell(cmd) if pattern.search(output[0]) is not None: return (False, output[0]) for f in [infile, outfile, cachefile]: self._access.shell("rm -f {}".format(f)) logger.debug('Tcpreplay info: \n{}'.format(output[0])) pattern = re.compile(r'Actual: \d+ packets \(\d+ bytes\) sent') if pattern.search(output[0]) is None: logger.error( 'Failed to tcpreplay, expected expression: {}'.format(pattern)) return (False, output[0]) logger.info('Succeed to tcpreplay') return (True, output[0])
def va_move_log_file(self): """ Move log file to external log server. kwargs: None """ log_server2_tag = False if testdata.va_get_control().get('move_log').upper() == 'N': logger.debug('Noe need to move log file to external log server') return True ip = log_server1._access._resource.get_mgmt_ip() user = log_server1._access._resource.get_user() user_name = user.get('name') user_pwd = user.get('password') #check log_server2 if it is in topo file. if 'log_server2' in testdata.va_get_test_vms(): log_server2_tag = True ip2 = log_server2._access._resource.get_mgmt_ip() user2 = log_server2._access._resource.get_user() user_name2 = user2.get('name') user_pwd2 = user2.get('password') jobid = os.getpid() try: curframe = inspect.currentframe() calframe = inspect.getouterframes(curframe, 2) caller_name = calframe[4][3] casename = caller_name except Exception as error: casename = 'test' destdir = "/var/log/varmour_log/%s/%s" % (jobid, casename) log_server1.exec_command("mkdir -p %s " % destdir) node_type = self._access._resource.get_nodetype() name = self._resource.get_uniq_id() curr_mode = self.va_get_mode() # download debug log file from all EPs. if (node_type == "dir"): if name == "dir_1" and curr_mode != "PB" or curr_mode == "M": self._access.va_cli( "request download debug-log device all all", 600) if (curr_mode == "PB"): dev_num = 1 else: output = self._access.va_cli('show chassis') match1 = re.search(r'total devices connected:\s+(\d+)\s+', output, re.I | re.M) match2 = re.search(r'inactive devices:\s+(\d+)\s+', output, re.I | re.M) if match1 is None or match2 is None: dev_num = 1 else: dev_num = int(match1.group(1)) - int(match2.group(1)) else: dev_num = 1 logdir = "/var/log/varmour_log" apachedir = "/var/log/apache2" destdir = "/var/log/varmour_log/%s/%s" % (jobid, casename) log_server1.exec_command("mkdir -p %s " % destdir) self._access.va_shell("sudo ls -l %s/*" % logdir) self._access.va_shell("sudo grep \"Exception\" %s/current/*.log" % logdir) cmd_tar = "sudo tar -zcvf %s/log_%s.tar %s/current/* %s/*" % \ (logdir, name, logdir, apachedir) if (int(dev_num) >= 2): dev_num = int(dev_num) + 1 for i in range(2, int(dev_num)): cmd_tar = cmd_tar + " %s/dev_%d/*" % (logdir, i) set_cmds = [] set_cmds.append(cmd_tar) self._access.va_shell(set_cmds, 200) set_cmd2 = "sudo scp -o 'StrictHostKeyChecking no'" set_cmd2 += " %s/log_%s.tar* %s@%s:%s" % (logdir, name, user_name, ip, destdir) self._access.va_shell(set_cmd2, 200, **{'handle_password': user_pwd}) #check the file if it exist on log server. #it will move to backup logserver if failure. output = log_server1.exec_command('ls {}'.format(destdir)) if re.search(r'No such file or directory', output, re.I | re.M) is not None: logger.error('Failed to copy log file to logserver {}'.format(ip)) if log_server2_tag: log_server2.exec_command("mkdir -p %s " % destdir) set_cmd2 = "sudo scp -o 'StrictHostKeyChecking no'" set_cmd2 += " %s/log_%s.tar* %s@%s:%s" % \ (logdir, name, user_name2, ip2, destdir) self._access.va_shell(set_cmd2, 200, **{'handle_password': user_pwd2}) output = log_server2.exec_command('ls {}'.format(destdir)) if re.search(r'No such file or directory', output, re.I | re.M) is not None: logger.error( 'Failed to copy log file to logserver {}'.format(ip2)) return False else: return False set_cmds = [] set_cmds.append("sudo rm -f %s/current/*" % logdir) if (int(dev_num) >= 2): for i in range(2, int(dev_num)): set_cmds.append("sudo rm -rf %s/dev_%d" % (logdir, i)) set_cmds.append("sudo rm -f %s/log_%s.tar*" % (logdir, name)) self._access.va_shell(set_cmds) logger.error("The log files have been moved to %s@%s:%s/" % \ (user_name, ip, destdir)) return True
def setup(self, **kwargs): """ Implementation of setup test bed Kwargs: None Return: True : Succeed to setup test bed False : Failed to setup testbed Examples: vatpobj = VaTopo(test_param_file, topo_file) vatpobj.setup() """ setup_tb = self.control_data.get('setup_tb') cleanup_dut_cfg = self.control_data.get('cleanup_dut_cfg') upgrade_device = self.control_data.get('upgrade_device') logger.info("*********************************") logger.info("* ") logger.info("* Start to setup topology ") logger.info("* ") logger.info("*********************************") if (setup_tb.upper() == 'Y') : #Config links if not self.config_links(): logger.error('Failed to configure links') return False #Config interface if not self.va_config_interfaces(): logger.error('Failed to configure ip address of interfaces') return False #Config interface if not self.va_config_routes(): logger.error('Failed to configure routes') return False else : logger.info('Noe need to setup testbed') if (cleanup_dut_cfg.upper() == 'Y') : # Reset director if not self.va_reset_director(): return False else : logger.info('Not need to cleanup director') #upgrade device if need. if (upgrade_device.upper() == 'Y' and self.image is not None) : if not self.va_update_firmware_for_directors(self.image): return False else: logger.info('Not need to upgrade device') #reconnect all cp/ep/epi logger.debug("*********************************") logger.debug("* ") logger.debug("* Finished to setup topology ") logger.debug("* ") logger.debug("*********************************") return True
def va_send_and_verify_icmp(*args, **kwargs): """ API to send traffic, capture packet and verify session related to ICMP param : kwargs : dict example : va_send_and_verify_icmp(**kwargs) kwargs = { 'traffic_data' : { 'client' : pc1, 'server' : pc2, 'src_intf' : 'eth1', 'dest_intf' : 'eth1', 'size' : 64, 'count' : 5, more parameters refer to Icmp, }, 'tcpdump_data' : { 'expr' : expression to match packets, 'host' : 15.15.15.2, 'intf' : 'eth4', more parameters refer to start_tcpdump and check_tcpdump, }, 'session_data' : { 'policy' : 'test_pol', more parameters refer to va_verify_session, } 'dev_obj' : dir_1, return: :bool - True on success or False on failure: """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) if 'traffic_data' not in kwargs or \ 'session_data' not in kwargs: raise ValueError('traffic_data and session_data are \ mandatory parameters!\n') traffic_data = kwargs.get('traffic_data') session_data = kwargs.get('session_data') if 'dev_obj' not in kwargs: raise ValueError('dev_obj is mandatory parameter!\n') dev_obj = kwargs.get('dev_obj') if 'client' not in traffic_data or \ 'server' not in traffic_data or \ 'src_intf' not in traffic_data or \ 'dest_intf' not in traffic_data: raise ValueError('client, server, src_intf and dest_intf are \ mandatory parameters!\n') client = traffic_data.get('client') server = traffic_data.get('server') src_intf = traffic_data.get('src_intf') dest_intf = traffic_data.get('dest_intf') client_ip = client.get_ip(src_intf) server_ip = server.get_ip(dest_intf) tcpdump_data = None if 'tcpdump_data' in kwargs: tcpdump_data = kwargs.get('tcpdump_data') if 'intf' not in tcpdump_data: raise ValueError('intf is mandatory parameter!\n') intf = tcpdump_data.get('intf') if 'expr' in tcpdump_data: expr = tcpdump_data.get('expr') else: expr = '{}\s+>\s+{}:\s+ICMP echo request'.format( client_ip, server_ip) icmp_obj = Icmp(**traffic_data) if tcpdump_data is not None: packets_file, pid, process_file = server.start_tcpdump(intf=intf) if packets_file is None: return False dev_obj.va_clear_session() try: icmp_obj.start(**traffic_data) except ValueError as e: logger.error(e) logger.debug('Start to clean traffic since got exception') icmp_obj.stop() return False session = dev_obj.va_get_session() icmp_obj.stop() if tcpdump_data is not None: time.sleep(2) if not server.stop_tcpdump(pid, process_file): return False if not server.check_tcpdump(packets_file, expr, **tcpdump_data): return False session_data['proto'] = 'icmp' session_data['session'] = session if not dev_obj.va_verify_session(**session_data): return False del session_data['session'] return True
def va_send_and_verify_tftp(*args, **kwargs): """ API to send traffic and verify session related to FTP param : kwargs : dict example : va_send_and_verify_tftp(**kwargs) kwargs = { 'traffic_data' : { 'client' : pc1, 'server' : pc2, 'dest_intf' : 'eth1', more parameters refer to Icmp, }, 'session_data' : { 'policy' : 'test_pol', more parameters refer to va_verify_session, } 'dev_obj' : dir_1, return: :bool - True on success or False on failure: """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) if 'traffic_data' not in kwargs or \ 'session_data' not in kwargs: raise ValueError('traffic_data and session_data are \ mandatory parameters!\n') traffic_data = kwargs.get('traffic_data') session_data = kwargs.get('session_data') if 'dev_obj' not in kwargs: raise ValueError('dev_obj is mandatory parameter!\n') dev_obj = kwargs.get('dev_obj') dev_obj.va_clear_session() tftp_obj = Tftp(**traffic_data) try: tftp_obj.start(**traffic_data) except ValueError as e: logger.error(e) logger.debug('Start to clean traffic since got exception') tftp_obj.stop() return False session = dev_obj.va_get_session() times = 1 session_data['proto'] = 'tftp' data_session_before = dev_obj.va_get_data_session(**session_data) time.sleep(1) data_session_after = dev_obj.va_get_data_session(**session_data) is_increment = dev_obj.va_check_session_packets_increment( data_session_before, data_session_after) while times <= 6 and not is_increment: logger.info( 'Retry {} times to check if session packet increment'.format( times)) time.sleep(1) data_session_after = dev_obj.va_get_data_session(**session_data) is_increment = dev_obj.va_check_session_packets_increment( data_session_before, data_session_after) times += 1 tftp_obj.stop() if not is_increment: return False session_data['session'] = session if not dev_obj.va_verify_session(**session_data): return False del session_data['session'] return True
def va_setup_ha(*args, **kwargs): """ API to setup HA environment. param : kwargs : dict example : va_setup_ha(**kwargs) kwargs = { 'master' : {dir1 : {'local_address' : '8.8.8.1/24', 'remote_address' : '8.8.8.2', 'priority' : 8, 'preempt' : enable, 'sw_obj' : vswitch object, 'vlan' : 3, used to update vlan of fabric into the same with pb } }, 'pb' : {dir2 : {'local_address' : '8.8.8.2/24', 'remote_address' : '8.8.8.1' 'priority' : 10, 'preempt' : enable, 'sw_obj' : vswitch object, 'vlan' : 3, used to update vlan of fabric into the same with master } }, 'origin_vlan' : dict, included vlan_port, vlan_id and vswitch of HA, used to split vlan of fabric of pb into different from master 'timeout' : 60, } return: :bool - True on success or False on failure: """ logger.info("\nIn subroutine: " + sys._getframe().f_code.co_name) if 'master' not in kwargs or \ 'pb' not in kwargs: raise ValueError("master and pb are mandatory parameter!\n") master, master_kwargs = kwargs.get('master').popitem() pb, pb_kwargs = kwargs.get('pb').popitem() for kwgs in [master_kwargs, pb_kwargs]: if 'local_address' not in kwgs or \ 'remote_address' not in kwgs or\ 'vlan' not in kwgs or\ 'sw_obj' not in kwgs: raise ValueError("'local_address', 'remote_address', \ 'vlan' and 'sw_obj' are mandatory parameters!\n") if 'origin_vlan' not in kwargs: raise ValueError("origin_vlan is mandatory parameter!\n") origin_vlan = kwargs.pop('origin_vlan') if 'timeout' in kwargs: timeout = kwargs.get('timeout') else: timeout = 60 * 2 master_uniq_id = master._resource.get_uniq_id() pb_uniq_id = pb._resource.get_uniq_id() master_sw_obj = master_kwargs.get('sw_obj') pb_sw_obj = pb_kwargs.get('sw_obj') vlan_data = origin_vlan.get(pb_uniq_id) vlan_data['sw_obj'] = pb_sw_obj if not va_update_ha_vlan(**vlan_data): return False times = 1 sleeptime = 10 status = master.va_check_chassis_status() while not status and times <= 6: logger.info('Sleeping {} seconds to wait'.format(sleeptime)) time.sleep(sleeptime) status = master.va_check_chassis_status() times += 1 if not status: return False if not master.va_config_ha(*args, **master_kwargs): return False times = 1 sleeptime = 2 ha_info = master.va_show_ha() ha_mode = ha_info.get('HA Mode') while ha_mode != 'ON' and times <= 6: logger.info('Sleeping {} seconds to wait'.format(sleeptime)) time.sleep(sleeptime) ha_info = master.va_show_ha() ha_mode = ha_info.get('HA Mode') times += 1 if ha_mode != 'ON': return False if not pb.va_delete_db(): return False pb.va_reboot(reconnect_delay=timeout) if not pb.va_config_ha(*args, **pb_kwargs): return False pb.va_reboot(reconnect_delay=timeout) for uniq_id in [master_uniq_id, pb_uniq_id]: vlan_data = dict() if uniq_id == master_uniq_id: vlan_data = master_kwargs elif uniq_id == pb_uniq_id: vlan_data = pb_kwargs vlan_data['port_group'] = origin_vlan[uniq_id]['port_group'] if not va_update_ha_vlan(**vlan_data): return False for dev_obj in [master, pb]: times = 1 sleeptime = 10 logger.debug('Waiting HA to normal') try: ha_info = dev_obj.va_show_ha() ha_mode = ha_info.get('HA Mode') except: pass while ha_mode != 'ON' and times <= 6: logger.info('Sleeping {} seconds to wait'.format(sleeptime)) time.sleep(sleeptime) try: ha_info = dev_obj.va_show_ha() ha_mode = ha_info.get('HA Mode') except: pass times += 1 times = 1 sleeptime = 10 is_ready = dev_obj.va_check_ha_ready() while not is_ready and times <= 30: logger.info('Sleeping {} seconds to wait'.format(sleeptime)) time.sleep(sleeptime) is_ready = dev_obj.va_check_ha_ready() times += 1 if not is_ready: logger.error('Unsuccessfully configured HA environment') return False logger.info('Successfully configured HA environment') return True
def va_move_core_file(self, core_file, casename='test'): """ move core file to external log server kwargs: log_server: object of log server Return : True """ log_server2_tag = False if testdata.va_get_control().get('move_core').upper() == 'N': logger.debug('Not need to move core file to external log server') return True ip = log_server1._access._resource.get_mgmt_ip() user = log_server1._access._resource.get_user() user_name = user.get('name') user_pwd = user.get('password') #check log_server2 if it is in topo file. if 'log_server2' in testdata.va_get_test_vms(): ip2 = log_server2._access._resource.get_mgmt_ip() user2 = log_server2._access._resource.get_user() user_name2 = user2.get('name') user_pwd2 = user2.get('password') log_server2_tag = True jobid = os.getpid() destdir = "/var/log/varmour_log/%s/%s" % (jobid, casename) log_server1.exec_command("mkdir -p %s " % destdir) coredir = "/usr-varmour/core" set_cmds = [] index = 1 exec_files = "" for core in core_file: core = core.strip() core = '/usr-varmour/core/{}'.format(core) match_core = re.search(r'(.*).gz|.tar', core, re.I) if match_core is not None: # uncompress core file self._access.va_shell("sudo gunzip -d %s" % core) un_compress_core_file = match_core.group(1) self.print_coredump_to_debug(un_compress_core_file) # compress core file self._access.va_shell("sudo gzip %s" % un_compress_core_file, 200) else: self.print_coredump_to_debug(core) if (index == 1): tar_file_name = "%s.tar" % core exefile = self._va_get_full_exe_name_from_core(core) exec_files += " " + exefile index += 1 logger.info("compress core file") cmd = "sudo tar -zcvf {} ".format(tar_file_name) for corename in core_file: cmd += "/usr-varmour/core/{} ".format(corename) cmd += "{} /etc/syslog-ng/*".format(exec_files) cmd += " /etc/pam.d/* /opt/varmour/conf/* /var/log/varmour_log/current/*" cmd += " /etc/nsswitch.conf " set_cmds.append(cmd) self._access.va_shell(set_cmds, 200) set_cmd = "sudo scp -o 'StrictHostKeyChecking no' " set_cmd += "{} {}@{}:{}".format(tar_file_name, user_name, ip, destdir) self._access.va_shell(set_cmd, 200, **{'handle_password': user_pwd}) #check the file if it exist on log server. #it will move to backup logserver if failure. output = log_server1.exec_command('ls {}'.format(destdir)) #check log_server2 if it is in topo file. if re.search(r'No such file or directory', output, re.I | re.M) is not None: logger.error('Failed to copy core file to logserver {}'.format(ip)) if log_server2_tag: log_server2.exec_command("mkdir -p %s " % destdir) set_cmd = "sudo scp -o 'StrictHostKeyChecking no' " set_cmd += "{} {}@{}:{}".format(tar_file_name, user_name2, ip2, destdir) self._access.va_shell(set_cmd, 200, **{'handle_password': user_pwd2}) output = log_server2.exec_command('ls {}'.format(destdir)) if re.search(r'No such file or directory', output, re.I | re.M) is not None: logger.error( 'Failed to copy core file to logserver {}'.format(ip2)) return False else: return False # delete all core files. cmd = "sudo rm -f " for corename in core_file: cmd += "/usr-varmour/core/{} ".format(corename) cmd += "{} ".format(tar_file_name) self._access.va_shell(cmd) logger.error("The device have core file!\n") log_msg = "The core, log, and cfg file have been moved to" logger.error(log_msg + " %s@%s:%s/\n" % (user_name, ip, destdir)) return True
def va_dump_coredump_backtrace(self, corefile, *args, **kwargs): """ Print core file information via gdb kwargs: corefile: core file name Return : None """ exefile = self._va_get_full_exe_name_from_core(corefile) cmd = "sudo gdb {} --batch --core {} --quiet".format(exefile, corefile) cmd += " --ex 'set pagination off' -ex 'bt full' -ex 'quit'" cmd1 = "sudo gdb {} --batch --core {} --quiet".format( exefile, corefile) cmd1 += " --ex 'set pagination off' -ex 'thread apply all bt full' -ex 'quit'" logger.debug("+++++++++++++++++++++++++++++++++++++++++++++++") logger.debug("+ gdb with bt full +") logger.debug("+++++++++++++++++++++++++++++++++++++++++++++++") self._access.va_shell(cmd, 200) logger.debug("+++++++++++++++++++++++++++++++++++++++++++++++") logger.debug("+ gdb with thread apply all bt full +") logger.debug("+++++++++++++++++++++++++++++++++++++++++++++++") self._access.va_shell(cmd1, 240) return True
def start(self, *args, **kwargs): """ method used to start the Tftp traffic process in the background on the client. It does a clean up of file if existing locally. It launches the tftp client tool in the background, and gets the corresponding pid. If it cannot retrieve the pid it means the transfer is already complete or the process launch failed. kwargs: :file_size (str): size of the file to be get in terms of MB :rate (int): transfer rate (kb) :operation (str): -g, get remote file :timeout (int): tftp timeout """ self._cmd = 'curl' self._type = 'tftp' self._rate = 128 self._timeout = 90 self._file_size = 100 self._operation = '-g' self._stats = None self._outfile = None if 'rate' in kwargs: self._rate = kwargs.get('rate') if 'operation' in kwargs: self._operation = kwargs.get('operation') if 'file_size' in kwargs: self._file_size = kwargs.get('file_size') if 'timeout' in kwargs: self._timeout = kwargs.get('timeout') try: self._setup_server_infra() self._build_tftp_cmd() except ValueError as e: raise e client = self._conf_client self._transfer_cleanup_util(True) logger.info('######################################################') logger.info('# #') logger.info("# Warning, TFTP can't control transfer rate so far!!!#") logger.info('# #') logger.info('######################################################') pid, outfile = client.exec_background( self._cmd, redirect=True, search_expr=self._cmd.split(' ')[0]) logger.info('Tftp pid: {}'.format(pid)) logger.info('Outfile: {}'.format(outfile)) self._outfile = outfile if not pid or outfile is None: raise ValueError('Tftp traffic not started') times = 1 sleeptime = 0.2 self._stats = self.get_stats() while (self._stats == 'failed' or self._stats is None) and times <= 5: logger.debug( 'Sleeping {} seconds to start traffic'.format(sleeptime)) time.sleep(sleeptime) self._stats = self.get_stats() times += 1 if self._stats == 'failed' or self._stats is None: raise ValueError('Tftp traffic not started') logger.info('Tftp traffic started')
def start(self, *args, **kwargs): """ method used to start the Icmp traffic process in the background on the client. It does a clean up of file if existing locally. It launches the ping client tool in the background, and gets the corresponding pid. If it cannot retrieve the pid it means the transfer is already complete or the process launch failed. kwargs: :src_intf (str): source interface name :count (int): number of ICMP pings :size (int): size of the ping packet :timeout (int): ping timeout """ self._cmd = 'ping' self._type = 'ping' self._count = 5 self._size = 56 self._timeout = 60 self._interval = 0.2 self._src_intf = None self._stats = None self._outfile = None if 'src_intf' in kwargs: self._src_intf = kwargs.get('src_intf') if 'count' in kwargs: self._count = kwargs.get('count') if 'size' in kwargs: self._size = kwargs.get('size') if 'timeout' in kwargs: self._timeout = kwargs.get('timeout') if 'interval' in kwargs: self._interval = kwargs.get('interval') if 'dest_ip' in kwargs: self._dest_ip = kwargs.get('dest_ip') try: self._build_ping_cmd() except ValueError as e: raise e client = self._conf_client pid, outfile = client.exec_background( self._cmd, redirect=True, search_expr=self._cmd.split(' ')[0]) logger.info('Icmp pid: {}'.format(pid)) logger.info('Outfile: {}'.format(outfile)) self._outfile = outfile if not pid or outfile is None: raise ValueError('Icmp traffic not started!') times = 1 sleeptime = 0.1 max_times = 10 if re.search(r'(\d+\.){3}', self._dest_ip) is None: sleeptime = 1 time.sleep(2) self._stats = self.get_stats() while (self._stats == 'failed' or self._stats is None) and times <= max_times: logger.debug( 'Sleeping {} seconds to start traffic'.format(sleeptime)) time.sleep(sleeptime) self._stats = self.get_stats() times += 1 if self._stats == 'failed' or self._stats is None: raise ValueError('Icmp traffic not started!') logger.info('Icmp traffic started')