Ejemplo n.º 1
0
 def do_omit_service(hostname, description):
     if config.service_ignored(hostname, None, description):
         return True
     if hostname != config_cache.host_of_clustered_service(
             hostname, description):
         return True
     return False
Ejemplo n.º 2
0
 def do_omit_service(hostname, description):
     # type: (HostName, ServiceName) -> bool
     if config.service_ignored(hostname, None, description):
         return True
     if hostname != config_cache.host_of_clustered_service(hostname, description):
         return True
     return False
Ejemplo n.º 3
0
    def keep(self, service: Service) -> bool:
        # drop unknown plugins:
        if agent_based_register.get_check_plugin(
                service.check_plugin_name) is None:
            return False

        if self._skip_ignored and config.service_ignored(
                self._host_name,
                service.check_plugin_name,
                service.description,
        ):
            return False

        if self._mode is FilterMode.INCLUDE_CLUSTERED:
            return True

        if not self._host_part_of_clusters:
            return self._mode is not FilterMode.ONLY_CLUSTERED

        host_of_service = self._config_cache.host_of_clustered_service(
            self._host_name,
            service.description,
            part_of_clusters=self._host_part_of_clusters,
        )
        svc_is_mine = (self._host_name == host_of_service)

        if self._mode is FilterMode.NONE:
            return svc_is_mine

        # self._mode is FilterMode.ONLY_CLUSTERED
        return not svc_is_mine
Ejemplo n.º 4
0
    def _handle_service(self, service):
        # type: (Service) -> CheckTable
        check_table = {}  # type: CheckTable
        hostname = self._host_config.hostname

        if not self._is_checkname_valid(service.check_plugin_name):
            return {}

        if self.skip_ignored and config.service_ignored(
                hostname, service.check_plugin_name, service.description):
            return {}

        if not self._host_config.part_of_clusters:
            svc_is_mine = True
        else:
            svc_is_mine = hostname == self._config_cache.host_of_clustered_service(
                hostname,
                service.description,
                part_of_clusters=self._host_config.part_of_clusters)

        if self.filter_mode is None and not svc_is_mine:
            return {}

        if self.filter_mode == "only_clustered" and svc_is_mine:
            return {}

        check_table[(service.check_plugin_name, service.item)] = service

        return check_table
Ejemplo n.º 5
0
    def _keep_service(
        self,
        service: Service,
        filter_mode: Optional[str],
        skip_ignored: bool,
    ) -> bool:
        hostname = self._host_config.hostname

        # drop unknown plugins:
        if agent_based_register.get_check_plugin(
                service.check_plugin_name) is None:
            return False

        if skip_ignored and config.service_ignored(
                hostname, service.check_plugin_name, service.description):
            return False

        if self._host_config.part_of_clusters:
            host_of_service = self._config_cache.host_of_clustered_service(
                hostname,
                service.description,
                part_of_clusters=self._host_config.part_of_clusters)
            svc_is_mine = (hostname == host_of_service)
        else:
            svc_is_mine = True

        if filter_mode is None and not svc_is_mine:
            return False

        if filter_mode == "only_clustered" and svc_is_mine:
            return False

        return True
Ejemplo n.º 6
0
    def keep(self, service: ConfiguredService) -> bool:

        if self._skip_ignored and config.service_ignored(
            self._host_name,
            service.check_plugin_name,
            service.description,
        ):
            return False

        if self._mode is FilterMode.INCLUDE_CLUSTERED:
            return True

        if not self._host_part_of_clusters:
            return self._mode is not FilterMode.ONLY_CLUSTERED

        host_of_service = self._config_cache.host_of_clustered_service(
            self._host_name,
            service.description,
            part_of_clusters=self._host_part_of_clusters,
        )
        svc_is_mine = self._host_name == host_of_service

        if self._mode is FilterMode.NONE:
            return svc_is_mine

        # self._mode is FilterMode.ONLY_CLUSTERED
        return not svc_is_mine
