Example #1
0
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")
Example #2
0
    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
Example #3
0
    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
Example #4
0
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')
Example #5
0
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()