Esempio n. 1
0
    def test_one_nonsnmp_source(self, hostname, ipaddress, mode, config_cache, host_config, source):
        source = source(hostname, ipaddress, mode=mode)
        assert source.source_type is SourceType.HOST

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=[source],
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, source.source_type)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        assert len(section.sections) == 1
        assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
Esempio n. 2
0
    def test_no_sources(self, cluster, nodes, config_cache, host_config, mode):
        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                None,
                mode=mode,
                sources=[],
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
        )
        assert len(mhs) == len(nodes)

        key_clu = HostKey(cluster, None, SourceType.HOST)
        assert key_clu not in mhs

        for hostname, addr in nodes.items():
            key = HostKey(hostname, addr, SourceType.HOST)
            assert key in mhs

            section = mhs[key]
            # yapf: disable
            assert (section.sections[SectionName("section_name_%s" % hostname)]
                    == [["section_content"]])
            assert not section.cache_info
            assert not section.piggybacked_raw_data
            assert not section.persisted_sections
    def test_no_sources(self, hostname, ipaddress, mode, config_cache,
                        host_config):
        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=(),
            ),
            max_cachefile_age=0,
            host_config=host_config,
            fetcher_messages=(),
            selected_sections=NO_SELECTION,
        )
        # The length is not zero because the function always sets,
        # at least, a piggy back section.
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]

        # Public attributes from HostSections:
        assert not section.sections
        assert not section.cache_info
        assert not section.piggybacked_raw_data
Esempio n. 4
0
def _get_multi_host_sections_for_inv(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
) -> Tuple[MultiHostSections, Sequence[Tuple[ABCSource, result.Result[
        ABCHostSections, Exception]]]]:
    if host_config.is_cluster:
        return MultiHostSections(), []

    sources = checkers.make_sources(
        host_config,
        ipaddress,
        mode=checkers.Mode.INVENTORY,
    )

    multi_host_sections = MultiHostSections()
    results = checkers.update_host_sections(
        multi_host_sections,
        checkers.make_nodes(
            config_cache,
            host_config,
            ipaddress,
            checkers.Mode.INVENTORY,
            sources,
        ),
        max_cachefile_age=host_config.max_cachefile_age,
        selected_raw_sections=None,
        host_config=host_config,
    )

    return multi_host_sections, results
Esempio n. 5
0
    def test_no_sources(self, hostname, ipaddress, mode, config_cache, host_config):
        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=[],
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
        )
        # The length is not zero because the function always sets,
        # at least, a piggy back section.
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        # Public attributes from ABCHostSections:
        assert not section.sections
        assert not section.cache_info
        assert not section.piggybacked_raw_data
        assert not section.persisted_sections
Esempio n. 6
0
    def test_multiple_sources_from_the_same_host(
        self,
        hostname,
        ipaddress,
        mode,
        config_cache,
        host_config,
    ):
        sources = [
            ProgramSource.ds(
                hostname,
                ipaddress,
                mode=mode,
                preselected_sections=AUTO_DETECT,
                template="",
            ),
            TCPSource(
                hostname,
                ipaddress,
                mode=mode,
                preselected_sections=AUTO_DETECT,
            ),
        ]

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=sources,
            ),
            max_cachefile_age=0,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK(source.default_raw_data),
                    Snapshot.null(),
                    source.fetcher_type,
                ) for source in sources
            ],
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        assert len(section.sections) == 1
        # yapf: disable
        assert (section.sections[SectionName("section_name_%s" % hostname)]
                == len(sources) * [["section_content"]])
Esempio n. 7
0
    def test_multiple_sources_from_the_same_host(
        self,
        hostname,
        ipaddress,
        mode,
        config_cache,
        host_config,
    ):
        sources = [
            ProgramSource.ds(
                hostname,
                ipaddress,
                mode=mode,
                template="",
            ),
            TCPSource(
                hostname,
                ipaddress,
                mode=mode,
            ),
        ]

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=sources,
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        assert len(section.sections) == 1
        # yapf: disable
        assert (section.sections[SectionName("section_name_%s" % hostname)]
                == len(sources) * [["section_content"]])
