Esempio n. 1
0
    def cb_action(self, uinfo, name, kp, input, output):
        self.log.info('Action: {}'.format(name))
        action_set_timeout(uinfo, 240)

        try:
            service_call = service_handler(
                input.service_name,
                ServiceArgs(input.service_name, input.operation_id), self.log)

            result = service_call(uinfo)

        except Exception as e:
            self.log.error('Error in {}: {}'.format(name, e))
            output.failure = "An error occurred: {}".format(e)
        else:
            action_output = ["Service call completed successfully"]
            if result is not None:
                action_output.append(":\n{}".format(result))

            output.success = "".join(action_output)
Esempio n. 2
0
    def cb_action(self, uinfo, name, kp, input, output):
        self.log.info("Action {}".format(name))
        action_set_timeout(uinfo, 240)

        try:
            # Run assessment
            results = None
            with ncs.maapi.single_read_trans(uinfo.username,
                                             "system") as read_t:
                root = ncs.maagic.get_root(read_t)
                # kp sample: /ncs:services/snap:health-samples/device{IOS-0}
                kp_node = ncs.maagic.cd(root, kp)

                assessment_name = kp_node.snap__lightweight_assessment

                if assessment_name is None:
                    raise AssessmentError(
                        "No lightweight assessment defined for {}".format(
                            kp_node.snap__name))

                results = run_assessment(
                    root.devices.device[kp_node.snap__name],
                    root.ncs__services.snap__health_samples.snap__setup.
                    snap__stop_on_error, root.ncs__services.
                    snap__health_samples.snap__assessment[assessment_name],
                    self.log)

            # Figure out the outcome
            assessment_outcome = all(map(attrgetter('passed'), results))
            if assessment_outcome:
                output.success = "Assessment completed without errors"
            else:
                failed_cmds = ', '.join([
                    str(seq) for seq, result, passed in results if not passed
                ])
                output.failure = "Assessment completed with errors. Commands that failed: {}".format(
                    failed_cmds)

        except AssessmentError as e:
            output.failure = "Assessment error: {}".format(e)
            self.log.info("Lightweight assessment error: {}".format(e))
Esempio n. 3
0
    def cb_action(self, uinfo, name, kp, input, output):
        self.log.info("Action {}".format(name))
        action_set_timeout(uinfo, 240)

        try:
            # Run assessment
            with ncs.maapi.single_read_trans(uinfo.username,
                                             "system") as read_t:
                root = ncs.maagic.get_root(read_t)
                # kp sample: /ncs:services/snap:health-samples/device{IOS-0}
                kp_node = ncs.maagic.cd(root, kp)

                assessment_name = kp_node.snap__assessment

                results = run_assessment(
                    root.devices.device[kp_node.snap__name],
                    root.ncs__services.snap__health_samples.snap__setup.
                    snap__stop_on_error, root.ncs__services.
                    snap__health_samples.snap__assessment[assessment_name],
                    self.log)

            # Save assessment sample
            with ncs.maapi.single_write_trans(uinfo.username,
                                              "system",
                                              db=ncs.OPERATIONAL) as write_t:
                root = ncs.maagic.get_root(write_t)
                kp_node = ncs.maagic.cd(root, kp)

                # Create a new sample
                timestamp = int(time())
                new_sample = kp_node.snap__sample.create(timestamp)

                for seq, result, passed in results:
                    new_cmd = new_sample.snap__command.create(seq)
                    new_cmd.snap__output = result
                    new_cmd.snap__passed = passed

                # Trim old samples
                key_list = [
                    sample_entry.timestamp
                    for sample_entry in kp_node.snap__sample
                ]
                items_to_trim = len(
                    key_list
                ) - root.ncs__services.snap__health_samples.snap__setup.snap__max_samples
                if items_to_trim > 0:
                    for old_key in islice(sorted(key_list), items_to_trim):
                        del kp_node.snap__sample[old_key]
                    self.log.info('Trimmed {} sample(s)'.format(items_to_trim))

                write_t.apply()
                self.log.info("Saved assessment: {}, timestamp: {}".format(
                    kp_node.snap__name, timestamp))

            # Figure out the outcome
            assessment_outcome = all(map(attrgetter('passed'), results))
            if assessment_outcome:
                output.success = "Assessment completed without errors"
            else:
                failed_cmds = ', '.join([
                    str(seq) for seq, result, passed in results if not passed
                ])
                output.failure = "Assessment completed with errors. Commands that failed: {}".format(
                    failed_cmds)

        except AssessmentError as e:
            output.failure = "Assessment error: {}".format(e)
            self.log.info("Assessment error: {}".format(e))
