Esempio n. 1
0
 def _read_autochecks_of(self, hostname):
     # type: (str) -> List[Service]
     """Read automatically discovered checks of one host"""
     autochecks = []
     for service in self._read_raw_autochecks_cached(hostname):
         autochecks.append(
             Service(
                 check_plugin_name=service.check_plugin_name,
                 item=service.item,
                 description=service.description,
                 parameters=config.compute_check_parameters(hostname, service.check_plugin_name,
                                                            service.item, service.parameters),
                 service_labels=service.service_labels,
             ))
     return autochecks
Esempio n. 2
0
    def _get_clustered_services(self, hostname, skip_autochecks):
        # type: (str, bool) -> CheckTable
        check_table = {}  # type: CheckTable
        for node in self._host_config.nodes or []:
            # TODO: Cleanup this to work exactly like the logic above (for a single host)
            node_config = self._config_cache.get_host_config(node)
            node_checks = self._get_static_check_entries(node_config)
            if not skip_autochecks:
                node_checks += self._config_cache.get_autochecks_of(node)

            for service in node_checks:
                if self._config_cache.host_of_clustered_service(node,
                                                                service.description) != hostname:
                    continue

                cluster_params = config.compute_check_parameters(hostname,
                                                                 service.check_plugin_name,
                                                                 service.item, service.parameters)
                cluster_service = Service(service.check_plugin_name, service.item,
                                          service.description, cluster_params,
                                          service.service_labels)
                check_table.update(self._handle_service(cluster_service))
        return check_table
Esempio n. 3
0
    def get(self, remove_duplicates, use_cache, skip_autochecks, filter_mode,
            skip_ignored):
        # type: (bool, bool, bool, Optional[str], bool) -> CheckTable
        """Returns check table for a specific host

        Format of check table is: {(checkname, item): (params, description)}

        filter_mode: None                -> default, returns only checks for this host
        filter_mode: "only_clustered"    -> returns only checks belonging to clusters
        filter_mode: "include_clustered" -> returns checks of own host, including clustered checks
        """
        # TODO: Clean them up
        self.remove_duplicates = remove_duplicates
        self.use_cache = use_cache
        self.skip_autochecks = skip_autochecks
        self.filter_mode = filter_mode
        self.skip_ignored = skip_ignored
        hostname = self._host_config.hostname

        if self._host_config.is_ping_host:
            skip_autochecks = True

        # speed up multiple lookup of same host
        check_table_cache = self._config_cache.check_table_cache
        table_cache_id = hostname, filter_mode

        if not skip_autochecks and use_cache and table_cache_id in check_table_cache:
            # TODO: The whole is_dual_host handling needs to be cleaned up. The duplicate checking
            #       needs to be done in all cases since a host can now have a lot of different data
            #       sources.
            if remove_duplicates and self._host_config.is_dual_host:
                return remove_duplicate_checks(
                    check_table_cache[table_cache_id])
            return check_table_cache[table_cache_id]

        check_table = {}  # type: CheckTable

        # Now process all entries that are specific to the host
        # in search (single host) or that might match the host.
        if not skip_autochecks:
            for checkname, item, params in self._config_cache.get_autochecks_of(
                    hostname):
                check_table.update(self._handle_entry(checkname, item, params))

        for checkname, item, params in self._get_static_check_entries(
                self._host_config):
            check_table.update(self._handle_entry(checkname, item, params))

        # Now add checks a cluster might receive from its nodes
        if self._host_config.is_cluster:
            for node in self._host_config.nodes or []:
                # TODO: Cleanup this to work exactly like the logic above (for a single host)
                node_config = self._config_cache.get_host_config(node)
                node_checks = self._get_static_check_entries(node_config)
                if not skip_autochecks:
                    node_checks += self._config_cache.get_autochecks_of(node)

                for checkname, item, params in node_checks:
                    descr = config.service_description(node, checkname, item)

                    if hostname == self._config_cache.host_of_clustered_service(
                            node, descr):
                        cluster_params = config.compute_check_parameters(
                            hostname, checkname, item, params)
                        check_table.update(
                            self._handle_entry(checkname, item,
                                               cluster_params))

        # Remove dependencies to non-existing services
        all_descr = set([
            descr for ((checkname, item), (params, descr,
                                           deps)) in check_table.iteritems()
        ])
        for (checkname, item), (params, descr,
                                deps) in check_table.iteritems():
            deeps = deps[:]
            del deps[:]
            for d in deeps:
                if d in all_descr:
                    deps.append(d)

        if not skip_autochecks and use_cache:
            check_table_cache[table_cache_id] = check_table

        if remove_duplicates:
            return remove_duplicate_checks(check_table)
        return check_table