Esempio n. 8
0
    def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, mode, config_cache, host_config):
        sources = [
            ProgramSource.ds(hostname + "0", ipaddress,
                                                    mode=mode,
                                                   template="",),
            TCPSource(hostname + "1", ipaddress, mode=mode,),
            TCPSource(hostname + "2", ipaddress, mode=mode,),
        ]

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=sources,
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK(source.default_raw_data),
                    L3Stats(CPUTracker()),
                    source.fetcher_type,
                )
                for source in sources
            ],
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        assert len(section.sections) == len(sources)
        for source in sources:
            # yapf: disable
            assert (
                section.sections[SectionName("section_name_%s" % source.hostname)]
                == [["section_content"]])
Esempio n. 9
0
def _fetch_multi_host_sections_for_inv(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
    selected_sections: checkers.SectionNameCollection,
) -> Tuple[MultiHostSections, Sequence[Tuple[Source, result.Result[
        HostSections, Exception]]]]:
    if host_config.is_cluster:
        return MultiHostSections(), []

    mode = (checkers.Mode.INVENTORY
            if selected_sections is checkers.NO_SELECTION else
            checkers.Mode.FORCE_SECTIONS)

    sources = checkers.make_sources(
        host_config,
        ipaddress,
        mode=mode,
        selected_sections=selected_sections,
    )

    nodes = checkers.make_nodes(
        config_cache,
        host_config,
        ipaddress,
        mode,
        sources,
    )
    multi_host_sections = MultiHostSections()
    results = checkers.update_host_sections(
        multi_host_sections,
        nodes,
        max_cachefile_age=host_config.max_cachefile_age,
        host_config=host_config,
        fetcher_messages=list(
            checkers.fetch_all(
                nodes,
                max_cachefile_age=host_config.max_cachefile_age,
                host_config=host_config,
            )),
        selected_sections=selected_sections,
    )

    return multi_host_sections, results
    def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, mode, config_cache, host_config):
        sources = [
            ProgramSource.ds(hostname + "0", ipaddress, mode=mode, template=""),
            TCPSource(hostname + "1", ipaddress, mode=mode),
            TCPSource(hostname + "2", ipaddress, mode=mode),
        ]

        nodes = make_nodes(
            config_cache,
            host_config,
            ipaddress,
            mode=mode,
            sources=sources,
        )

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            nodes,
            max_cachefile_age=0,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK(source.default_raw_data),
                    Snapshot.null(),
                    source.fetcher_type,
                )
                for _h, _i, sources in nodes for source in sources
            ],
            selected_sections=NO_SELECTION,
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]

        assert len(section.sections) == len(sources)
        for source in sources:
            # yapf: disable
            assert (
                section.sections[SectionName("section_name_%s" % source.hostname)]
                == [["section_content"]])
Esempio n. 11
0
    def test_one_snmp_source(self, hostname, ipaddress, mode, config_cache,
                             host_config):
        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=[
                    SNMPSource.snmp(
                        hostname,
                        ipaddress,
                        mode=mode,
                        selected_sections=NO_SELECTION,
                        on_scan_error="raise",
                    ),
                ],
            ),
            max_cachefile_age=0,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK({}),
                    Snapshot.null(),
                    FetcherType.SNMP,
                ),
            ],
            selected_sections=NO_SELECTION,
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]

        assert len(section.sections) == 1
        assert section.sections[SectionName("section_name_%s" %
                                            hostname)] == [["section_content"]]
