def connect(self): """ Connect to IxVeriwave chassis """ self.telnet_handle = Telnet(self.chassis) # First we need to login to the chassis by issuing the appropriate command for the expected prompts match_results = self.telnet_handle.expect( [br"Hit Enter to proceed:\s"], timeout=self.expect_timeout) if match_results[0] == -1: raise TobyException( "Expected 'Hit Enter to proceed: ' but instead got:\r\n'" + match_results[2].decode('ascii') + "'") # We need to hit enter to continue self.telnet_handle.write(b'\r\n') match_results = self.telnet_handle.expect([br"Enter username:\s"], timeout=self.expect_timeout) if match_results[0] == -1: raise TobyException( "Expected 'Enter username: '******'" + match_results[2].decode('ascii') + "'") # We need to enter username at this point user = self.host_args['user'] + '\r\n' user = user.encode(encoding='ascii') self.telnet_handle.write(user) match_results = self.telnet_handle.expect([self.prompt], timeout=self.expect_timeout) if match_results[0] == -1: raise TobyException("Expected 'ready>' but instead got:\r\n'" + match_results[2].decode('ascii') + "'") else: return "Successfully connected to IxVeriwave chassis!"
def get_var_from_task(self, job='default', task=None, var=None): ''' Get Var from the specified Job and/or Tasks ARGUMENTS: [job='default', task=None, var=None] :param STR job: *OPTIONAL* job name.Default is set to "default". :param STR task: *MANDATORY* name of the task.To get var details. Default is set to None. :param STR var: *MANDATORY* Name of the var.Default is set to None. ROBOT USAGE: Run In Parallel tasks=task1,task2,task3,task4 ${res} = Get Var From Task task=task1 var=$(res) :return:return vars. else raise exception. ''' if not task: raise TobyException("Task name need to be passed get var") if not var: raise TobyException("Variable name need to be passed get var") match = re.match(r'^\$\((\w*)\)\s?', var) if match: var_name = match.group(1) else: var_name = var if task not in self._vars[job]: raise TobyException("Task " + task + " is not defined") if var_name not in self._vars[job][task]: raise TobyException("Variable " + var + " is not defined") return self._vars[job][task][var_name]
def __download_selenium_jar(self): selenium_jar_path = "C:/selenium/selenium-server-standalone-%s.jar" % self.selenium_jar_version file_status = self.shell(command="IF EXIST " + selenium_jar_path + " ECHO file found successfully").response() if re.search("file found successfully", file_status, re.I): grid_path = selenium_jar_path else: self.log("file not found on device, now attempting to download") download_status = self.shell( command='wget http://selenium-release.storage.googleapis.com' '/%s/selenium-server-standalone-%s.jar -P ' 'C:/selenium/ 2>&1 | FINDSTR /I /R "error ' 'failed"' % (self.selenium_jar_major_version, self.selenium_jar_version), timeout=180).response() if re.search("not recognized as an internal or external command", download_status, re.I) is not None: raise TobyException("wget utility not installed, now exiting", host_obj=self) elif re.search('(error|failed)', download_status, re.I) is not None: raise TobyException( "Unable to download selenium-server-standalone-%s.jar" % self.selenium_jar_version, host_obj=self) else: grid_path = selenium_jar_path return grid_path
def _set_current_controller(self, role='MASTER'): if len(self.controllers.keys()) == 1: self.current_controller_str = list(self.controllers.keys())[0] self.current_controller = self.controllers[ self.current_controller_str] self.current_controller.dual_controller = False else: for controller in self.controllers.keys(): self.controllers[controller].dual_controller = True if role.upper() == 'MASTER': if self.controllers[controller].is_master(): self.current_controller = self.controllers[controller] self.current_controller_str = controller break elif role.upper() == 'BACKUP': if not self.controllers[controller].is_master(): self.current_controller = self.controllers[controller] self.current_controller_str = controller break else: raise TobyException( "Invalid Role provided, valid values are'Master/Backup'" ) if not self.current_controller: raise TobyException("Unable to set current_controller")
def connect(self, port_list, reset=1, **kwargs): # pylint: disable=unused-argument """ Connect to Breakingpoint chassis :param port_list (*REQUIRED): port list , ex: '1/9 1/10 1/11' :return: breakingpoint connection object """ self.log('Attempting to connect to Breakingpoint...') if not port_list: raise TobyException("Missing port_list parameter", host_obj=self) self.port_list = port_list try: self.bps.login() except Exception as error: raise TobyException("Error in 'bpsRest.py': " + str(error)) sorted_ports = dict() for port in port_list: slot, num = port.split('/') sort_key = '{:03}'.format(int(slot)) + '{:03}'.format(int(num)) sorted_ports[sort_key] = (slot, num) self.debug = True for sort_key in sorted(sorted_ports): slot, num = sorted_ports[sort_key] reserve_status = self.bps.reservePorts( slot=slot, portList=[num], group=self.group, force=True, enableRequestPrints=self.debug) self.log("Reserve Status for port(s) " + str(num) + ": " + str(reserve_status))
def _get_lib_version(self): """ Needed to determine which Breakingpoint library folder to use. """ breakingpoint_lib_ver = None try: best_match = None breakingpoint_lib_vers = list( filter(lambda x: os.path.isdir(os.path.join(self.lib_path, x)), os.listdir(self.lib_path))) for possible_lib_ver in breakingpoint_lib_vers: if re.search(r'\d+\.\d+\.\d+', possible_lib_ver): if possible_lib_ver == self.version: breakingpoint_lib_ver = possible_lib_ver break elif re.search('^' + self.major_version + '.', possible_lib_ver): best_match = possible_lib_ver if best_match and not breakingpoint_lib_ver: breakingpoint_lib_ver = best_match except: raise TobyException("Unable to find appropriate Breakingpoint lib version in " + self.lib_path + \ " for Breakingpoint version " + self.version, host_obj=self) if not breakingpoint_lib_ver: raise TobyException("Unable to find appropriate Breakingpoint lib version in " + self.lib_path + \ " for Breakingpoint version " + self.version, host_obj=self) self.log("BREAKINGPOINT LIB AVAILABLE= " + str(breakingpoint_lib_ver)) return breakingpoint_lib_ver
def shell(self, *args, **kvargs): """ Method called by user to send a string command to device and save its response. :param command: **REQUIRED** string command to be sent to the device :param pattern: *OPTIONAL* Output will be collected till this pattern is found. :param timeout: *OPTIONAL* Time by which output is expected. Default is set based on os/platform/model of the box :return: response from device. exception if timeout seen """ if 'command' not in kvargs: raise TobyException('Command for device not specified', host_obj=self) try: kvargs['timeout'] = kvargs.get('timeout', self.shell_timeout) patt_match = self.execute(*args, **kvargs) if patt_match == -1: raise TobyException('Timeout seen while retrieving output', host_obj=self) else: return_value = Response(response=self.response) return return_value except: raise TobyException("Timeout seen while retrieving output", host_obj=self)
def cli(self, command='', mode='privileged', pattern=None, timeout=60, kw_call=False): """ Executes operational commands for user or privileged mode on IOS device_object.cli(command = 'show version') :param command: **REQUIRED** CLI command to execute :param mode: **OPTIONAL** 'user' or 'privileged' mode. Default: privileged :param timeout: *OPTIONAL* Time by which response should be received. Default is 60 seconds :param pattern: Expected pattern :return: Object with the following methods 'response()': Response from the CLI command(text) """ if command is None: raise TobyException("Mandatory argument 'command' is missing!", host_obj=self) self._switch_mode(mode=mode) if not pattern: pattern = self.prompt # Only one command can be executed if not isinstance(command, str): raise TobyException("'command' should be a string", host_obj=self) self.log('command: ' + command) response = self.execute(command=command, pattern=pattern, timeout=timeout) return_value = Response(response=response, status=True) return return_value
def get_credentials(self, **kwargs): """ Populates user and password based on user inputs. DESCRIPTION: Populates self.user and self.password based on user inputs. If user has not provided then try to get them from default credentials. Else raise an exception. ARGUMENTS: [kwargs] :param STR user: *OPTIONAL* user name :param STR password: *OPTIONAL* password of the device :param STR ssh_key_file: *OPTIONAL* ssh key value ROBOT USAGE: NOT EXPOSED TO ROBOT USAGE :return: Tuple containing username and password """ # Check if user and password are passed arguments if (not kwargs.get('user') or not kwargs.get('password')) and \ (not kwargs.get('user') or not kwargs.get('ssh_key_file')): if self.os.upper() == 'JUNOS': dev_cred = credentials.JUNOS elif self.os.upper() in ("UNIX", "LINUX", "CENTOS", "FREEBSD", "UBUNTU"): dev_cred = credentials.UNIX elif self.os.upper() == 'IOS': dev_cred = credentials.IOS elif self.os.upper() == 'SPIRENT': dev_cred = credentials.SPIRENT elif self.os.upper() == 'BREAKINGPOINT': dev_cred = credentials.BREAKINGPOINT elif self.os.upper() == 'PARAGON': dev_cred = credentials.PARAGON elif self.os.upper() == 'BPS': dev_cred = credentials.BREAKINGPOINT elif self.os.upper() == 'ELEVATE': dev_cred = credentials.ELEVATE elif self.os.upper().startswith('IX'): dev_cred = credentials.IXIA elif self.os.upper() == 'WINDOWS': dev_cred = credentials.WINDOWS else: raise TobyException('Unknown Device OS', host_obj=self) # Check if default credentials are available if not dev_cred['USERNAME'] and not dev_cred['PASSWORD']: raise TobyException("Username/Password cannot be determined", host_obj=self) return dev_cred['USERNAME'], dev_cred['PASSWORD'] if kwargs.get('ssh_key_file', None): return kwargs['user'], kwargs.get('password', None) else: return kwargs['user'], kwargs['password']
def __init__(self, **kwargs): """ :param host: **REQUIRED** hostname or IP address of device to telnet to :param user: *OPTIONAL* Login user name. If not provided will be derived from Toby framework defaults. :param password: *OPTIONAL* Login Password. If not provided will be derived from Toby framework defaults. :param connect_mode: *OPTIONAL* Connection mode to device. Default is telnet. Supported value is telnet. """ if 'host' not in kwargs: raise TobyException("Mandatory Parameter host missing") # if username and password are not specified by caller kwargs['os'] = kwargs.get('osname', 'WINDOWS') if not kwargs.get('user', None): kwargs['user'], kwargs['password'] = credentials.get_credentials( os=kwargs.get('osname', 'WINDOWS')) host = kwargs.get('host') connect_mode = kwargs.get('connect_mode', 'telnet') super(Windows, self).__init__(**kwargs) self.log(message='Trying to connect to device ' + host + ' via ' + connect_mode + ' ...') self.prompt = 'Toby-%s-%s' % (os.getpid(), host) self.prompt += '%' self.port = kwargs.get('text_port') try: if connect_mode == 'ssh': self.prompt = '>\s?' handle = SshConn(host=host, user=kwargs['user'], password=kwargs['password'], initialize_command='cd') else: handle = TelnetConn(host=host, user=kwargs['user'], password=kwargs['password'], port=self.port) self.handle = handle self.log(message='Connection to ' + host + ' via ' + connect_mode + ' is successful.') except: raise TobyException( "Cannot connect text channel via %s to %s Device %s" % (connect_mode, kwargs['os'], host), host_obj=self) if self.port == 23: self.set_shell_prompt(prompt=self.prompt) else: self.prompt = '>\s?' self.connected = 1 self.response = '' self.mode = 'shell'
def _get_juniper_details(self): response = self.handle.cli( command='show version invoke-on all-routing-engines', format='xml', warning=False) try: multi_re = response.findall('multi-routing-engine-item') except: raise TobyException('Could not connect to the other RE.') if len(multi_re) > 0: re_name0 = multi_re[0].find('re-name').text model0 = multi_re[0].find( 'software-information/product-model').text host_name0 = multi_re[0].find( 'software-information/host-name').text os_list = multi_re[0].findall( 'software-information/package-information') os0 = 'junos' try: re_name1 = multi_re[1].find('re-name').text model1 = multi_re[1].find( 'software-information/product-model').text host_name1 = multi_re[1].find( 'software-information/host-name').text os_list1 = multi_re[1].findall( 'software-information/package-information') os1 = 'junos' dual_re = True except: re_name1 = None model1 = None host_name1 = None os1 = None dual_re = False facts_list = [ dual_re, re_name0, host_name0, model0, os0, re_name1, host_name1, model1, os1 ] else: try: if 're-name' in response: re_name = response.find('re-name').text else: re_name = 're0' model = response.find('product-model').text host_name = response.find('host-name').text os_list = response.findall('package-information') devos = os_list[0].find('name').text facts_list = [ False, re_name, host_name, model, devos, None, None, None, None ] except: raise TobyException('Could not retrieve details') return facts_list
def _run_all_tasks(self, job='default', tasks=None, *args): ''' Runs all the tasks in a job in parallel. ''' targets = [] # Checks if task names are inputted if tasks: # checks if tasks is a list try: tasks = eval(tasks) except (NameError, SyntaxError): pass # checks if tasks is string if isinstance(tasks, str): tasks = tasks.split(',') # parses tasks and gets the keywords, args and kwargs for task in tasks: target_dict = {} target_dict['target'] = self._wrapped_f list_args = self._jobs[job].get(task, []) if not list_args: raise TobyException("Task " + task + " is not defined") target_dict['args'] = [] target_dict['args'].extend(list_args) target_dict['kwargs'] = {'job': job, 'task': task} targets.append(target_dict) # checks if a job name is inputted and parses tasks defined in it elif job is not 'default' and job: for task in self._jobs[job]: target_dict = {} target_dict['target'] = self._wrapped_f list_args = self._jobs[job].get(task) target_dict['args'] = [] target_dict['args'].extend(list_args) target_dict['kwargs'] = {'job': job, 'task': task} targets.append(target_dict) # checks if keywords are passed directly to run in parallel elif args: targets = self._resolve_args('run', *args) else: raise TobyException("No arguments passed to run") # Creates threads, waits for thread execution to complete and returns results try: output = run_multiple(targets) except Exception as exp: raise TobyException("Unable to run one or more threads: %s" % exp) # Logs the output of the threads as a list t.log(output) # Raises Exception if any of the threads fail if False in output: raise TobyException("One or more tasks failed during execution") else: return output
def reconnect(self, timeout=30, interval=10, force=True): """ Method called by user to reconnect to Host :param timeout: *OPTIONAL* Time by which device need to reconnect. Default is 30 seconds :param interval: *OPTIONAL* Interval at which reconnect need to be attempted. Default is 10 seconds :return: True if device reconnection is successful. In all other cases Exception is raised """ if force is True: try: oldprompt = self.prompt self.prompt = '\$' if 'proxy_host' not in self._kwargs and 'proxy_hosts' not in self._kwargs: self.log(level='INFO', message="Now checking %s's %s server.." % (self.host, self.connect_mode)) if check_socket(host=self.host, socket_type=self.connect_mode, timeout=timeout, interval=interval): self.log( level='INFO', message='Successfully created %s socket to %s' % (self.connect_mode, self.host)) else: raise TobyException( 'Failed to create %s socket to %s' % (self.host, self.connect_mode), host_obj=self) if self.connect_mode == 'ssh': if self.handle.client.get_transport().isAlive(): self.handle.client.close() self.handle = _connect_unix(self._kwargs) self.set_prompt(oldprompt) except: raise TobyException("Error reconnecting to Device", host_obj=self) return True else: try: if self.handle.client.get_transport().isAlive(): self.log(level='INFO', message='Unix channel is alive') return True except: pass
def check_version(device=None, version=None, operator='ge', all=False): """ Utility to check Minimum Junos Version required to run a Testcase. :device: *MANDATORY* device handle for the currently executing device :version: *MANDATORY* Minimum JUNOS version required :operator: *OPTIONAL* Condition for version comparision. Currently supporting 1. greater than or equal(ge) 2. equal(eq) :all: *OPTIONAL* Valid only if the device is of Junos. When set to True, all JUNOS REs will be checked for Version match. """ input_condition = ['ge', 'eq'] result = False if all: if operator in input_condition: for node in device.nodes.keys(): for controller_name in device.nodes[node].controllers.keys(): device_version = re.match(r"^\d+\.\d+.*", \ device.nodes[node].controllers[controller_name].get_version(refresh=True)) if operator == 'ge': result = device_version.group() >= version if not result: device.log(level="WARN", \ message="Version check failed on: %s" % controller_name) break else: device.log(level="INFO", \ message="Version check passed on: %s" % controller_name) else: result = device_version.group() == version if not result: break return result else: raise TobyException("Invalid Condition provided. Supported values" \ + str(input_condition)) else: device_version = re.match(r"^\d+\.\d+.*", device.get_version(refresh=True)) if operator in input_condition: if operator == 'ge': if device_version.group() >= version: result = True else: if device_version.group() == version: result = True return result else: raise TobyException("Invalid Condition provided. Supported values" +str(input_condition))
def reconnect(self, timeout=30, interval=10): """ Method called by user to reconnect to Host :param timeout: *OPTIONAL* Time by which device need to reconnect. Default is 30 seconds :param interval: *OPTIONAL* Interval at which reconnect need to be attempted. Default is 10 seconds :return: True if device reconnection is successful. In all other cases Exception is raised """ try: self.log(level='INFO', message="Now checking %s's %s server.." % (self.host, self.connect_mode)) if check_socket(host=self.host, socket_type=self.connect_mode, timeout=timeout, interval=interval): self.log(level='DEBUG', message='Successfully created %s socket to %s' % (self.connect_mode, self.host)) else: raise TobyException('Failed to create %s socket to %s' % (self.host, self.connect_mode), host_obj=self) if self.connect_mode == 'ssh': if self.handle.client.get_transport().isAlive(): self.handle.client.close() self.handle = SshConn(host=self.host, user=self.user, password=self.password, port=22, initialize_command='cd') else: self.handle = TelnetConn(host=self.host, user=self.user, password=self.password) if self.port == 23: self.prompt = 'Toby-%s-%s' % (os.getpid(), self.host) self.prompt += '%' self.set_shell_prompt(prompt=self.prompt) else: self.prompt = '>\s?' except: raise TobyException("Error reconnecting to Device", host_obj=self) return True
def close(self): """ Device object destroyer """ self.disconnect() try: del self except NameError as Exception: raise TobyException("self not defined for deleting") except: raise TobyException("Unable to destroy Unix object") return True
def check_interface_status(device, interface=None): """ Checks interface status is in up or not. :param interface: *REQUIRED* Interface name :returns: Dictionary of interface name with True/False If the interface status as up then dictionary stores with True If the interface status as down then dictionary stores with False """ if not interface: device.log(level='DEBUG', message='No interface specified') raise TobyException("No interface specified") status_all = {} if not isinstance(interface, list): interface = [interface] for intf in interface: response = device.cli(command="show interface %s" % intf).response() search = re.search( r'(?:invalid|incomplete|command)\s+(?:input|command|failed)', response, re.I) if not response or search: device.log(level="DEBUG", message="Error while executing show interface command") raise TobyException("Error while executing the show interface command") else: output = response.split('\n') search1 = re.search(r'\S+\s+is\s+([^,]+),.*\s+is\s+(.*?)\s*$', output[0], re.I) info_all = {} info_all[intf] = {} if search1: admin_status = search1.group(1) oper_status = search1.group(2) else: admin_status = '' oper_status = '' info_all[intf]['admin-status'] = admin_status info_all[intf]['oper-status'] = oper_status search_operstatus = re.search(r'up\s*$', info_all[intf]['oper-status'], re.I) if search_operstatus: status_all[intf] = {} status_all[intf]['oper-status'] = True else: status_all[intf] = {} status_all[intf]['oper-status'] = False device.log(level='INFO', message='for the interface ' '%s the protocol status is not in up' % intf) return status_all
def get_interface_address(self, interface=None, interface_type=None, family=None): """ Get interface address from the router :param interface: *REQUIRED* name of the interface to get the address :param interface_type: *OPTIONAL* type of interface ex: link-local :param family: *OPTIONAL* interface belongs to which family ex:6, 4 :return: IP address of the interface with subnetmask """ if not interface: raise TobyException("Please specify the interface", host_obj=self) if family and str(family) == '6': family = 'ipv6' else: family = 'ip' response = self.cli( command="show %s interface %s" % (family, interface)).response() search_error = re.search( r'(?:invalid|incomplete)\s+(?:input|command)', response, re.I) if not response or search_error: raise TobyException("Error in executing the show interface command", host_obj=self) output = response.split('\n') interface_address = "" if family == 'ipv6': if re.search('link-local', interface_type, re.I): for line in output: search = re.search(r'link-local address is (\S*)', line, re.I) if search: interface_address = search.group(1) else: for line in range(0, len(output)): search = re.search('Global unicast address.*$', output[line], re.I) if search: search1 = re.search(r'(\S*), subnet is [^/]+(/\d+)', output[line + 1], re.I) if search1: interface_address = \ search1.group(1) + search1.group(2) else: for line in output: search = re.search(r'Internet address is (\S*)', line, re.I) if search: interface_address = search.group(1) return interface_address
def kill_process(self, pid=None, signal=None): """ Uses to kill the process :param pid: *REQUIRED* Process ID to kill :param signal: *OPTIONAL* Kill process signal :returns Response - if the kill process is success False - If the kill process if failes """ if not pid: raise TobyException("Please specify the pid", host_obj=self) if not signal: signal = 9 response = self.cli( command='kill -%s %s' % (pid, signal)).response() if response: self.log(level='INFO', message='Kill the %s process ID' % pid) return response else: self.log(level="DEBUG", message="Unable to kill the process ID") return False
def _set_current_node(self, set_node=None): if set_node is not None: self.current_node = self.nodes[set_node.lower()] elif len(self.nodes.keys()) == 1: self.current_node = self.nodes[list(self.nodes.keys())[0]] else: for node in self.nodes: try: if self.nodes[node].is_node_master(): self.current_node = self.nodes[node] break except Exception: pass if self.current_node is None: for node in self.nodes: try: if not self.nodes[node].is_node_master(): t.log( level="INFO", message= "Since could not find active node, setting " + node + " as active node") self.current_node = self.nodes[node] break except Exception: pass if self.current_node is None: raise TobyException( 'Error : Could not set current node for the system')
def get_model(self): """ Returns model of the device """ version = self.handle.rpc.get_software_information() multi_re = version.findall('multi-routing-engine-item') if len(multi_re) > 0: model = multi_re[0].find('software-information/product-model').text if re.search(r'MX\d+', model, re.I): return 'MX' elif re.search(r'VSRX', model, re.I): return 'VSRX' elif re.search(r'SRX\d+', model, re.I): return 'SRX' elif re.search(r'ex\d+', model, re.I): return 'EX' elif re.search(r'qfx\d+', model, re.I): return 'QFX' elif re.search(r'ocx\d+', model, re.I): return 'OCX' elif re.search(r'nfx\d+', model, re.I): return 'NFX' try: model = version.find('product-model').text except: raise TobyException('Could not retrieve model') return model
def _connect(self): # Default connect_mode to ssh connect_mode = self._kwargs.get('connect_mode', 'ssh').lower() # Check for valid connect modes if connect_mode not in ('telnet', 'ssh', 'console', 'netconf'): raise TobyException( 'Invalid connect mode({0}) specified. Connect mode can be ' 'telnet/ssh/console/netconf'.format(connect_mode)) handle = None try: user, password = self._get_credentials() device_args = { 'host': self._kwargs['host'], 'user': user, 'passwd': password, 'gather_facts': False } if connect_mode == 'ssh': device_args['port'] = 22 if connect_mode == 'telnet' or connect_mode == 'console': device_args['mode'] = 'telnet' if self._kwargs['pyez_port'] is not None: device_args['port'] = int(self._kwargs['pyez_port']) handle = Pyez_Device(**device_args) handle.open() except Exception as exp: logging.error('Could not connect to device ' + self._kwargs['host'] + ':' + str(exp)) return handle
def __delete_service_selenium(self): try: self.shell(command="nssm stop selenium_toby") self.shell(command="nssm remove selenium_toby confirm") return True except Exception as exp: raise TobyException("unable to delete service", host_obj=self)
def add_channel(self, channel_type, controller='current', channel_attributes=None): """ Add new Channel to Channel Object :param channel_type: *MANDATORY* Type to channel to create , currently supports snmp, grpc only :param controller: *OPTIONAL* Controller to create the channel :param channel_attributes: *OPTIONAL* Arguments required for creating the channel :return: 1-D dictionary of channel ID per controller """ controller = controller.lower() channel_dict = dict() if controller == 'current': current_controller = self.current_controller_str return_dict = self.current_controller.add_channel( channel_type, channel_attributes) channel_dict[current_controller] = return_dict channel_dict['current_controller'] = return_dict elif controller == 'all': for controller_to_call in self.controllers.keys(): channel_dict[controller_to_call] = self.controllers[ controller_to_call].add_channel(channel_type, channel_attributes) elif controller in self.controllers.keys(): channel_dict[controller] = self.controllers[ controller].add_channel(channel_type, channel_attributes) else: raise TobyException("Controller %s does not exist for the device" % controller) return channel_dict
def invoke(self, function, **args): """ Pass-through for av.py functions """ if 'port_handle' in args.keys(): port_handle = args['port_handle'] if isinstance(port_handle, six.string_types): port_handle = port_handle.split(' ') if port_handle[0] in self.intf_to_port_map.keys(): new_port_handle = list() for intf in port_handle: new_port_handle.append( self.port_to_handle_map[self.intf_to_port_map[intf]]) args['port_handle'] = ' '.join(new_port_handle) avalanche_func = getattr(self.av, function) self.log("Invoking Avalanche API " + function + " with the following parameters: " + str(args)) result = avalanche_func(**args) self.log("Invocation of Avalanche method " + function + " executed resulting in: " + str(result)) if function != 'invoke': if not result: raise TobyException("Invocation of Avalanche method " + function + " failed with result: " + str(result), host_obj=self) self.log("Invocation of Avalanche method " + function + " succeeded") return result
def is_node_status_primary(self): """ Module to check if node status is primary :return: return true if the current node is primary else false """ sccs = self.current_controller.cli( command="show chassis cluster status redundancy-group 0", format="xml").response() match = re.match(r"(<rpc-reply.*>)([\s\S]*)(<cli>[\s\S]*</rpc-reply>)", sccs) sccs = match.group(2) # will only get the XML response of the command try: root = etree.fromstring(sccs) status = jxmlease.parse_etree(root) status = status['chassis-cluster-status']['redundancy-group'][ 'device-stats'] except: raise TobyException('Chassis cluster is not enabled') node = self.node_name() if node == 'node0' and status['redundancy-group-status'][ 0] == 'primary': return True elif node == 'node1' and status['redundancy-group-status'][ 1] == 'primary': return True return False
def upload_file(dev, *args, **kwargs): """ Transfers file from local execution server/machine to host ARGUMENTS: :param STR local_file: *MANDATORY* Full path along with filename which has to be copied to the host. This could be a string or list of files :param STR remote_file: *MANDATORY* File to create on the router :param STR protocol: *OPTIONAL* Transfer protocol that needs to be used. Acceptable values are ftp , scp or None. In case of None, scp is used if the device is connected via ssh else ftp is used :param STR user: *OPTIONAL* Username to be used to transfer the file. If not provided username from device object is taken :param STR password: *OPTIONAL* Password to be used to transfer the file. If not provided password from device object is taken :param INT timeout: *OPTIONAL* maximum time to upload file to a device. Default is set To 30 ROBOT USAGE: ${device-handle} = Get Handle resource=r1 Upload File local_file=/var/temp/iiaka.py remote_file=/tmp/value/ ... user=root password=xuma timeout=${202} protocal=scp returns:True if the file transfer is successful, else Exception is raised """ result = dev.upload(*args, **kwargs) if not result: raise TobyException('Upload file failed') return result
def _switch_mode(self, mode='privileged'): """ This function is used to switch from one mode another mode. ex: user to privileged/ privileged to config param mode: It takes the mode as input argument. The mode which you to switch """ curr_mode = self.mode.lower() mode = mode.lower() if mode == curr_mode: return_value = True return return_value try: if mode == 'user': self._switch_mode(mode='privileged') self.execute(command="disable", pattern='>$') elif mode == 'privileged': if curr_mode == 'user': self.enable() if curr_mode == 'config': self.execute(command="end", pattern='#$') elif mode == 'config': self._switch_mode(mode='privileged') self.execute(command="configure terminal", pattern=r'.*\(config\)#$') except Exception: raise TobyException('Cannot switch to ' + mode + ' mode.', host_obj=self) return_value = True self.mode = mode return return_value
def invoke(self, method, **args): """ Pass-through for Warp17.py methods """ if 'port_handle' in args.keys(): port_handle = args['port_handle'] if isinstance(port_handle, six.string_types): port_handle = port_handle.split(' ') if port_handle[0] in self.intf_to_port_map.keys(): new_port_handle = list() for intf in port_handle: new_port_handle.append( self.port_to_handle_map[self.intf_to_port_map[intf]]) args['port_handle'] = ' '.join(new_port_handle) warp17_func = getattr(self.warp17, method) self.log("Invoking Warp17 API " + method + " with the following parameters: " + str(args)) result = warp17_func(**args) self.log("Invocation of Warp17 method " + method + " executed resulting in: " + str(result)) if not result: raise TobyException("Invocation of Warp17 method " + method + " failed with result: " + str(result), host_obj=self) self.log("Invocation of Warp17 method " + method + " succeeded") return result
def node_name(self): """ Get name of the chassis in the cluster :return: name of the chassis in the cluster ("node0"/"node1"). """ # Execute show version on the connected device sccs = self.current_controller.cli(command="show version", format="xml").response() match = re.match(r"(<rpc-reply.*>)([\s\S]*)(<cli>[\s\S]*</rpc-reply>)", sccs) sccs = match.group(2) # will only get the XML response of the command # Get RG stats try: root = etree.fromstring(sccs) status = jxmlease.parse_etree(root) host_name = self.current_controller.shell( command='hostname').response() node0_name = status['multi-routing-engine-results'][ 'multi-routing-engine-item'][0]['software-information'][ 'host-name'] node1_name = status['multi-routing-engine-results'][ 'multi-routing-engine-item'][1]['software-information'][ 'host-name'] if str(node0_name).lower() == str(host_name).lower(): return "node0" elif str(node1_name).lower() == str(host_name).lower(): return "node1" except: self.current_controller.log( level='ERROR', message='Chassis cluster is not enabled') raise TobyException("Chassis cluster is not enabled")