Ejemplo n.º 7
0
    def _keep_service(
        config_cache: config.ConfigCache,
        host_config: config.HostConfig,
        service: Service,
        filter_mode: Optional[Literal["only_clustered", "include_clustered"]],
        skip_ignored: bool,
    ) -> bool:
        hostname = host_config.hostname

        # drop unknown plugins:
        if agent_based_register.get_check_plugin(service.check_plugin_name) is None:
            return False

        if skip_ignored and config.service_ignored(hostname, service.check_plugin_name,
                                                   service.description):
            return False

        if filter_mode == "include_clustered":
            return True

        if not host_config.part_of_clusters:
            return filter_mode != "only_clustered"

        host_of_service = config_cache.host_of_clustered_service(
            hostname,
            service.description,
            part_of_clusters=host_config.part_of_clusters,
        )
        svc_is_mine = (hostname == host_of_service)

        if filter_mode is None:
            return svc_is_mine

        # filter_mode == "only_clustered"
        return not svc_is_mine
Ejemplo n.º 8
0
def _merge_manual_services(
    host_config: config.HostConfig,
    services: ServicesTable,
    discovery_parameters: DiscoveryParameters,
) -> ServicesByTransition:
    """Add/replace manual and active checks and handle ignoration"""
    host_name = host_config.hostname

    # Find manual checks. These can override discovered checks -> "manual"
    manual_items = check_table.get_check_table(host_name, skip_autochecks=True)
    for service in manual_items.values():
        services[service.id()] = ('manual', service, [host_name])

    # Add custom checks -> "custom"
    for entry in host_config.custom_checks:
        services[(CheckPluginName('custom'), entry['service_description'])] = (
            'custom',
            Service(
                check_plugin_name=CheckPluginName('custom'),
                item=entry['service_description'],
                description=entry['service_description'],
                parameters=None,
            ),
            [host_name],
        )

    # Similar for 'active_checks', but here we have parameters
    for plugin_name, entries in host_config.active_checks:
        for params in entries:
            descr = config.active_check_service_description(
                host_name, plugin_name, params)
            services[(CheckPluginName(plugin_name), descr)] = (
                'active',
                Service(
                    check_plugin_name=CheckPluginName(plugin_name),
                    item=descr,
                    description=descr,
                    parameters=params,
                ),
                [host_name],
            )

    # Handle disabled services -> "ignored"
    for check_source, discovered_service, _found_on_nodes in services.values():
        if check_source in ["legacy", "active", "custom"]:
            # These are ignored later in get_check_preview
            # TODO: This needs to be cleaned up. The problem here is that service_description() can not
            # calculate the description of active checks and the active checks need to be put into
            # "[source]_ignored" instead of ignored.
            continue

        if config.service_ignored(host_name,
                                  discovered_service.check_plugin_name,
                                  discovered_service.description):
            services[discovered_service.id()] = ("ignored", discovered_service,
                                                 [host_name])

    return _group_by_transition(services.values())
Ejemplo n.º 9
0
def _preview_check_source(
    host_name: HostName,
    service: Service,
    check_source: _ServiceOrigin,
) -> str:
    if check_source in {"active", "custom"} and config.service_ignored(
            host_name, None, service.description):
        return "%s_ignored" % check_source
    return check_source
Ejemplo n.º 10
0
def _preview_check_source(
    host_name: HostName,
    service: Service,
    check_source: str,
) -> str:
    if (check_source in ["legacy", "active", "custom"]
            and config.service_ignored(host_name, None, service.description)):
        return "%s_ignored" % check_source
    return check_source
Ejemplo n.º 11
0
def _discover_plugins_services(
    *,
    check_plugin_name: CheckPluginName,
    host_key: HostKey,
    parsed_sections_broker: ParsedSectionsBroker,
    on_error: OnError,
) -> Iterator[AutocheckEntry]:
    # Skip this check type if is ignored for that host
    if config.service_ignored(host_key.hostname, check_plugin_name, None):
        console.vverbose("  Skip ignored check plugin name '%s'\n" %
                         check_plugin_name)
        return

    check_plugin = agent_based_register.get_check_plugin(check_plugin_name)
    if check_plugin is None:
        console.warning("  Missing check plugin: '%s'\n" % check_plugin_name)
        return

    try:
        kwargs = get_section_kwargs(parsed_sections_broker, host_key,
                                    check_plugin.sections)
    except Exception as exc:
        if cmk.utils.debug.enabled() or on_error is OnError.RAISE:
            raise
        if on_error is OnError.WARN:
            console.warning("  Exception while parsing agent section: %s\n" %
                            exc)
        return

    if not kwargs:
        return

    disco_params = config.get_discovery_parameters(host_key.hostname,
                                                   check_plugin)
    if disco_params is not None:
        kwargs = {**kwargs, "params": disco_params}

    try:
        yield from (
            AutocheckEntry(
                check_plugin_name=check_plugin.name,
                item=service.item,
                parameters=unwrap_parameters(service.parameters),
                # Convert from APIs ServiceLabel to internal ServiceLabel
                service_labels={
                    label.name: label.value
                    for label in service.labels
                },
            ) for service in check_plugin.discovery_function(**kwargs))
    except Exception as e:
        if on_error is OnError.RAISE:
            raise
        if on_error is OnError.WARN:
            console.warning(
                "  Exception in discovery function of check plugin '%s': %s" %
                (check_plugin.name, e))