Esempio n. 12
0
def _fetch_multi_host_sections_for_inv(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
) -> Tuple[MultiHostSections, Sequence[Tuple[Source, result.Result[
        HostSections, Exception]]]]:
    if host_config.is_cluster:
        return MultiHostSections(), []

    sources = checkers.make_sources(
        host_config,
        ipaddress,
        mode=checkers.Mode.INVENTORY,
    )
    for source in sources:
        _configure_source_for_inv(source)

    nodes = checkers.make_nodes(
        config_cache,
        host_config,
        ipaddress,
        checkers.Mode.INVENTORY,
        sources,
    )
    multi_host_sections = MultiHostSections()
    results = checkers.update_host_sections(
        multi_host_sections,
        nodes,
        max_cachefile_age=host_config.max_cachefile_age,
        selected_raw_sections=None,
        host_config=host_config,
        fetcher_messages=list(
            checkers.fetch_all(
                nodes,
                max_cachefile_age=host_config.max_cachefile_age,
                host_config=host_config,
                selected_raw_sections=None,
            )),
    )

    return multi_host_sections, results
    def test_no_sources(self, cluster, nodes, config_cache, host_config, mode):
        made_nodes = make_nodes(
            config_cache,
            host_config,
            None,
            mode=mode,
            sources=(),
        )

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            made_nodes,
            max_cachefile_age=0,
            host_config=host_config,
            fetcher_messages=[
                # We do not pass sources explicitly but still append Piggyback.
                FetcherMessage.from_raw_data(
                    result.OK(AgentRawData(b"")),
                    Snapshot.null(),
                    FetcherType.PIGGYBACK,
                ) for _n in made_nodes
            ],
            selected_sections=NO_SELECTION,
        )
        assert len(mhs) == len(nodes)

        key_clu = HostKey(cluster, None, SourceType.HOST)
        assert key_clu not in mhs

        for hostname, addr in nodes.items():
            key = HostKey(hostname, addr, SourceType.HOST)
            assert key in mhs

            section = mhs[key]
            # yapf: disable
            assert (section.sections[SectionName("section_name_%s" % hostname)]
                    == [["section_content_%s" % hostname]])
            assert not section.cache_info
            assert not section.piggybacked_raw_data
Esempio n. 14
0
    def test_one_snmp_source(self, hostname, ipaddress, mode, config_cache,
                             host_config):
        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=[
                    SNMPSource.snmp(
                        hostname,
                        ipaddress,
                        mode=mode,
                    ),
                ],
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK({}),
                    L3Stats(CPUTracker()),
                    FetcherType.SNMP,
                ),
            ],
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, SourceType.HOST)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, SNMPHostSections)

        assert len(section.sections) == 1
        assert section.sections[SectionName("section_name_%s" %
                                            hostname)] == [["section_content"]]
Esempio n. 15
0
    def test_one_nonsnmp_source(self, hostname, ipaddress, mode, config_cache,
                                host_config, source):
        source = source(hostname, ipaddress, mode=mode)
        assert source.source_type is SourceType.HOST

        mhs = MultiHostSections()
        update_host_sections(
            mhs,
            make_nodes(
                config_cache,
                host_config,
                ipaddress,
                mode=mode,
                sources=[source],
            ),
            max_cachefile_age=0,
            selected_raw_sections=None,
            host_config=host_config,
            fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK(source.default_raw_data),
                    L3Stats(CPUTracker()),
                    source.fetcher_type,
                ),
            ],
        )
        assert len(mhs) == 1

        key = HostKey(hostname, ipaddress, source.source_type)
        assert key in mhs

        section = mhs[key]
        assert isinstance(section, AgentHostSections)

        assert len(section.sections) == 1
        assert section.sections[SectionName("section_name_%s" %
                                            hostname)] == [["section_content"]]