Esempio n. 4
0
    def cb_action(self, uinfo, name, kp, input, output):
        def sample_cmds(sample_node):
            """
            Return commands in a sample as a generator
            :param sample_node: maagic node representing a sample instance
            :return: list of (seq, output, passed) tuples
            """
            return (
                (cmd.seq, cmd.output, cmd.passed)
                for cmd in sorted(sample_node.command, key=attrgetter('seq')))

        self.log.info("Action {}".format(name))
        action_set_timeout(uinfo, 240)

        with ncs.maapi.single_read_trans(uinfo.username, "system") as read_t:
            root = ncs.maagic.get_root(read_t)
            # kp: /ncs:services/snap:health-samples/device{IOS-0}
            kp_node = ncs.maagic.cd(root, kp)

            ts_list = sorted([
                sample_entry.timestamp for sample_entry in kp_node.snap__sample
            ])

            try:
                if len(ts_list) < 2:
                    raise DiffFailed("Not enough samples to complete")

                assessment = root.ncs__services.snap__health_samples.snap__assessment[
                    kp_node.snap__assessment]
                parse_dict = {
                    cmd.seq: cmd.parse
                    for cmd in assessment.snap__command
                }

                last_ts, prev_ts = ts_list[-1], ts_list[-2]
                self.log.info("{}: comparing {} and {} samples".format(
                    kp_node.snap__name, last_ts, prev_ts))

                # Iterate over commands from the last 2 samples
                zipped_cmds = zip(sample_cmds(kp_node.snap__sample[last_ts]),
                                  sample_cmds(kp_node.snap__sample[prev_ts]))
                for (last_seq, last_output,
                     last_passed), (prev_seq, prev_output,
                                    prev_passed) in zipped_cmds:
                    if last_seq != prev_seq:
                        raise DiffFailed(
                            "Command sequence number mismatch: last: {}, prev: {}"
                            .format(last_seq, prev_seq))
                    if not last_passed:
                        raise DiffFailed(
                            "Last assessment failed: {}".format(last_ts))
                    if not prev_passed:
                        raise DiffFailed(
                            "Previous assessment failed: {}".format(prev_ts))

                    cmd_run = assessment.snap__command[last_seq].snap__run
                    self.log.info("Comparing '{}' ({}) output".format(
                        cmd_run, last_seq))

                    last_tokens = cmd_parse(last_output, parse_dict[last_seq])
                    prev_tokens = cmd_parse(prev_output, parse_dict[prev_seq])
                    if len(last_tokens) != len(prev_tokens):
                        raise DiffFailed(
                            "Different number of matches across samples from '{}' ({})"
                            .format(cmd_run, last_seq))

                    token_match = [(token_last == token_prev)
                                   for token_last, token_prev in zip(
                                       last_tokens, prev_tokens)]
                    if not all(token_match):
                        raise DiffFailed(
                            "Output from '{}' ({}) changed".format(
                                cmd_run, last_seq))

                output.success = "Diff passed"
                self.log.info("Diff assessment passed")

            except DiffFailed as e:
                output.failure = "Diff failed: {}".format(e)
                self.log.info("Diff assessment failed: {}".format(e))
Esempio n. 5
0
 def extend_timeout(self, timeout_extension):
     dp.action_set_timeout(self.uinfo, timeout_extension)
Esempio n. 6
0
 def extend_timeout(self) -> None:
     '''Tell NSO to wait a bit longer.  See also `TIMEOUT_MARGIN`.
     '''
     extension = self.device_timeout + 2 * TIMEOUT_MARGIN
     dp.action_set_timeout(self.uinfo, extension)