Ejemplo n.º 12
0
def _discover_plugins_services(
    *,
    check_plugin_name: CheckPluginName,
    host_name: HostName,
    ipaddress: Optional[HostAddress],
    parsed_sections_broker: ParsedSectionsBroker,
    on_error: OnError,
) -> Iterator[Service]:
    # Skip this check type if is ignored for that host
    if config.service_ignored(host_name, check_plugin_name, None):
        console.vverbose("  Skip ignored check plugin name '%s'\n" %
                         check_plugin_name)
        return

    check_plugin = agent_based_register.get_check_plugin(check_plugin_name)
    if check_plugin is None:
        console.warning("  Missing check plugin: '%s'\n" % check_plugin_name)
        return

    host_key = HostKey(
        host_name,
        ipaddress,
        SourceType.MANAGEMENT
        if check_plugin.name.is_management_name() else SourceType.HOST,
    )

    try:
        kwargs = parsed_sections_broker.get_section_kwargs(
            host_key, check_plugin.sections)
    except Exception as exc:
        if cmk.utils.debug.enabled() or on_error is OnError.RAISE:
            raise
        if on_error is OnError.WARN:
            console.warning("  Exception while parsing agent section: %s\n" %
                            exc)
        return

    if not kwargs:
        return

    disco_params = config.get_discovery_parameters(host_name, check_plugin)
    if disco_params is not None:
        kwargs["params"] = disco_params

    try:
        plugins_services = check_plugin.discovery_function(**kwargs)
        yield from _enriched_discovered_services(host_name, check_plugin.name,
                                                 plugins_services)
    except Exception as e:
        if on_error is OnError.RAISE:
            raise
        if on_error is OnError.WARN:
            console.warning(
                "  Exception in discovery function of check plugin '%s': %s" %
                (check_plugin.name, e))
Ejemplo n.º 13
0
def _node_service_source(
    *,
    check_source: str,
    host_name: HostName,
    cluster_name: HostName,
    service: Service,
) -> str:
    if host_name == cluster_name:
        return check_source

    if config.service_ignored(cluster_name, service.check_plugin_name, service.description):
        return "ignored"

    return "clustered_" + check_source
Ejemplo n.º 14
0
def _reclassify_disabled_items(
    host_name: HostName,
    services: ServicesTable,
) -> Iterable[Tuple[ServiceID, ServicesTableEntry]]:
    """Handle disabled services -> 'ignored'"""
    yield from (
        (discovered_service.id(), ("ignored", discovered_service, [host_name]))
        for check_source, discovered_service, _found_on_nodes in services.values()
        # These are ignored later in get_check_preview
        # TODO: This needs to be cleaned up. The problem here is that service_description() can not
        # calculate the description of active checks and the active checks need to be put into
        # "[source]_ignored" instead of ignored.
        if check_source not in {"legacy", "active", "custom"} and config.service_ignored(
            host_name, discovered_service.check_plugin_name, discovered_service.description))
Ejemplo n.º 15
0
def _node_service_source(
    *,
    check_source: _BasicTransition,
    host_name: HostName,
    cluster_name: HostName,
    service: Service,
) -> _Transition:
    if host_name == cluster_name:
        return check_source

    if config.service_ignored(cluster_name, service.check_plugin_name,
                              service.description):
        return "ignored"

    if check_source == "vanished":
        return "clustered_vanished"
    if check_source == "old":
        return "clustered_old"
    return "clustered_new"
