Exemplo n.º 1
0
    def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, config_cache, host_config):
        sources = [
            DSProgramDataSource(
                hostname + "0", ipaddress,
                configurator=DSProgramConfigurator(hostname + "0", ipaddress,
                                                   template="",),),
            TCPDataSource(hostname + "1", ipaddress),
            TCPDataSource(hostname + "2", ipaddress),
        ]

        mhs = make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            sources=sources,
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        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"]])
Exemplo n.º 2
0
    def test_no_sources(self, cluster, nodes, config_cache, host_config):
        mhs = make_host_sections(
            config_cache,
            host_config,
            None,
            sources=[],
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        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
Exemplo n.º 3
0
    def test_one_snmp_source(self, hostname, ipaddress, mode, config_cache, host_config):
        mhs = make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            mode=mode,
            sources=[
                SNMPDataSource(configurator=SNMPConfigurator.snmp(
                    hostname,
                    ipaddress,
                    mode=mode,
                ),),
            ],
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        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"]]
Exemplo n.º 4
0
    def test_no_sources(self, hostname, ipaddress, mode, config_cache, host_config):
        mhs = make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            mode=mode,
            sources=[],
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        # 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
Exemplo n.º 5
0
    def test_multiple_sources_from_the_same_host(
        self,
        hostname,
        ipaddress,
        mode,
        config_cache,
        host_config,
    ):
        sources = [
            ProgramDataSource(configurator=ProgramConfigurator.ds(
                hostname,
                ipaddress,
                mode=mode,
                template="",
            ),),
            TCPDataSource(configurator=TCPConfigurator(
                hostname,
                ipaddress,
                mode=mode,
            ),),
        ]

        mhs = make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            mode=mode,
            sources=sources,
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        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"]])
Exemplo n.º 6
0
    def test_one_nonsnmp_source(self, hostname, ipaddress, config_cache, host_config, source):
        source = source(hostname, ipaddress)
        assert source.source_type is SourceType.HOST

        mhs = make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            sources=[source],
            max_cachefile_age=0,
            selected_raw_sections=None,
        )
        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"]]
Exemplo n.º 7
0
def test_get_host_sections_cluster(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 make_piggybacked_sections(hc):
        if hc.nodes == host_config.nodes:
            return {section_name: True}
        return {}

    def run(_, *, selected_raw_sections):
        sections = {}
        if selected_raw_sections is not None and section_name in selected_raw_sections:
            sections = {section_name: [[str(section_name)]]}
        return AgentHostSections(sections=sections)

    monkeypatch.setattr(
        ip_lookup,
        "lookup_ip_address",
        lookup_ip_address,
    )
    monkeypatch.setattr(
        _data_sources,
        "_make_piggybacked_sections",
        make_piggybacked_sections,
    )
    monkeypatch.setattr(
        ABCDataSource,
        "run",
        run,
    )
    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())

    mhs = make_host_sections(
        config_cache,
        host_config,
        address,
        make_sources(host_config, address),
        max_cachefile_age=host_config.max_cachefile_age,
        selected_raw_sections=None,
    )
    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
        assert not section.persisted_sections
Exemplo n.º 8
0
def do_check(
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    only_check_plugin_names: Optional[Set[CheckPluginName]] = None
) -> Tuple[int, List[ServiceDetails], List[ServiceAdditionalDetails], List[str]]:
    cpu_tracking.start("busy")
    console.verbose("Check_MK 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:
        # 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)

        services = _get_filtered_services(
            host_name=hostname,
            belongs_to_cluster=len(config_cache.clusters_of(hostname)) > 0,
            config_cache=config_cache,
            only_check_plugins=only_check_plugin_names,
        )

        # see which raw sections we may need
        selected_raw_sections = _get_relevant_raw_sections(services, host_config)

        sources = data_sources.make_sources(
            host_config,
            ipaddress,
        )
        mhs = data_sources.make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            sources=sources,
            selected_raw_sections=selected_raw_sections,
            max_cachefile_age=host_config.max_cachefile_age,
        )
        num_success, plugins_missing_data = _do_all_checks_on_host(
            config_cache,
            host_config,
            ipaddress,
            multi_host_sections=mhs,
            services=services,
            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 in sources:
            source_state, source_output, source_perfdata = source.get_summary_result_for_checking()
            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)

        cpu_tracking.end()
        phase_times = cpu_tracking.get_times()
        total_times = phase_times["TOTAL"]
        run_time = total_times[4]

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

            for phase, times in phase_times.items():
                if phase in ["agent", "snmp", "ds"]:
                    t = times[4] - sum(times[:4])  # real time - CPU time
                    perfdata.append("cmk_time_%s=%.3f" % (phase, t))
        else:
            perfdata.append("execution_time=%.3f" % 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).is_inline_snmp_host:
            inline.snmp_stats_save()