Esempio n. 4
0
def get_check_table(hostname,
                    remove_duplicates=False,
                    use_cache=True,
                    skip_autochecks=False,
                    filter_mode=None,
                    skip_ignored=True):

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

    if host_config.is_ping_host:
        skip_autochecks = True

    # speed up multiple lookup of same host
    check_table_cache = config_cache.check_table_cache
    table_cache_id = hostname, filter_mode

    if not skip_autochecks and use_cache and table_cache_id in check_table_cache:
        # TODO: The whole is_dual_host handling needs to be cleaned up. The duplicate checking
        #       needs to be done in all cases since a host can now have a lot of different data
        #       sources.
        if remove_duplicates and host_config.is_dual_host:
            return remove_duplicate_checks(check_table_cache[table_cache_id])
        return check_table_cache[table_cache_id]

    check_table = {}

    single_host_checks = config_cache.single_host_checks
    multi_host_checks = config_cache.multi_host_checks

    hosttags = host_config.tags

    # Just a local cache and its function
    is_checkname_valid_cache = {}

    def is_checkname_valid(checkname):
        if checkname in is_checkname_valid_cache:
            return is_checkname_valid_cache[checkname]

        passed = True
        if checkname not in config.check_info:
            passed = False

        # Skip SNMP checks for non SNMP hosts (might have been discovered before with other
        # agent setting. Remove them without rediscovery). Same for agent based checks.
        elif not host_config.is_snmp_host and config_cache.is_snmp_check(checkname) and \
           (not host_config.has_management_board or host_config.management_protocol != "snmp"):
            passed = False

        elif not host_config.is_agent_host and config_cache.is_tcp_check(checkname):
            passed = False

        is_checkname_valid_cache[checkname] = passed
        return passed

    def handle_entry(entry):
        num_elements = len(entry)
        if num_elements == 3:  # from autochecks
            hostlist = hostname
            checkname, item, params = entry
            tags = []
        elif num_elements == 4:
            hostlist, checkname, item, params = entry
            tags = []
        elif num_elements == 5:
            tags, hostlist, checkname, item, params = entry
            if not isinstance(tags, list):
                raise MKGeneralException(
                    "Invalid entry '%r' in check table. First entry must be list of host tags." %
                    (entry,))

        else:
            raise MKGeneralException(
                "Invalid entry '%r' in check table. It has %d entries, but must have 4 or 5." %
                (entry, len(entry)))

        # hostlist list might be:
        # 1. a plain hostname (string)
        # 2. a list of hostnames (list of strings)
        # Hostnames may be tagged. Tags are removed.
        # In autochecks there are always single untagged hostnames. We optimize for that.
        if isinstance(hostlist, str):
            if hostlist != hostname:
                return  # optimize most common case: hostname mismatch
            hostlist = [hostlist]
        elif isinstance(hostlist[0], str):
            pass  # regular case: list of hostnames
        elif hostlist != []:
            raise MKGeneralException("Invalid entry '%r' in check table. Must be single hostname "
                                     "or list of hostnames" % hostlist)

        if not is_checkname_valid(checkname):
            return

        if config.hosttags_match_taglist(hosttags, tags) and \
               config.in_extraconf_hostlist(hostlist, hostname):
            descr = config.service_description(hostname, checkname, item)
            if skip_ignored and config.service_ignored(hostname, checkname, descr):
                return

            if not host_config.part_of_clusters:
                svc_is_mine = True
            else:
                svc_is_mine = hostname == config_cache.host_of_clustered_service(
                    hostname, descr, part_of_clusters=host_config.part_of_clusters)

            if filter_mode is None and not svc_is_mine:
                return

            elif filter_mode == "only_clustered" and svc_is_mine:
                return

            deps = config.service_depends_on(hostname, descr)
            check_table[(checkname, item)] = (params, descr, deps)

    # Now process all entries that are specific to the host
    # in search (single host) or that might match the host.
    if not skip_autochecks:
        for entry in config_cache.get_autochecks_of(hostname):
            handle_entry(entry)

    for entry in single_host_checks.get(hostname, []):
        handle_entry(entry)

    for entry in multi_host_checks:
        handle_entry(entry)

    # Now add checks a cluster might receive from its nodes
    if host_config.is_cluster:
        single_host_checks = cmk_base.config_cache.get_dict("single_host_checks")

        for node in host_config.nodes:
            node_checks = single_host_checks.get(node, [])
            if not skip_autochecks:
                node_checks = node_checks + config_cache.get_autochecks_of(node)
            for entry in node_checks:
                if len(entry) == 4:
                    entry = entry[1:]  # drop hostname from single_host_checks
                checkname, item, params = entry
                descr = config.service_description(node, checkname, item)
                if hostname == config_cache.host_of_clustered_service(node, descr):
                    cluster_params = config.compute_check_parameters(hostname, checkname, item,
                                                                     params)
                    handle_entry((hostname, checkname, item, cluster_params))

    # Remove dependencies to non-existing services
    all_descr = set(
        [descr for ((checkname, item), (params, descr, deps)) in check_table.iteritems()])
    for (checkname, item), (params, descr, deps) in check_table.iteritems():
        deeps = deps[:]
        del deps[:]
        for d in deeps:
            if d in all_descr:
                deps.append(d)

    if not skip_autochecks and use_cache:
        check_table_cache[table_cache_id] = check_table

    if remove_duplicates:
        return remove_duplicate_checks(check_table)
    return check_table