Ejemplo n.º 16
0
def _snmp_scan(host_config,
               on_error="ignore",
               for_inv=False,
               do_snmp_scan=True,
               for_mgmt_board=False):
    import cmk.base.inventory_plugins as inventory_plugins

    # Make hostname globally available for scan functions.
    # This is rarely used, but e.g. the scan for if/if64 needs
    # this to evaluate if_disabled_if64_checks.
    check_api_utils.set_hostname(host_config.hostname)

    snmp.initialize_single_oid_cache(host_config)
    console.vverbose("  SNMP scan:\n")
    if not config.get_config_cache().in_binary_hostlist(
            host_config.hostname, config.snmp_without_sys_descr):
        for oid, name in [(".1.3.6.1.2.1.1.1.0", "system description"),
                          (".1.3.6.1.2.1.1.2.0", "system object")]:
            value = snmp.get_single_oid(host_config,
                                        oid,
                                        do_snmp_scan=do_snmp_scan)
            if value is None:
                raise MKSNMPError(
                    "Cannot fetch %s OID %s. This might be OK for some bogus devices. "
                    "In that case please configure the ruleset \"Hosts without system "
                    "description OID\" to tell Check_MK not to fetch the system "
                    "description and system object OIDs." % (name, oid))
    else:
        # Fake OID values to prevent issues with a lot of scan functions
        console.vverbose(
            "       Skipping system description OID "
            "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n")
        snmp.set_single_oid_cache(host_config, ".1.3.6.1.2.1.1.1.0", "")
        snmp.set_single_oid_cache(host_config, ".1.3.6.1.2.1.1.2.0", "")

    found_check_plugin_names = []
    if for_inv:
        items = inventory_plugins.inv_info.items()
    else:
        items = config.check_info.items()

    positive_found = []
    default_found = []

    for check_plugin_name, _unused_check in items:
        if config.service_ignored(host_config.hostname, check_plugin_name,
                                  None):
            continue
        else:
            if for_inv and not inventory_plugins.is_snmp_plugin(
                    check_plugin_name):
                continue
            elif not for_inv and not cmk.base.check_utils.is_snmp_check(
                    check_plugin_name):
                continue

        section_name = cmk.base.check_utils.section_name_of(check_plugin_name)
        # The scan function should be assigned to the section_name, because
        # subchecks sharing the same SNMP info of course should have
        # an identical scan function. But some checks do not do this
        # correctly
        if check_plugin_name in config.snmp_scan_functions:
            scan_function = config.snmp_scan_functions[check_plugin_name]
        elif section_name in config.snmp_scan_functions:
            scan_function = config.snmp_scan_functions[section_name]
        elif section_name in inventory_plugins.inv_info:
            scan_function = inventory_plugins.inv_info[section_name].get(
                "snmp_scan_function")
        else:
            scan_function = None

        if scan_function:
            try:

                def oid_function(oid,
                                 default_value=None,
                                 cp_name=check_plugin_name):
                    value = snmp.get_single_oid(host_config,
                                                oid,
                                                cp_name,
                                                do_snmp_scan=do_snmp_scan)
                    return default_value if value is None else value

                result = scan_function(oid_function)
                if result is not None and not isinstance(result, (str, bool)):
                    if on_error == "warn":
                        console.warning(
                            "   SNMP scan function of %s returns invalid type %s."
                            % (check_plugin_name, type(result)))
                    elif on_error == "raise":
                        raise MKGeneralException("SNMP Scan aborted.")
                elif result:
                    found_check_plugin_names.append(check_plugin_name)
                    positive_found.append(check_plugin_name)
            except MKGeneralException:
                # some error messages which we explicitly want to show to the user
                # should be raised through this
                raise
            except Exception:
                if on_error == "warn":
                    console.warning(
                        "   Exception in SNMP scan function of %s" %
                        check_plugin_name)
                elif on_error == "raise":
                    raise
        else:
            found_check_plugin_names.append(check_plugin_name)
            default_found.append(check_plugin_name)

    _output_snmp_check_plugins("SNMP scan found", positive_found)
    if default_found:
        _output_snmp_check_plugins("SNMP without scan function", default_found)

    filtered = config.filter_by_management_board(host_config.hostname,
                                                 found_check_plugin_names,
                                                 for_mgmt_board,
                                                 for_discovery=True,
                                                 for_inventory=for_inv)

    _output_snmp_check_plugins("SNMP filtered check plugin names", filtered)
    snmp.write_single_oid_cache(host_config)
    return sorted(filtered)
