Ejemplo n.º 1
0
 def _make_inventory_snmp_sections(self) -> Set[SectionName]:
     return self._enabled_snmp_sections.intersection(
         agent_based_register.get_relevant_raw_sections(
             check_plugin_names=(),
             consider_inventory_plugins=self.mode is Mode.INVENTORY
             or self.host_config.do_status_data_inventory,
         ))
Ejemplo n.º 2
0
 def _make_inventory_snmp_sections(self) -> Set[SectionName]:
     return set(
         agent_based_register.get_relevant_raw_sections(
             check_plugin_names=(),
             inventory_plugin_names=(p.name for p in agent_based_register.
                                     iter_all_inventory_plugins()),
         )).intersection(
             s.name for s in agent_based_register.iter_all_snmp_sections())
Ejemplo n.º 3
0
def make_inventory_sections() -> Set[SectionName]:
    return {
        s for s in agent_based_register.get_relevant_raw_sections(
            check_plugin_names=(),
            inventory_plugin_names=(
                p.name for p in agent_based_register.iter_all_inventory_plugins()))
        if agent_based_register.is_registered_snmp_section_plugin(s)
    }
Ejemplo n.º 4
0
def _make_piggybacked_sections(host_config) -> SelectedRawSections:
    check_plugin_names = set(
        itertools.chain.from_iterable(
            check_table.get_needed_check_names(
                node_name,
                remove_duplicates=True,
                filter_mode="only_clustered",
            ) for node_name in host_config.nodes))
    return agent_based_register.get_relevant_raw_sections(check_plugin_names=check_plugin_names)
Ejemplo n.º 5
0
 def _make_configured_snmp_sections(self) -> Set[SectionName]:
     return self._enabled_snmp_sections.intersection(
         agent_based_register.get_relevant_raw_sections(
             check_plugin_names=check_table.get_needed_check_names(
                 self.hostname,
                 filter_mode="include_clustered",
                 skip_ignored=True,
             ),
             consider_inventory_plugins=False,
         ))
Ejemplo n.º 6
0
 def _make_configured_snmp_sections(self) -> Set[SectionName]:
     return (set(
         agent_based_register.get_relevant_raw_sections(
             check_plugin_names=check_table.get_needed_check_names(
                 self.hostname,
                 filter_mode="include_clustered",
                 skip_ignored=True,
             ),
             consider_inventory_plugins=False,
         ),) if self.preselected_sections is AUTO_DETECT else
             self.preselected_sections).intersection(
                 s.name for s in agent_based_register.iter_all_snmp_sections())
Ejemplo n.º 7
0
 def _make_selected_sections(self) -> Set[SectionName]:
     selection = self.selected_sections
     if selection is NO_SELECTION:
         selection = set(
             agent_based_register.get_relevant_raw_sections(
                 check_plugin_names=check_table.get_needed_check_names(
                     self.hostname,
                     filter_mode="include_clustered",
                     skip_ignored=True,
                 ),
                 inventory_plugin_names=()))
     return selection.intersection(
         s.name for s in agent_based_register.iter_all_snmp_sections())
Ejemplo n.º 8
0
 def _make_checking_sections(self) -> Set[SectionName]:
     if self.selected_sections is not NO_SELECTION:
         checking_sections = self.selected_sections
     else:
         checking_sections = set(
             agent_based_register.get_relevant_raw_sections(
                 check_plugin_names=check_table.get_check_table(
                     self.hostname,
                     filter_mode=check_table.FilterMode.INCLUDE_CLUSTERED,
                     skip_ignored=True,
                 ).needed_check_names(),
                 inventory_plugin_names=()))
     return checking_sections.intersection(
         s.name for s in agent_based_register.iter_all_snmp_sections())
Ejemplo n.º 9
0
def _make_piggybacked_sections(host_config) -> SelectedRawSections:
    check_plugin_names = set(
        itertools.chain.from_iterable(
            check_table.get_needed_check_names(
                node_name,
                filter_mode="only_clustered",
            ) for node_name in host_config.nodes))
    return agent_based_register.get_relevant_raw_sections(
        check_plugin_names=check_plugin_names,
        # TODO: this was added when an optional argument became
        # mandatory. So this makes the default explicit, but
        # currently I am not sure if this is correct.
        consider_inventory_plugins=False,
    )
