Exemplo n.º 1
0
    def _handle_entry(self, checkname, item, params):
        # type: (str, Text, Any) -> CheckTable
        check_table = {}  # type: CheckTable
        hostname = self._host_config.hostname

        if not self._is_checkname_valid(checkname):
            return {}

        descr = config.service_description(hostname, checkname, item)
        if self.skip_ignored and config.service_ignored(
                hostname, checkname, descr):
            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,
                descr,
                part_of_clusters=self._host_config.part_of_clusters)

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

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

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

        return check_table
Exemplo n.º 2
0
    def _get_static_check_entries(self, host_config):
        # type: (config.HostConfig) -> List[Service]
        entries = []  # type: List[Service]
        for _checkgroup_name, check_plugin_name, item, params in host_config.static_checks:
            # Make sure, that for dictionary based checks at least those keys
            # defined in the factory settings are present in the parameters
            # TODO: Isn't this done during checking for all checks in more generic code?
            if isinstance(params,
                          dict) and check_plugin_name in config.check_info:
                def_levels_varname = config.check_info[check_plugin_name].get(
                    "default_levels_variable")
                if def_levels_varname:
                    for key, value in config.factory_settings.get(
                            def_levels_varname, {}).items():
                        if key not in params:
                            params[key] = value

            descr = config.service_description(host_config.hostname,
                                               check_plugin_name, item)
            entries.append(Service(check_plugin_name, item, descr, params))

        # Note: We need to reverse the order of the static_checks. This is
        # because users assume that earlier rules have precedence over later
        # ones. For static checks that is important if there are two rules for
        # a host with the same combination of check type and item.
        return list(reversed(entries))
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
def _parse_autocheck_entry(hostname, entry):
    # type: (str, Union[ast.Tuple, ast.Dict]) -> Optional[DiscoveredService]
    if isinstance(entry, ast.Tuple):
        ast_check_plugin_name, ast_item, ast_parameters_unresolved = _parse_pre_16_tuple_autocheck_entry(
            entry)
        ast_service_labels = ast.Dict()
    elif isinstance(entry, ast.Dict):
        ast_check_plugin_name, ast_item, ast_parameters_unresolved, ast_service_labels = \
            _parse_dict_autocheck_entry(entry)
    else:
        raise Exception("Invalid autocheck: Wrong type: %r" % entry)

    if not isinstance(ast_check_plugin_name, ast.Str):
        raise Exception("Invalid autocheck: Wrong check plugin type: %r" %
                        ast_check_plugin_name)
    check_plugin_name = ast_check_plugin_name.s

    item = None  # type: Item
    if isinstance(ast_item, ast.Str):
        item = ast_item.s
    elif isinstance(ast_item, ast.Num):
        item = int(ast_item.n)
    elif isinstance(ast_item, ast.Name) and ast_item.id == "None":
        item = None
    else:
        raise Exception("Invalid autocheck: Wrong item type: %r" % ast_item)

    # With Check_MK 1.2.7i3 items are now defined to be unicode
    # strings. Convert items from existing autocheck files for
    # compatibility.
    if isinstance(item, str):
        item = config.decode_incoming_string(item)

    if isinstance(ast_parameters_unresolved, ast.Name):
        # Keep check variable names as they are: No evaluation of check parameters
        parameters_unresolved = ast_parameters_unresolved.id
    else:
        # Other structures, like dicts, lists and so on should also be loaded as repr() str
        # instead of an interpreted structure
        parameters_unresolved = repr(
            eval(
                compile(ast.Expression(ast_parameters_unresolved),
                        filename="<ast>",
                        mode="eval")))

    try:
        description = config.service_description(hostname, check_plugin_name,
                                                 item)
    except Exception:
        return None  # ignore

    return DiscoveredService(
        check_plugin_name,
        item,
        description,
        parameters_unresolved,
        service_labels=_parse_discovered_service_label_from_ast(
            ast_service_labels))
Exemplo n.º 5
0
def update_service_info(config_cache, hostnames, args):
    for hostname in hostnames:
        for check_plugin_name, item, _ in config_cache.get_autochecks_of(
                hostname):
            if check_plugin_name in CHECKS_USING_DF_INCLUDE:
                servicedesc = config.service_description(
                    hostname, check_plugin_name, item)
                update_files(args, hostname, servicedesc, item, 'cmc')
                update_files(args, hostname, servicedesc, item, 'pnp4nagios')