Esempio n. 16
0
def do_check(
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    only_check_plugin_names: Optional[Set[CheckPluginName]] = None,
    fetcher_messages: Optional[Sequence[FetcherMessage]] = None
) -> Tuple[int, List[ServiceDetails], List[ServiceAdditionalDetails], List[str]]:
    console.verbose("Checkmk version %s\n", cmk_version.__version__)

    config_cache = config.get_config_cache()
    host_config = config_cache.get_host_config(hostname)

    exit_spec = host_config.exit_code_spec()

    status: ServiceState = 0
    infotexts: List[ServiceDetails] = []
    long_infotexts: List[ServiceAdditionalDetails] = []
    perfdata: List[str] = []
    try:
        with cpu_tracking.execute(), cpu_tracking.phase("busy"):
            license_usage.try_history_update()

            # In case of keepalive we always have an ipaddress (can be 0.0.0.0 or :: when
            # address is unknown). When called as non keepalive ipaddress may be None or
            # is already an address (2nd argument)
            if ipaddress is None and not host_config.is_cluster:
                ipaddress = ip_lookup.lookup_ip_address(host_config)

            item_state.load(hostname)

            # When monitoring Checkmk clusters, the cluster nodes are responsible for fetching all
            # information from the monitored host and cache the result for the cluster checks to be
            # performed on the cached information.
            #
            # This means that in case of SNMP nodes, they need to take the clustered services of the
            # node into account, fetch the needed sections and cache them for the cluster host.
            #
            # But later, when checking the node services, the node has to only deal with the unclustered
            # services.
            belongs_to_cluster = len(config_cache.clusters_of(hostname)) > 0

            services_to_fetch = _get_services_to_fetch(
                host_name=hostname,
                belongs_to_cluster=belongs_to_cluster,
                config_cache=config_cache,
                only_check_plugins=only_check_plugin_names,
            )

            services_to_check = _filter_clustered_services(
                config_cache=config_cache,
                host_name=hostname,
                belongs_to_cluster=belongs_to_cluster,
                services=services_to_fetch,
            )

            # see which raw sections we may need
            selected_raw_sections = agent_based_register.get_relevant_raw_sections(
                check_plugin_names=(s.check_plugin_name for s in services_to_fetch),
                consider_inventory_plugins=host_config.do_status_data_inventory,
            )

            sources = checkers.make_sources(
                host_config,
                ipaddress,
                mode=checkers.Mode.CHECKING,
            )
            mhs = MultiHostSections()

            result = checkers.update_host_sections(
                mhs,
                checkers.make_nodes(
                    config_cache,
                    host_config,
                    ipaddress,
                    checkers.Mode.CHECKING,
                    sources,
                ),
                selected_raw_sections=selected_raw_sections,
                max_cachefile_age=host_config.max_cachefile_age,
                host_config=host_config,
                fetcher_messages=fetcher_messages,
            )

            num_success, plugins_missing_data = _do_all_checks_on_host(
                config_cache,
                host_config,
                ipaddress,
                multi_host_sections=mhs,
                services=services_to_check,
                only_check_plugins=only_check_plugin_names,
            )
            inventory.do_inventory_actions_during_checking_for(
                config_cache,
                host_config,
                ipaddress,
                sources=sources,
                multi_host_sections=mhs,
            )

            if _submit_to_core:
                item_state.save(hostname)

            for source, host_sections in result:
                source_state, source_output, source_perfdata = source.summarize(host_sections)
                if source_output != "":
                    status = max(status, source_state)
                    infotexts.append("[%s] %s" % (source.id, source_output))
                    perfdata.extend([_convert_perf_data(p) for p in source_perfdata])

            if plugins_missing_data:
                missing_data_status, missing_data_infotext = _check_plugins_missing_data(
                    plugins_missing_data,
                    exit_spec,
                    bool(num_success),
                )
                status = max(status, missing_data_status)
                infotexts.append(missing_data_infotext)

        for msg in fetcher_messages if fetcher_messages else ():
            cpu_tracking.update(msg.stats.cpu_times)

        phase_times = cpu_tracking.get_times()
        total_times = phase_times["busy"]

        infotexts.append("execution time %.1f sec" % total_times.run_time)
        if config.check_mk_perfdata_with_times:
            perfdata += [
                "execution_time=%.3f" % total_times.run_time,
                "user_time=%.3f" % total_times.process.user,
                "system_time=%.3f" % total_times.process.system,
                "children_user_time=%.3f" % total_times.process.children_user,
                "children_system_time=%.3f" % total_times.process.children_system,
            ]

            for phase, times in phase_times.items():
                if phase in ["agent", "snmp", "ds"]:
                    t = times.run_time - sum(times.process[:4])  # real time - CPU time
                    perfdata.append("cmk_time_%s=%.3f" % (phase, t))
        else:
            perfdata.append("execution_time=%.3f" % total_times.run_time)

        return status, infotexts, long_infotexts, perfdata
    finally:
        if _checkresult_file_fd is not None:
            _close_checkresult_file()

        # "ipaddress is not None": At least when working with a cluster host it seems the ipaddress
        # may be None.  This needs to be understood in detail and cleaned up. As the InlineSNMP
        # stats feature is a very rarely used debugging feature, the analyzation and fix is
        # postponed now.
        if config.record_inline_snmp_stats and ipaddress is not None and host_config.snmp_config(
                ipaddress).snmp_backend == "inline":
            inline.snmp_stats_save()