Ejemplo n.º 10
0
    def _extract_disabled_snmp_sections_from_ignored_checks(
            self, all_rulesets):
        ignored_checks_ruleset = all_rulesets.get("ignored_checks")
        if ignored_checks_ruleset.is_empty():
            # nothing to do
            return
        if not all_rulesets.get("snmp_exclude_sections").is_empty():
            # this must be an upgrade from 2.0.0 or newer - don't mess with
            # the existing rules!
            return

        self._logger.log(VERBOSE, "Extracting excluded SNMP sections")

        all_snmp_section_names = set(
            s.name for s in register.iter_all_snmp_sections())
        all_check_plugin_names = set(
            p.name for p in register.iter_all_check_plugins())
        all_inventory_plugin_names = set(
            i.name for i in register.iter_all_inventory_plugins())

        snmp_exclude_sections_ruleset = cmk.gui.watolib.rulesets.Ruleset(
            "snmp_exclude_sections", ignored_checks_ruleset.tag_to_group_map)

        for folder, _index, rule in ignored_checks_ruleset.get_rules():
            disabled = {CheckPluginName(n) for n in rule.value}
            still_needed_sections_names = set(
                register.get_relevant_raw_sections(
                    check_plugin_names=all_check_plugin_names - disabled,
                    inventory_plugin_names=all_inventory_plugin_names,
                ))
            sections_to_disable = all_snmp_section_names - still_needed_sections_names
            if not sections_to_disable:
                continue

            new_rule = cmk.gui.watolib.rulesets.Rule(
                rule.folder, snmp_exclude_sections_ruleset)
            new_rule.from_config(rule.to_config())
            new_rule.id = cmk.gui.watolib.rulesets.utils.gen_id()
            new_rule.value = {  # type: ignore[assignment]
                'sections_disabled': sorted(str(s) for s in sections_to_disable),
                'sections_enabled': [],
            }
            new_rule.rule_options["comment"] = (
                '%s - Checkmk: automatically converted during upgrade from rule '
                '"Disabled checks". Please review if these rules can be deleted.'
            ) % time.strftime("%Y-%m-%d %H:%M", time.localtime())
            snmp_exclude_sections_ruleset.append_rule(folder, new_rule)

        all_rulesets.set(snmp_exclude_sections_ruleset.name,
                         snmp_exclude_sections_ruleset)
Ejemplo n.º 11
0
    def _make_configured_snmp_sections(self) -> Iterable[SectionName]:
        section_names = set(
            agent_based_register.get_relevant_raw_sections(
                check_plugin_names=check_table.get_needed_check_names(
                    self.hostname,
                    remove_duplicates=True,
                    filter_mode="include_clustered",
                    skip_ignored=True,
                ),
                consider_inventory_plugins=self.host_config.do_status_data_inventory,
            ))

        section_names -= self.host_config.disabled_snmp_sections()

        return SNMPSource._sort_section_names(section_names)
Ejemplo n.º 12
0
    def _make_configured_snmp_sections(self) -> Collection[SectionName]:
        section_names = set(
            agent_based_register.get_relevant_raw_sections(
                check_plugin_names=check_table.get_needed_check_names(
                    self.hostname,
                    filter_mode="include_clustered",
                    skip_ignored=True,
                ),
                consider_inventory_plugins=self.host_config.do_status_data_inventory,
            ))

        snmp_section_names = section_names.intersection(
            s.name for s in agent_based_register.iter_all_snmp_sections()
        ) - self.host_config.disabled_snmp_sections()

        return SNMPSource._sort_section_names(snmp_section_names)
Ejemplo n.º 13
0
def _get_relevant_raw_sections(services: List[Service], host_config: config.HostConfig):
    # see if we can remove this function, once inventory plugins have been migrated to
    # the new API. In particular, we schould be able to get rid of the imports.

    if host_config.do_status_data_inventory:
        # This is called during checking, but the inventory plugins are not loaded yet
        import cmk.base.inventory_plugins as inventory_plugins  # pylint: disable=import-outside-toplevel
        from cmk.base.check_api import get_check_api_context  # pylint: disable=import-outside-toplevel
        inventory_plugins.load_plugins(get_check_api_context, inventory.get_inventory_context)
        inventory_plugin_names: Iterable[InventoryPluginName] = (
            InventoryPluginName(name.split('.')[0]) for name in inventory_plugins.inv_info)
    else:
        inventory_plugin_names = ()

    return agent_based_register.get_relevant_raw_sections(
        check_plugin_names=(s.check_plugin_name for s in services),
        inventory_plugin_names=inventory_plugin_names,
    )
