def save_bootvar(self, testbed): """Check boot information and save bootvar to startup-config Args: testbed (`obj`): Testbed object Returns: None Raises: pyATS Results """ # Create Summary summary = Summary(title='Summary', width=90) devices = [] for dev in self.parent.mapping_data['devices']: device = testbed.devices[dev] if device.type in EXCLUDED_DEVICE_TYPES: msg = " - This subsection is not supported for 'TGN' devices" summarize(summary, message=msg, device=dev) continue devices.append(device) device_dict = {} failed = False # We don't catch exceptions since failures will lead to passx in that # CommonSetup subsection asynchronous_boot_var_output = pcall(asynchronous_save_boot_variable, ckwargs={ 'self': self, 'device_dict': device_dict }, device=tuple(devices)) for item in asynchronous_boot_var_output: for dev, res in item.items(): if res == 'Failed': failed = True msg = " - Failed to save boot variable or copy "\ "running-config to startup-config" summarize(summary, message=msg, device=dev) elif res == 'Skipped': msg = " - Skipped saving boot variable or copy "\ "running-config to startup-config" summarize(summary, message=msg, device=dev) else: msg = " - Successfully saved boot variable" summarize(summary, message=msg, device=dev) summary.print() if failed: self.passx("Issue while saving boot variable on one of the devices, " "Check section summary for more details")
def is_global_ver_enabled(self): '''To check if global verifications need to be udpated.''' # create summary instnace for Global verification self.global_summary = Summary(title='Global Verifications', width=150) if not self.obj.parent.verifications: self.global_summary.add_message('* No verifications imported') self.global_summary.add_subtitle_line() log.info('No verifications imported') return False if hasattr('self.obj.parent', 'verf'): if not self.obj.parent.verf: self.global_summary.add_message( '* No global verifications executed') self.global_summary.add_subtitle_line() log.info('No global verifications executed') return False if not self.update_ver_list: self.global_summary.add_message( '* No verifications defined to be updated') self.global_summary.add_subtitle_line() log.info('No verifications require to be updated') return False for ver in self.update_ver_list: if hasattr('self.obj.parent', 'verf'): if self.device.name in self.obj.parent.verf and \ self.obj.parent.verf[self.device.name] and \ ver in self.obj.parent.verf[self.device.name]: return True # add seperate line self.global_summary.add_sep_line() # compose the summary message self.global_summary.add_message('* Skipped Update\n') msgs = '' for ver in self.update_ver_list: msgs += '%s: Not learned before on device %s\n' % \ (self.global_summary.add_indent(ver), self.device.name) self.global_summary.add_message(msgs) self.global_summary.add_subtitle_line() log.info( 'Required Global verification "{v}" is ' 'not learned before on device {d}, Skip updating global'.format( v=self.update_ver_list, d=self.device.name)) return False
def is_pts_enabled(self): '''To check if PTS need to be udpated.''' # create summary instnace for PTS self.pts_summary = Summary(title='PTS', width=150) if 'pts' not in self.obj.parent.parameters: self.pts_summary.add_message('* No PTS executed') log.info('No PTS executed') self.pts_summary.add_subtitle_line() return False if not self.update_feature_list: self.pts_summary.add_message( '* No PTS features require to be updated') self.pts_summary.add_subtitle_line() log.info('No PTS features require to be updated') return False for feature in self.update_feature_list: if feature in self.obj.parent.parameters['pts']: return True # add seperate line self.pts_summary.add_sep_line() # compose the summary message self.pts_summary.add_message('* Skipped Update') msgs = '' for fe in self.update_feature_list: msgs += '%s: Not learned before on device %s\n' % \ (self.pts_summary.add_indent(fe), self.device.name) self.pts_summary.add_message(msgs) self.pts_summary.add_subtitle_line() log.info('Required features "{v}" is ' 'not learned before on device {d}, Skip updating PTS'.format( v=self.update_feature_list, d=self.device.name)) return False
def learn_system_defaults(self, testbed): """Execute commands to learn default system information Args: testbed (`obj`): Testbed object Returns: None Raises: pyATS Results """ # Get default memory location self.parent.default_file_system = {} # Create Summary summary = Summary(title='Summary', width=150) for device in self.parent.mapping_data['devices']: dev = testbed.devices[device] lookup = Lookup.from_device(dev) # Skip in case of TGN device if dev.type in EXCLUDED_DEVICE_TYPES: log.info("This subsection is not supported for " "TGN device '{}'".format(dev.name)) msg = " - This subsection is not supported for 'TGN' devices" summarize(summary, message=msg, device=dev.name) continue try: self.parent.default_file_system[dev.name] = lookup.sdk.libs.\ abstracted_libs.subsection.get_default_dir( device=dev) msg = " - Successfully learnt system default directroy" summarize(summary, message=msg, device=device) except LookupError as e: log.info('Cannot find device {d} correspoding get_default_dir'.\ format(d=dev.name)) msg = " - Didn't find device OS corresponding "\ "'get_default_dir' implementation, Please contact Genie support" summarize(summary, message=msg, device=device) except Exception as e: msg = " - Failed to learn system default directory" summarize(summary, message=msg, device=device) summary.print() self.failed('Unable to learn system default directory', from_exception=e) summary.print() if not self.parent.default_file_system: # Create Summary summary = Summary(title='Summary', width=90) summary.add_message("* Summary for device(s): " "{}".format(', '.join(self.parent.mapping_data['devices']))) summary.add_sep_line() msg = " - Couldn't set system default directory" summarize(summary, message=msg) summary.print() self.failed('Unable to set system default directory')
class UpdateLearntDatabase(object): """Class to update local/global verifications and PTS""" def __init__(self, obj, device, update_ver_list=None, update_feature_list=None): """built-in __init__ instantiates each update actions. Arguments --------- device (`obj`): Device object obj (`obj`): Genie Trigger Object update_ver_list (`list`): List of verifications names update_feature_list(`list`): List of pts features names """ self.device = device self.obj = obj # update verifications list self.update_ver_list = update_ver_list # update pts features list self.update_feature_list = update_feature_list # build up abstract object based on the os of device self.abstract = Lookup.from_device(device) @property def is_local_ver_enabled(self): '''To check if local verifications need to be udpated.''' # create summary instnace for local verification self.local_summary = Summary(title='Local Verifications', width=150) if not self.obj.parent.verifications: self.local_summary.add_message('* No verifications imported') self.local_summary.add_subtitle_line() log.info('No verifications imported') return False if not self.obj.verf: self.local_summary.add_message('* No local verifications executed') self.local_summary.add_subtitle_line() log.info('No local verifications executed') return False if not self.update_ver_list: self.local_summary.add_message( '* No verifications defined to be updated') self.local_summary.add_subtitle_line() log.info('No verifications defined to be updated') return False for ver in self.update_ver_list: if self.obj.verf and self.device.name in self.obj.verf and \ self.obj.verf[self.device.name] and \ ver in self.obj.verf[self.device.name]: return True # add seperate line self.local_summary.add_sep_line() # compose the summary message self.local_summary.add_message('* Skipped Update\n') msgs = '' for ver in self.update_ver_list: msgs += '%s: Not learned before on device %s\n' % \ (self.local_summary.add_indent(ver), self.device.name) self.local_summary.add_message(msgs) self.local_summary.add_subtitle_line() log.info( 'Required Local verification "{v}" is ' 'not learned before on device {d}, Skip updating local'.format( v=self.update_ver_list, d=self.device.name)) return False @property def is_global_ver_enabled(self): '''To check if global verifications need to be udpated.''' # create summary instnace for Global verification self.global_summary = Summary(title='Global Verifications', width=150) if not self.obj.parent.verifications: self.global_summary.add_message('* No verifications imported') self.global_summary.add_subtitle_line() log.info('No verifications imported') return False if not self.obj.parent.verf: self.global_summary.add_message( '* No global verifications executed') self.global_summary.add_subtitle_line() log.info('No global verifications executed') return False if not self.update_ver_list: self.global_summary.add_message( '* No verifications defined to be updated') self.global_summary.add_subtitle_line() log.info('No verifications require to be updated') return False for ver in self.update_ver_list: if self.device.name in self.obj.parent.verf and \ self.obj.parent.verf[self.device.name] and \ ver in self.obj.parent.verf[self.device.name]: return True # add seperate line self.global_summary.add_sep_line() # compose the summary message self.global_summary.add_message('* Skipped Update\n') msgs = '' for ver in self.update_ver_list: msgs += '%s: Not learned before on device %s\n' % \ (self.global_summary.add_indent(ver), self.device.name) self.global_summary.add_message(msgs) self.global_summary.add_subtitle_line() log.info( 'Required Global verification "{v}" is ' 'not learned before on device {d}, Skip updating global'.format( v=self.update_ver_list, d=self.device.name)) return False @property def is_pts_enabled(self): '''To check if PTS need to be udpated.''' # create summary instnace for PTS self.pts_summary = Summary(title='PTS', width=150) if 'pts' not in self.obj.parent.parameters: self.pts_summary.add_message('* No PTS executed') log.info('No PTS executed') self.pts_summary.add_subtitle_line() return False if not self.update_feature_list: self.pts_summary.add_message( '* No PTS features require to be updated') self.pts_summary.add_subtitle_line() log.info('No PTS features require to be updated') return False for feature in self.update_feature_list: if feature in self.obj.parent.parameters['pts']: return True # add seperate line self.pts_summary.add_sep_line() # compose the summary message self.pts_summary.add_message('* Skipped Update') msgs = '' for fe in self.update_feature_list: msgs += '%s: Not learned before on device %s\n' % \ (self.pts_summary.add_indent(fe), self.device.name) self.pts_summary.add_message(msgs) self.pts_summary.add_subtitle_line() log.info('Required features "{v}" is ' 'not learned before on device {d}, Skip updating PTS'.format( v=self.update_feature_list, d=self.device.name)) return False def _get_command_output(self, ver): '''Extract the Verification output. Args: Mandatory: ver (`str`) : verification name. Returns: str: parser output ops object: ops object after learn Raises: Metaparser errors ''' # Check if verificaiton is parser, callable or Ops if 'cmd' in self.obj.parent.verifications[ver]: # compose the command object execute_obj = self.abstract.parser for item in self.obj.parent.verifications[ver]['cmd'][ 'class'].split('.'): execute_obj = getattr(execute_obj, item) execute_obj = execute_obj(self.device) elif 'source' in self.obj.parent.verifications[ver]: # compose the source object execute_obj = self.abstract for item in self.obj.parent.verifications[ver]['source'][ 'class'].split('.'): execute_obj = getattr(execute_obj, item) execute_obj = execute_obj(self.device) # parser update if hasattr(execute_obj, 'parse'): # check if has parameters if 'parameters' in self.obj.parent.verifications[ver]: para = self.obj.parent.verifications[ver]['parameters'] else: para = {} output = execute_obj.parse(**para) return output # Ops update if hasattr(execute_obj, 'learn'): execute_obj.learn() return execute_obj # Callable update # TODO def _update_msg_summary(self, summary, successes, skips): if successes: summary.add_message('* Successfully Updated') for ver in successes: msg = summary.add_indent(ver) summary.add_message(msg) if skips: summary.add_message('* Skipped Update') for ver, msg in skips.items(): msgs = '%s: %s\n' % \ (summary.add_indent(ver), msg) summary.add_message(msgs) def update_verification(self): '''Learn the verifications from the given list and overwrite it into local and global verifications. Args: None Returns: None Raises: None Example: >>> update_obj = UpdateLearntDatabase(object, device, update_ver_list=['Verify_Module', 'Verify_RedundancyStatus']) >>> update_obj.update_verification() ''' # Check if neede to update if not self.is_local_ver_enabled: # no combining the logic is to let it run each function # to initial the summary object if not self.is_global_ver_enabled: return else: # inital the global summary object self.is_global_ver_enabled # Initial lists for updating local/global vers tmp_list_local = [] tmp_list_global = [] # initial for message print skip_dict_local = {} skip_dict_global = {} success_list_local = [] success_list_global = [] # get same commands for local/global to avoid the duplicated show commands for ver in self.update_ver_list: # local verififations if self.obj.verf and self.device.name in self.obj.verf and \ self.obj.verf[self.device.name] and \ ver in self.obj.verf[self.device.name]: tmp_list_local.append(ver) else: skip_dict_local.update({ ver: 'Not learned before on device %s' % self.device.name }) # global verififations if self.device.name in self.obj.parent.verf and \ self.obj.parent.verf[self.device.name] and \ ver in self.obj.parent.verf[self.device.name]: tmp_list_global.append(ver) else: skip_dict_global.update({ ver: 'Not learned before on device %s' % self.device.name }) # get same list same_list = list(set(tmp_list_local).intersection(tmp_list_global)) # get diff list [tmp_list_local.remove(i) for i in same_list] [tmp_list_global.remove(i) for i in same_list] # update same commands for local and global for ver in same_list: try: output = self._get_command_output(ver) except Exception as e: skip_dict_local.update({ver: '%s' % e.__class__.__name__}) skip_dict_global.update({ver: '%s' % e.__class__.__name__}) # ignore when the output is empty log.warning( 'Local verification "{}" cannot be updated'.format(ver)) log.warning(str(e)) continue else: success_list_local.append(ver) success_list_global.append(ver) if isinstance(output, dict): self.obj.verf[self.device.name][ver].name = output self.obj.parent.verf[self.device.name][ver].name = output elif isinstance(output, object): self.obj.verf[self.device.name][ver] = output self.obj.parent.verf[self.device.name][ver] = output # update local specific for ver in tmp_list_local: try: output = self._get_command_output(ver) except Exception as e: skip_dict_local.update({ver: '%s' % e.__class__.__name__}) # ignore when the output is empty log.warning( 'Local verification "{}" cannot be updated'.format(ver)) log.warning(str(e)) continue else: success_list_local.append(ver) if isinstance(output, dict): self.obj.verf[self.device.name][ver].name = output elif isinstance(output, object): self.obj.verf[self.device.name][ver] = output # update global specific for ver in tmp_list_global: try: output = self._get_command_output(ver) except Exception as e: skip_dict_global.update({ver: '%s' % e.__class__.__name__}) # ignore when the output is empty log.warning( 'Global verification "{}" cannot be updated'.format(ver)) log.warning(str(e)) continue else: success_list_global.append(ver) if isinstance(output, dict): self.obj.parent.verf[self.device.name][ver].name = output elif isinstance(output, object): self.obj.parent.verf[self.device.name][ver] = output # print out messages # - LOCAL self._update_msg_summary(self.local_summary, success_list_local, skip_dict_local) # - Global self._update_msg_summary(self.global_summary, success_list_global, skip_dict_global) def update_pts(self, update_attributes=None): '''Learn the PTS from the given list and overwrite it. Args: Mandatory: Optional: update_attributes (`dict`) : Attributes from the PTSs that want to be updatd, should be {'feature': ['key1_path', 'key2_path']}. Default: None (will update the whole PTS) Returns: None Raises: None Example: >>> update_obj = UpdateLearntDatabase(object, device, update_feature_list=['platform', 'bgp']) >>> update_obj.update_verification( update_attributes={'bgp': ['info'], 'platform': ['chassis_sn', 'slot']}) ''' if not self.is_pts_enabled: return # initial skip list for pring message skip_dict_pts = {} success_list_pts = [] # update pts for feature in self.update_feature_list: log.info("Update {f} pts on {d}".format(f=feature, d=self.device)) # check if pts runs on this device before if self.device.alias in self.obj.parent.parameters['pts'][feature]: # learn the ops again try: module = self.obj.parent.parameters['pts'][feature][self.device.alias]\ .__class__(self.device) module.learn() except Exception as e: skip_dict_pts.update({feature: e.__class__.__name__}) log.warning( 'Feature {} cannot be learned, Skip updating'.format( feature)) log.warning(str(e)) continue # update the given keys for attr in update_attributes[feature]: try: setattr( self.obj.parent.parameters['pts'][feature] [self.device.alias], attr, (getattr(module, attr))) except Exception as e: skip_dict_pts.update({feature: e.__class__.__name__}) success_list_pts.append(feature) else: skip_dict_pts.update({ feature: 'Feature {f} was not learned on {d} before, Skip updating'. format(f=feature, d=self.device) }) log.warning( 'Feature {f} was not learned on {d} before, Skip updating'. format(f=feature, d=self.device)) # print out messages # - PTS self._update_msg_summary(self.pts_summary, success_list_pts, skip_dict_pts) self.pts_summary.add_subtitle_line()