Exemplo n.º 6
0
def update_service_info(config_cache, hostnames, args):
    pnp_files_present = False
    if args.dry_run:
        logger.info("Files to be updated:")

    for hostname in hostnames:
        for service in config_cache.get_autochecks_of(hostname):
            if service.check_plugin_name in CHECKS_USING_DF_INCLUDE:
                servicedesc = config.service_description(hostname, service.check_plugin_name,
                                                         service.item)
                update_files(args, hostname, servicedesc, service.item, 'cmc')
                pnp_files_present |= update_files(args, hostname, servicedesc, service.item,
                                                  'pnp4nagios')

    if args.dry_run and pnp_files_present:
        logger.info("Journal files will be updates")
        return
Exemplo n.º 7
0
def _parse_autocheck_entry(hostname, entry):
    # type: (str, Union[ast.Tuple, ast.Dict]) -> Optional[DiscoveredService]
    if isinstance(entry, ast.Tuple):
        ast_check_plugin_name, ast_item, ast_parameters_unresolved = _parse_pre_16_tuple_autocheck_entry(
            entry)
        ast_service_labels = ast.Dict()
    elif isinstance(entry, ast.Dict):
        ast_check_plugin_name, ast_item, ast_parameters_unresolved, ast_service_labels = \
            _parse_dict_autocheck_entry(entry)
    else:
        raise Exception("Invalid autocheck: Wrong type: %r" % entry)

    if not isinstance(ast_check_plugin_name, ast.Str):
        raise Exception("Invalid autocheck: Wrong check plugin type: %r" %
                        ast_check_plugin_name)
    check_plugin_name = ast_check_plugin_name.s

    item = None  # type: Item
    if isinstance(ast_item, ast.Str):
        item = ast_item.s
    elif isinstance(ast_item, ast.Num):
        item = int(ast_item.n)
    elif isinstance(ast_item, ast.Name) and ast_item.id == "None":
        item = None
    else:
        raise Exception("Invalid autocheck: Wrong item type: %r" % ast_item)

    # With Check_MK 1.2.7i3 items are now defined to be unicode
    # strings. Convert items from existing autocheck files for
    # compatibility.
    if isinstance(item, str):
        item = config.decode_incoming_string(item)

    try:
        description = config.service_description(hostname, check_plugin_name,
                                                 item)
    except Exception:
        return None  # ignore

    return DiscoveredService(
        check_plugin_name,
        item,
        description,
        _parse_unresolved_parameters_from_ast(ast_parameters_unresolved),
        service_labels=_parse_discovered_service_label_from_ast(
            ast_service_labels))
Exemplo n.º 8
0
    def _read_raw_autochecks_of(self, hostname):
        # type: (str) -> List[Service]
        """Read automatically discovered checks of one host"""
        basedir = cmk.utils.paths.autochecks_dir
        filepath = basedir + '/' + hostname + '.mk'

        result = []  # type: List[Service]
        if not os.path.exists(filepath):
            return result

        check_config = config.get_check_variables()
        try:
            cmk_base.console.vverbose("Loading autochecks from %s\n", filepath)
            autochecks_raw = eval(
                file(filepath).read().decode("utf-8"), check_config,
                check_config)  # type: List[Dict]
        except SyntaxError as e:
            cmk_base.console.verbose("Syntax error in file %s: %s\n",
                                     filepath,
                                     e,
                                     stream=sys.stderr)
            if cmk.utils.debug.enabled():
                raise
            return result
        except Exception as e:
            cmk_base.console.verbose("Error in file %s:\n%s\n",
                                     filepath,
                                     e,
                                     stream=sys.stderr)
            if cmk.utils.debug.enabled():
                raise
            return result

        for entry in autochecks_raw:
            labels = DiscoveredServiceLabels()
            for label_id, label_value in entry["service_labels"].items():
                labels.add_label(ServiceLabel(label_id, label_value))

            # With Check_MK 1.2.7i3 items are now defined to be unicode strings. Convert
            # items from existing autocheck files for compatibility. TODO remove this one day
            item = entry["item"]
            if isinstance(item, str):
                item = config.decode_incoming_string(item)

            if not isinstance(entry["check_plugin_name"], six.string_types):
                raise MKGeneralException(
                    "Invalid entry '%r' in check table of host '%s': "
                    "The check type must be a string." % (entry, hostname))

            try:
                description = config.service_description(
                    hostname, entry["check_plugin_name"], item)
            except Exception:
                continue  # ignore

            result.append(
                Service(
                    check_plugin_name=str(entry["check_plugin_name"]),
                    item=item,
                    description=description,
                    parameters=entry["parameters"],
                    service_labels=labels,
                ))

        return result
Exemplo n.º 9
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
Exemplo n.º 10
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
Exemplo n.º 11
0
def service_description(hostname, check_plugin_name, item):
    # type: (str, str, Text) -> Text
    _load_config()
    return config.service_description(hostname, check_plugin_name, item)