Ejemplo n.º 14
0
    def _extract_disabled_snmp_sections_from_ignored_checks(
            self, all_rulesets):
        ignored_checks_ruleset = all_rulesets.get("ignored_checks")
        if ignored_checks_ruleset.is_empty():
            # nothing to do
            return
        if not all_rulesets.get("snmp_exclude_sections").is_empty():
            # this must be an upgrade from 2.0.0 or newer - don't mess with
            # the existing rules!
            return

        self._logger.log(VERBOSE, "Extracting excluded SNMP sections")

        all_snmp_section_names = set(
            s.name for s in register.iter_all_snmp_sections())
        all_check_plugin_names = set(
            p.name for p in register.iter_all_check_plugins())
        all_inventory_plugin_names = set(
            i.name for i in register.iter_all_inventory_plugins())

        snmp_exclude_sections_ruleset = cmk.gui.watolib.rulesets.Ruleset(
            "snmp_exclude_sections", ignored_checks_ruleset.tag_to_group_map)

        for folder, _index, rule in ignored_checks_ruleset.get_rules():
            disabled = {CheckPluginName(n) for n in rule.value}
            still_needed_sections_names = set(
                register.get_relevant_raw_sections(
                    check_plugin_names=all_check_plugin_names - disabled,
                    inventory_plugin_names=all_inventory_plugin_names,
                ))
            sections_to_disable = all_snmp_section_names - still_needed_sections_names

            new_rule = cmk.gui.watolib.rulesets.Rule(
                rule.folder, snmp_exclude_sections_ruleset)
            new_rule.from_config(rule.to_config())
            new_rule.id = cmk.gui.watolib.rulesets.utils.gen_id()
            new_rule.value = {  # type: ignore[assignment]
                'sections_disabled': sorted(str(s) for s in sections_to_disable),
                'sections_enabled': [],
            }
            snmp_exclude_sections_ruleset.append_rule(folder, new_rule)

        all_rulesets.set(snmp_exclude_sections_ruleset.name,
                         snmp_exclude_sections_ruleset)
Ejemplo n.º 15
0
def test_all_sections_are_subscribed_by_some_plugin(fix_register):
    """Test that all registered sections are subscribed to by some plugin

    We have very few sections (one at the time of this writing),
    that are not subscribed to by any plugin.
    We can afford to keep track of those.
    """
    all_section_names = set(fix_register.snmp_sections) | set(fix_register.agent_sections)

    subscribed_sections_names = set(
        get_relevant_raw_sections(
            check_plugin_names=fix_register.check_plugins,
            inventory_plugin_names=fix_register.inventory_plugins,
        )
    )

    unsubscribed_sections_names = {str(n) for n in all_section_names - subscribed_sections_names}

    assert unsubscribed_sections_names == {"labels"}
Ejemplo 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()
Ejemplo n.º 17
0
def do_check(
    hostname: HostName,
    ipaddress: Optional[HostAddress],
    *,
    # The next two *must* remain optional for Nagios and the `DiscoCheckExecutor`.
    #   See Also: `cmk.base.discovery.check_discovery()`
    fetcher_messages: Sequence[FetcherMessage] = (),
    only_check_plugin_names: Optional[Set[CheckPluginName]] = 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 CPUTracker() as tracker:
            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,
            )
            nodes = checkers.make_nodes(
                config_cache,
                host_config,
                ipaddress,
                checkers.Mode.CHECKING,
                sources,
            )

            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,
                        selected_raw_sections=selected_raw_sections,
                    ))

            mhs = MultiHostSections()
            result = checkers.update_host_sections(
                mhs,
                nodes,
                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)

        total_times = tracker.duration
        for msg in fetcher_messages if fetcher_messages else ():
            total_times += msg.stats.cpu_tracker.duration

        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,
            ]
            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.cpu_tracker.duration
            for phase, duration in summary.items():
                t = duration.run_time - sum(
                    duration.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()
Ejemplo n.º 18
0
 def _make_inventory_snmp_sections(self) -> Set[SectionName]:
     return self._enabled_snmp_sections.intersection(
         agent_based_register.get_relevant_raw_sections(
             check_plugin_names=(),
             consider_inventory_plugins=True,
         ))