Esempio n. 17
0
def do_check(
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    *,
    # The following arguments *must* remain optional for Nagios and the `DiscoCheckExecutor`.
    #   See Also: `cmk.base.discovery.check_discovery()`
    fetcher_messages: Sequence[FetcherMessage] = (),
    run_only_plugin_names: Optional[Set[CheckPluginName]] = None,
    selected_sections: checkers.SectionNameCollection = checkers.NO_SELECTION,
    submit_to_core: bool = True,
    show_perfdata: bool = False,
) -> Tuple[int, List[ServiceDetails], List[ServiceAdditionalDetails],
           List[str]]:
    console.verbose("Checkmk version %s\n", cmk_version.__version__)

    config_cache = config.get_config_cache()
    host_config = config_cache.get_host_config(hostname)

    exit_spec = host_config.exit_code_spec()

    mode = checkers.Mode.CHECKING if selected_sections is checkers.NO_SELECTION else checkers.Mode.FORCE_SECTIONS

    status: ServiceState = 0
    infotexts: List[ServiceDetails] = []
    long_infotexts: List[ServiceAdditionalDetails] = []
    perfdata: List[str] = []
    try:
        license_usage.try_history_update()

        # In case of keepalive we always have an ipaddress (can be 0.0.0.0 or :: when
        # address is unknown). When called as non keepalive ipaddress may be None or
        # is already an address (2nd argument)
        if ipaddress is None and not host_config.is_cluster:
            ipaddress = ip_lookup.lookup_ip_address(host_config)

        # When monitoring Checkmk clusters, the cluster nodes are responsible for fetching all
        # information from the monitored host and cache the result for the cluster checks to be
        # performed on the cached information.
        #
        # This means that in case of SNMP nodes, they need to take the clustered services of the
        # node into account, fetch the needed sections and cache them for the cluster host.
        #
        # But later, when checking the node services, the node has to only deal with the unclustered
        # services.
        #
        # TODO: clean this up. The fetched sections are computed in the checkers
        #       _make_configured_snmp_sections now.
        #
        belongs_to_cluster = len(config_cache.clusters_of(hostname)) > 0

        services_to_fetch = _get_services_to_fetch(
            host_name=hostname,
            belongs_to_cluster=belongs_to_cluster,
            config_cache=config_cache,
        )

        services_to_check = _filter_clustered_services(
            config_cache=config_cache,
            host_name=hostname,
            belongs_to_cluster=belongs_to_cluster,
            services=services_to_fetch,
            run_only_plugin_names=run_only_plugin_names,
        )

        nodes = checkers.make_nodes(
            config_cache,
            host_config,
            ipaddress,
            mode,
            checkers.make_sources(
                host_config,
                ipaddress,
                mode=mode,
                selected_sections=selected_sections,
            ),
        )

        if not fetcher_messages:
            # Note: `fetch_all(sources)` is almost always called in similar
            #       code in discovery and inventory.  The only other exception
            #       is `cmk.base.discovery.check_discovery(...)`.  This does
            #       not seem right.
            fetcher_messages = list(
                checkers.fetch_all(
                    nodes,
                    max_cachefile_age=host_config.max_cachefile_age,
                    host_config=host_config,
                ))

        with CPUTracker() as tracker:
            mhs = MultiHostSections()
            result = checkers.update_host_sections(
                mhs,
                nodes,
                max_cachefile_age=host_config.max_cachefile_age,
                host_config=host_config,
                fetcher_messages=fetcher_messages,
                selected_sections=selected_sections,
            )

            num_success, plugins_missing_data = _do_all_checks_on_host(
                config_cache,
                host_config,
                ipaddress,
                multi_host_sections=mhs,
                services=services_to_check,
                submit_to_core=submit_to_core,
                show_perfdata=show_perfdata,
            )

            if run_only_plugin_names is None:
                inventory.do_inventory_actions_during_checking_for(
                    config_cache,
                    host_config,
                    ipaddress,
                    multi_host_sections=mhs,
                )

            for source, host_sections in result:
                source_state, source_output, source_perfdata = source.summarize(
                    host_sections)
                if source_output != "":
                    status = max(status, source_state)
                    infotexts.append("[%s] %s" % (source.id, source_output))
                    perfdata.extend(
                        [_convert_perf_data(p) for p in source_perfdata])

            if plugins_missing_data:
                missing_data_status, missing_data_infotext = _check_plugins_missing_data(
                    plugins_missing_data,
                    exit_spec,
                    bool(num_success),
                )
                status = max(status, missing_data_status)
                infotexts.append(missing_data_infotext)

        total_times = tracker.duration
        for msg in fetcher_messages:
            total_times += msg.stats.duration

        infotexts.append("execution time %.1f sec" %
                         total_times.process.elapsed)
        if config.check_mk_perfdata_with_times:
            perfdata += [
                "execution_time=%.3f" % total_times.process.elapsed,
                "user_time=%.3f" % total_times.process.user,
                "system_time=%.3f" % total_times.process.system,
                "children_user_time=%.3f" % total_times.process.children_user,
                "children_system_time=%.3f" %
                total_times.process.children_system,
            ]
            summary: DefaultDict[str, Snapshot] = defaultdict(Snapshot.null)
            for msg in fetcher_messages if fetcher_messages else ():
                if msg.fetcher_type in (
                        FetcherType.PIGGYBACK,
                        FetcherType.PROGRAM,
                        FetcherType.SNMP,
                        FetcherType.TCP,
                ):
                    summary[{
                        FetcherType.PIGGYBACK: "agent",
                        FetcherType.PROGRAM: "ds",
                        FetcherType.SNMP: "snmp",
                        FetcherType.TCP: "agent",
                    }[msg.fetcher_type]] += msg.stats.duration
            for phase, duration in summary.items():
                perfdata.append("cmk_time_%s=%.3f" % (phase, duration.idle))
        else:
            perfdata.append("execution_time=%.3f" %
                            total_times.process.elapsed)

        return status, infotexts, long_infotexts, perfdata
    finally:
        if _checkresult_file_fd is not None:
            _close_checkresult_file()
