Exemplo n.º 1
0
def aggregate_node_details(
    node_name: str,
    node_check_returns: CheckResult,
) -> Tuple[State, Optional[str]]:
    """Aggregate the results of a node check

    The results of the check on the node are aggregated.
    The state is the worst of all individual states (as checkmk would
    compute it for the service on the node).

    If no results for the nodes are available, an OK state and None is returned.

    Example:
        To yield the summary results of every node of a cluster from within a
        cluster_check_function use

            for node_name, node_section in sections.values():
                node_state, node_text = aggregate_node_details(
                    node_name,
                    check_my_plugin(item, node_section),
                )
                if node_text is not None:
                    yield Result(state=node_state, notice=node_text)

        Note that this example will send text to the services summary only if the
        state is not OK, otherwise to the details page.

    Args:
        node_name: The name of the node
        node_check_returns: The return values or generator of the nodes check_function call

    Returns:
        Aggregated node result. None if the node check returned nothing.

    """

    # drop Metrics, we may be evaluating a generator
    try:
        returns_wo_metrics = [
            r for r in node_check_returns if not isinstance(r, Metric)
        ]
    except IgnoreResultsError:
        return State.OK, None

    results = [r for r in returns_wo_metrics if isinstance(r, Result)]
    if not results or len(results) != len(
            returns_wo_metrics):  # latter: encountered IgnoreResults
        return State.OK, None

    details_with_markers = [
        "%s%s" % (r.details.strip(), state_markers[int(r.state)])
        for r in results
    ]

    return (
        State.worst(*(r.state for r in results)),
        '\n'.join("[%s]: %s" % (node_name, line)
                  for detail in details_with_markers
                  for line in detail.split('\n')),
    )
Exemplo n.º 2
0
def _create_new_result(
    is_details: bool,
    legacy_state: int,
    legacy_text: str,
    legacy_metrics: Union[Tuple, List] = (),
) -> Generator[Union[Metric, Result], None, bool]:

    if legacy_state or legacy_text:  # skip "Null"-Result
        # Bypass the validation of the Result class:
        # Legacy plugins may relie on the fact that once a newline
        # as been in the output, *all* following ouput is sent to
        # the details. That means we have to create Results with
        # details only, which is prohibited by the original Result
        # class.
        yield Result(state=State(legacy_state), summary="Fake")._replace(
            summary="" if is_details else legacy_text.split("\n", 1)[0],
            details=legacy_text.strip(),
        )

    for metric in legacy_metrics:
        if len(metric) < 2:
            continue
        name = str(metric[0])
        value = _get_float(metric[1])
        if value is None:  # skip bogus metrics
            continue
        # fill up with None:
        warn, crit, min_, max_ = (
            _get_float(v)
            for v, _ in itertools.zip_longest(metric[2:], range(4)))
        yield Metric(name, value, levels=(warn, crit), boundaries=(min_, max_))

    return ("\n" in legacy_text) or is_details
Exemplo n.º 3
0
    def _get_selected_nodes(
        results_map: Mapping[str, Sequence[Result]],
        selector: Selector,
    ) -> Set[str]:
        """Determine the best/worst nodes names"""
        nodes_by_states = defaultdict(set)
        for node, results in ((n, r) for n, r in results_map.items() if r):
            nodes_by_states[State.worst(*(r.state for r in results))].add(node)

        return nodes_by_states[selector(*nodes_by_states)] if nodes_by_states else set(results_map)
Exemplo n.º 4
0
def _simple_check(section: Iterable[int]) -> CheckResult:
    """just a simple way to create test check results"""
    for value in section:
        try:
            yield Result(state=State(value), summary="Hi")
        except ValueError:
            if value == -1:
                yield IgnoreResults("yielded")
            elif value == -2:
                raise IgnoreResultsError("raised")
            else:
                yield Metric("n", value)
Exemplo n.º 5
0
def test_state():
    assert int(state.OK) == 0
    assert int(state.WARN) == 1
    assert int(state.CRIT) == 2
    assert int(state.UNKNOWN) == 3

    assert state.worst(state.WARN, state.UNKNOWN, state.CRIT) is state.CRIT
    assert state.worst(state.OK, state.WARN, state.UNKNOWN) is state.UNKNOWN
    assert state.worst(state.OK, state.WARN) is state.WARN
    assert state.worst(state.OK) is state.OK
    assert state.worst(state.OK, 3) is state.UNKNOWN

    assert state(0) is state.OK
    assert state(1) is state.WARN
    assert state(2) is state.CRIT
    assert state(3) is state.UNKNOWN

    assert state["OK"] is state.OK
    assert state["WARN"] is state.WARN
    assert state["CRIT"] is state.CRIT
    assert state["UNKNOWN"] is state.UNKNOWN

    with pytest.raises(TypeError):
        _ = state.OK < state.WARN  # type: ignore[operator]
Exemplo n.º 6
0
 def _secondary_nodes_state(
     secondary_nodes: Sequence[str],
     levels: Tuple[float, float],
 ) -> State:
     count = len(secondary_nodes)
     return State.CRIT if count >= levels[1] else State(count >= levels[0])
Exemplo n.º 7
0
def _is_ok(*elements: Union[Result, Metric, IgnoreResults]) -> bool:
    return State.worst(*(r.state for r in elements
                         if isinstance(r, Result))) is State.OK
Exemplo n.º 8
0
def test_best_state(states, best_state):
    assert state.best(*states) is best_state