Ejemplo n.º 17
0
def _snmp_scan(host_config,
               on_error="ignore",
               for_inv=False,
               do_snmp_scan=True,
               for_mgmt_board=False):
    # type: (SNMPHostConfig, str, bool, bool, bool) -> Set[CheckPluginName]
    import cmk.base.inventory_plugins as inventory_plugins  # pylint: disable=import-outside-toplevel

    # Make hostname globally available for scan functions.
    # This is rarely used, but e.g. the scan for if/if64 needs
    # this to evaluate if_disabled_if64_checks.
    check_api_utils.set_hostname(host_config.hostname)

    snmp_cache.initialize_single_oid_cache(host_config)
    console.vverbose("  SNMP scan:\n")
    if not config.get_config_cache().in_binary_hostlist(host_config.hostname,
                                                        config.snmp_without_sys_descr):
        for oid, name in [(".1.3.6.1.2.1.1.1.0", "system description"),
                          (".1.3.6.1.2.1.1.2.0", "system object")]:
            value = snmp.get_single_oid(host_config, oid, do_snmp_scan=do_snmp_scan)
            if value is None:
                raise MKSNMPError(
                    "Cannot fetch %s OID %s. This might be OK for some bogus devices. "
                    "In that case please configure the ruleset \"Hosts without system "
                    "description OID\" to tell Check_MK not to fetch the system "
                    "description and system object OIDs." % (name, oid))
    else:
        # Fake OID values to prevent issues with a lot of scan functions
        console.vverbose("       Skipping system description OID "
                         "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n")
        snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.1.0", "")
        snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.2.0", "")

    if for_inv:
        these_plugin_names = [
            name for name in inventory_plugins.inv_info if inventory_plugins.is_snmp_plugin(name)
        ]
    else:
        # TODO (mo): stop converting to string!
        these_plugin_names = [str(n) for n in config.registered_snmp_sections]

    found_plugins = set()  # type: Set[CheckPluginName]

    for check_plugin_name in these_plugin_names:
        if config.service_ignored(host_config.hostname, check_plugin_name, None):
            continue

        detection_spec = _get_detection_spec_from_plugin_name(check_plugin_name,
                                                              inventory_plugins.inv_info)

        if detection_spec is None:
            console.warning("   SNMP check %s: Could not detect specifications for plugin" %
                            check_plugin_name)

            continue

        try:

            def oid_function(oid, default_value=None, cp_name=check_plugin_name):
                # type: (OID, Optional[DecodedString], Optional[CheckPluginName]) -> Optional[DecodedString]
                value = snmp.get_single_oid(host_config, oid, cp_name, do_snmp_scan=do_snmp_scan)
                return default_value if value is None else value

            if callable(detection_spec):
                result = detection_spec(oid_function)
            else:
                result = _evaluate_snmp_detection(oid_function, detection_spec)

            if result is not None and not isinstance(result, (str, bool)):
                if on_error == "warn":
                    console.warning("   SNMP scan function of %s returns invalid type %s." %
                                    (check_plugin_name, type(result)))
                elif on_error == "raise":
                    raise MKGeneralException("SNMP Scan aborted.")
            elif result:
                found_plugins.add(check_plugin_name)
        except MKGeneralException:
            # some error messages which we explicitly want to show to the user
            # should be raised through this
            raise
        except Exception:
            if on_error == "warn":
                console.warning("   Exception in SNMP scan function of %s" % check_plugin_name)
            elif on_error == "raise":
                raise

    _output_snmp_check_plugins("SNMP scan found", found_plugins)

    filtered = config.filter_by_management_board(
        host_config.hostname,
        found_plugins,
        for_mgmt_board,
        for_discovery=True,
        for_inventory=for_inv,
    )

    _output_snmp_check_plugins("SNMP filtered check plugin names", filtered)
    snmp_cache.write_single_oid_cache(host_config)
    return filtered