def test_get_host_sections_cluster(mode, monkeypatch, mocker):
    hostname = "testhost"
    hosts = {
        "host0": "10.0.0.0",
        "host1": "10.0.0.1",
        "host2": "10.0.0.2",
    }
    address = "1.2.3.4"
    tags = {"agent": "no-agent"}
    section_name = SectionName("test_section")
    config_cache = make_scenario(hostname, tags).apply(monkeypatch)
    host_config = config.HostConfig.make_host_config(hostname)

    def lookup_ip_address(host_config, family=None, for_mgmt_board=False):
        return hosts[host_config.hostname]

    def check(_, *args, **kwargs):
        return result.OK(AgentHostSections(sections={section_name: [[str(section_name)]]}))

    monkeypatch.setattr(
        ip_lookup,
        "lookup_ip_address",
        lookup_ip_address,
    )
    monkeypatch.setattr(
        Source,
        "parse",
        check,
    )
    mocker.patch.object(
        cmk.utils.piggyback,
        "remove_source_status_file",
        autospec=True,
    )
    mocker.patch.object(
        cmk.utils.piggyback,
        "_store_status_file_of",
        autospec=True,
    )

    # Create a cluster
    host_config.nodes = list(hosts.keys())

    nodes = make_nodes(
        config_cache,
        host_config,
        address,
        mode=mode,
        sources=make_sources(host_config, address, mode=mode)
    )

    mhs = MultiHostSections()
    update_host_sections(
        mhs,
        nodes,
        max_cachefile_age=host_config.max_cachefile_age,
        host_config=host_config,
        fetcher_messages=[
                FetcherMessage.from_raw_data(
                    result.OK(source.default_raw_data),
                    Snapshot.null(),
                    source.fetcher_type,
                )
                for _h, _i, sources in nodes for source in sources
            ],
        selected_sections=NO_SELECTION,
    )
    assert len(mhs) == len(hosts) == 3
    cmk.utils.piggyback._store_status_file_of.assert_not_called()  # type: ignore[attr-defined]
    assert cmk.utils.piggyback.remove_source_status_file.call_count == 3  # type: ignore[attr-defined]

    for host, addr in hosts.items():
        remove_source_status_file = cmk.utils.piggyback.remove_source_status_file
        remove_source_status_file.assert_any_call(host)  # type: ignore[attr-defined]
        key = HostKey(host, addr, SourceType.HOST)
        assert key in mhs
        section = mhs[key]
        assert len(section.sections) == 1
        assert next(iter(section.sections)) == section_name
        assert not section.cache_info
        assert not section.piggybacked_raw_data