Exemplo n.º 9
0
def _do_inv_for_realhost(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    sources: data_sources.DataSources,
    multi_host_sections: Optional[MultiHostSections],
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    inventory_tree: StructuredDataTree,
    status_data_tree: StructuredDataTree,
) -> None:
    for source in sources:
        if isinstance(source, data_sources.snmp.SNMPDataSource):
            source.detector.on_error = "raise"  # default
            source.detector.do_snmp_scan = True
            data_sources.snmp.SNMPDataSource.disable_data_source_cache()
            source.set_use_snmpwalk_cache(False)
            source.set_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(
                    HostKey(hostname, ipaddress, source.source_type),
                    SNMPHostSections(),
                )
                source.set_fetched_raw_section_names(
                    set(host_sections.sections))
                host_sections.update(source.run(selected_raw_sections=None))

    if multi_host_sections is None:
        multi_host_sections = data_sources.make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            sources,
            max_cachefile_age=host_config.max_cachefile_age,
            selected_raw_sections=None,
        )

    section.section_step("Executing inventory plugins")
    import cmk.base.inventory_plugins as inventory_plugins  # pylint: disable=import-outside-toplevel
    console.verbose("Plugins:")
    for section_name, plugin in inventory_plugins.sorted_inventory_plugins():
        section_content = multi_host_sections.get_section_content(
            HostKey(hostname, ipaddress, SourceType.HOST),
            check_api_utils.HOST_PRECEDENCE,
            section_name,
            for_discovery=False,
        )
        if not section_content:  # section not present (None or [])
            # Note: this also excludes existing sections without info..
            continue

        if all([x in [[], {}, None] for x in section_content]):
            # Inventory plugins which get parsed info from related
            # check plugin may have more than one return value, eg
            # parse function of oracle_tablespaces returns ({}, {})
            continue

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

        # Inventory functions can optionally have a second argument: parameters.
        # These are configured via rule sets (much like check parameters).
        inv_function = plugin["inv_function"]
        kwargs = cmk.utils.misc.make_kwargs_for(
            inv_function,
            inventory_tree=inventory_tree,
            status_data_tree=status_data_tree)
        non_kwargs = set(
            cmk.utils.misc.getfuncargs(inv_function)) - set(kwargs)
        args = [section_content]
        if len(non_kwargs) == 2:
            args += [host_config.inventory_parameters(section_name)]
        inv_function(*args, **kwargs)
    console.verbose("\n")
Exemplo n.º 10
0
def _do_inv_for_realhost(
    config_cache: config.ConfigCache,
    host_config: config.HostConfig,
    sources: data_sources.DataSources,
    multi_host_sections: Optional[MultiHostSections],
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    inventory_tree: StructuredDataTree,
    status_data_tree: StructuredDataTree,
) -> None:
    for source in sources:
        if isinstance(source, data_sources.snmp.SNMPDataSource):
            # TODO(ml): This modifies the SNMP fetcher config dynamically.
            configurator = cast(data_sources.snmp.SNMPConfigurator, source.configurator)
            configurator.on_snmp_scan_error = "raise"  # default
            configurator.do_snmp_scan = True
            data_sources.FileCacheConfigurator.snmp_disabled = True
            configurator.use_snmpwalk_cache = False
            configurator.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.configurator.source_type),
                    SNMPHostSections(),
                )
                # TODO(ml): This modifies the SNMP fetcher config dynamically.
                #           Can the fetcher handle that on its own?
                configurator.prefetched_sections = host_sections.sections
                host_sections.update(source.run(selected_raw_sections=None))

    if multi_host_sections is None:
        multi_host_sections = data_sources.make_host_sections(
            config_cache,
            host_config,
            ipaddress,
            data_sources.Mode.INVENTORY,
            sources,
            max_cachefile_age=host_config.max_cachefile_age,
            selected_raw_sections=None,
        )

    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")