Esempio n. 19
0
def _do_inv_for_realhost(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    sources: Sequence[ABCSource],
    multi_host_sections: Optional[MultiHostSections],
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    inventory_tree: StructuredDataTree,
    status_data_tree: StructuredDataTree,
) -> Sequence[Tuple[ABCSource, Result[ABCHostSections, Exception]]]:
    results: List[Tuple[ABCSource, Result[ABCHostSections, Exception]]] = []
    for source in sources:
        if isinstance(source, checkers.snmp.SNMPSource):
            # TODO(ml): This modifies the SNMP fetcher config dynamically.
            source.on_snmp_scan_error = "raise"  # default
            checkers.FileCacheConfigurer.snmp_disabled = True
            source.use_snmpwalk_cache = False
            source.ignore_check_interval = True
            if multi_host_sections is not None:
                # Status data inventory already provides filled multi_host_sections object.
                # SNMP data source: If 'do_status_data_inv' is enabled there may be
                # sections for inventory plugins which were not fetched yet.
                host_sections = multi_host_sections.setdefault(
                    # TODO(ml): are
                    #    hostname == source.hostname
                    #    ipaddress == source.ipaddress
                    # ?
                    HostKey(hostname, ipaddress, source.source_type),
                    SNMPHostSections(),
                )
                # TODO(ml): This modifies the SNMP fetcher config dynamically.
                #           Can the fetcher handle that on its own?
                source.prefetched_sections = host_sections.sections

                # When executing the structured status inventory, we are in the Mode.CHECKING
                assert source.mode is Mode.INVENTORY or source.mode is Mode.CHECKING

                host_section = source.parse(source.fetch())
                results.append((source, host_section))
                if host_section.is_ok():
                    assert host_section.ok is not None
                    host_sections.update(host_section.ok)

    if multi_host_sections is None:
        multi_host_sections = MultiHostSections()
        hs = checkers.update_host_sections(
            multi_host_sections,
            checkers.make_nodes(
                config_cache,
                host_config,
                ipaddress,
                checkers.Mode.INVENTORY,
                sources,
            ),
            max_cachefile_age=host_config.max_cachefile_age,
            selected_raw_sections=None,
            host_config=host_config,
        )
        results.extend(hs)

    section.section_step("Executing inventory plugins")
    console.verbose("Plugins:")
    for inventory_plugin in agent_based_register.iter_all_inventory_plugins():

        kwargs = multi_host_sections.get_section_kwargs(
            HostKey(hostname, ipaddress, SourceType.HOST),
            inventory_plugin.sections,
        )
        if not kwargs:
            continue

        console.verbose(
            " %s%s%s%s" %
            (tty.green, tty.bold, inventory_plugin.name, tty.normal))

        # Inventory functions can optionally have a second argument: parameters.
        # These are configured via rule sets (much like check parameters).
        if inventory_plugin.inventory_ruleset_name is not None:
            kwargs["params"] = host_config.inventory_parameters(
                str(inventory_plugin.inventory_ruleset_name)
            )  # TODO (mo): keep type!

        _aggregate_inventory_results(
            inventory_plugin.inventory_function(**kwargs),
            inventory_tree,
            status_data_tree,
        )

    console.verbose("\n")
    return results