Exemple #1
0
def _extract_snmp_sections(
    inf_info: Dict[InventoryPluginNameStr, InventoryInfo],
    plugin_file_lookup: Dict[str, str],
) -> None:
    for plugin_name, plugin_info in sorted(inv_info.items()):
        if 'snmp_info' not in plugin_info:
            continue
        section_name = section_name_of(plugin_name)
        if isinstance(agent_based_register.get_section_plugin(SectionName(section_name)),
                      SNMPSectionPlugin):
            continue

        fallback_files = ([_include_file_path(i) for i in plugin_info.get('includes', [])] +
                          [plugin_file_lookup[plugin_name]])

        try:
            agent_based_register.add_section_plugin(
                create_snmp_section_plugin_from_legacy(
                    section_name,
                    {},
                    plugin_info['snmp_scan_function'],
                    plugin_info['snmp_info'],
                    scan_function_fallback_files=fallback_files,
                ))
        except (NotImplementedError, KeyError, AssertionError, ValueError):
            msg = config.AUTO_MIGRATION_ERR_MSG % ('section', plugin_name)
            if cmk.utils.debug.enabled():
                raise MKGeneralException(msg)
            console.warning(msg)
Exemple #2
0
def _snmp_scan_find_sections(
    sections: Iterable[SNMPScanSection],
    *,
    do_snmp_scan: bool,
    on_error: str,
    backend: ABCSNMPBackend,
) -> Set[SectionName]:
    found_sections: Set[SectionName] = set()
    for name, specs in sections:
        try:
            if _evaluate_snmp_detection(
                    specs,
                    name,
                    do_snmp_scan,
                    backend=backend,
            ):
                found_sections.add(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" % name)
            elif on_error == "raise":
                raise
    return found_sections
Exemple #3
0
def _find_sections(
    sections: Iterable[SNMPScanSection],
    *,
    on_error: str,
    backend: ABCSNMPBackend,
) -> Set[SectionName]:
    found_sections: Set[SectionName] = set()
    for name, specs in sections:
        oid_value_getter = functools.partial(
            snmp_modes.get_single_oid,
            section_name=name,
            backend=backend,
        )
        try:
            if evaluate_snmp_detection(
                    detect_spec=specs,
                    oid_value_getter=oid_value_getter,
            ):
                found_sections.add(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" %
                                name)
            elif on_error == "raise":
                raise
    return found_sections
Exemple #4
0
def _commandline_discovery_on_host(
    host_name: HostName,
    ipaddress: Optional[HostAddress],
    parsed_sections_broker: ParsedSectionsBroker,
    run_plugin_names: Container[CheckPluginName],
    only_new: bool,
    *,
    load_labels: bool,
    only_host_labels: bool,
    on_error: OnError,
) -> None:

    section.section_step("Analyse discovered host labels")

    host_labels = analyse_node_labels(
        host_name=host_name,
        ipaddress=ipaddress,
        parsed_sections_broker=parsed_sections_broker,
        load_labels=load_labels,
        save_labels=True,
        on_error=on_error,
    )

    count = len(host_labels.new) if host_labels.new else (
        "no new" if only_new else "no")
    section.section_success(f"Found {count} host labels")

    if only_host_labels:
        return

    section.section_step("Analyse discovered services")

    service_result = analyse_discovered_services(
        host_name=host_name,
        ipaddress=ipaddress,
        parsed_sections_broker=parsed_sections_broker,
        run_plugin_names=run_plugin_names,
        only_new=only_new,
        on_error=on_error,
    )

    # TODO (mo): for the labels the corresponding code is in _host_labels.
    # We should put the persisting in one place.
    autochecks.save_autochecks_file(host_name, service_result.present)

    new_per_plugin = Counter(s.check_plugin_name for s in service_result.new)
    for name, count in sorted(new_per_plugin.items()):
        console.verbose("%s%3d%s %s\n" %
                        (tty.green + tty.bold, count, tty.normal, name))

    count = len(service_result.new) if service_result.new else (
        "no new" if only_new else "no")
    section.section_success(f"Found {count} services")

    for detail in check_parsing_errors(
            parsed_sections_broker.parsing_errors()).details:
        console.warning(detail)
Exemple #5
0
def _prepare_check_command(command_spec: CheckCommandArguments,
                           hostname: HostName,
                           description: Optional[ServiceName]) -> str:
    """Prepares a check command for execution by Checkmk

    In case a list is given it quotes the single elements. It also prepares password store entries
    for the command line. These entries will be completed by the executed program later to get the
    password from the password store.
    """
    passwords: List[Tuple[str, str, str]] = []
    formated: List[str] = []
    stored_passwords = cmk.utils.password_store.load()
    for arg in command_spec:
        if isinstance(arg, (int, float)):
            formated.append("%s" % arg)

        elif isinstance(arg, str):
            formated.append(cmk.utils.quote_shell_string(arg))

        elif isinstance(arg, tuple) and len(arg) == 3:
            pw_ident, preformated_arg = arg[1:]
            try:
                password = stored_passwords[pw_ident]
            except KeyError:
                if hostname and description:
                    descr = ' used by service "%s" on host "%s"' % (
                        description, hostname)
                elif hostname:
                    descr = ' used by host host "%s"' % (hostname)
                else:
                    descr = ""

                console.warning(
                    'The stored password "%s"%s does not exist (anymore).' %
                    (pw_ident, descr))
                password = "******"

            pw_start_index = str(preformated_arg.index("%s"))
            formated.append(
                cmk.utils.quote_shell_string(preformated_arg %
                                             ("*" * len(password))))
            passwords.append((str(len(formated)), pw_start_index, pw_ident))

        else:
            raise MKGeneralException("Invalid argument for command line: %r" %
                                     (arg, ))

    if passwords:
        formated = [
            "--pwstore=%s" % ",".join(["@".join(p) for p in passwords])
        ] + formated

    return " ".join(formated)
Exemple #6
0
def do_restore(tarname):
    # type: (str) -> None
    console.verbose("Restoring from '%s'...\n", tarname)

    if not os.path.exists(tarname):
        raise MKGeneralException("Unable to restore: File does not exist")

    for name, path, canonical_name, descr, is_dir in backup_paths():
        absdir = os.path.abspath(path)
        if is_dir:
            basedir = absdir
            filename = "."
            if os.path.exists(absdir):
                console.verbose("  Deleting old contents of '%s'\n", absdir)
                # The path might point to a symbalic link. So it is no option
                # to call shutil.rmtree(). We must delete just the contents
                for f in os.listdir(absdir):
                    if f not in ['.', '..']:
                        try:
                            p = absdir + "/" + f
                            if os.path.isdir(p):
                                shutil.rmtree(p)
                            else:
                                os.remove(p)
                        except Exception as e:
                            console.warning("  Cannot delete %s: %s", p, e)
        else:
            basedir = os.path.dirname(absdir)
            filename = os.path.basename(absdir)
            canonical_path = basedir + "/" + canonical_name
            if os.path.exists(canonical_path):
                console.verbose("  Deleting old version of '%s'\n",
                                canonical_path)
                os.remove(canonical_path)

        if not os.path.exists(basedir):
            console.verbose("  Creating directory %s\n", basedir)
            os.makedirs(basedir)

        console.verbose("  Extracting %s (%s)\n", descr, absdir)
        tar = tarfile.open(tarname, "r:gz")
        if is_dir:
            subtar = tarfile.open(fileobj=tar.extractfile(name + ".tar"))
            if filename == ".":
                subtar.extractall(basedir)
            elif filename in subtar.getnames():
                subtar.extract(filename, basedir)
            subtar.close()
        elif filename in tar.getnames():
            tar.extract(filename, basedir)
        tar.close()

    console.verbose("Successfully restored backup.\n")
def warn_about_network_ports(old_site_id: SiteId, new_site_id: SiteId) -> None:
    if not Path("/omd/sites", old_site_id).exists():
        return  # Site was not copied

    logger.info("")
    warning(
        "Network port configuration may need your attention\n\n"
        "It seems like you copied an existing site. In case you plan to use both on the same "
        "system, you may have to review the network port configuration of your sites. Two sites"
        "with the same configuration may cause network port conflicts."
        "For example if you enabled livestatus to listen via TCP or enabled the Event Console "
        "to listen for incoming Syslog messages or SNMP traps, you may have to update the "
        "configuration in one of the sites to resolve the conflicts.\n")
Exemple #8
0
def warn_about_renamed_remote_site(old_site_id: SiteId,
                                   new_site_id: SiteId) -> None:
    """Warn user about central site that needs to be updated manually

    Detect whether or not this is a remote site and issue a warning to let the user known"""
    if not is_wato_slave_site():
        return

    logger.info("")
    warning(
        "You renamed a distributed remote site.\n\nTo make your distributed "
        "setup work again, you will have to update the \"Distributed Monitoring\" "
        "configuration in your central site.\n")
def warn_about_configs_to_review(old_site_id: SiteId,
                                 new_site_id: SiteId) -> None:
    logger.info("")
    warning(
        "Some configs may need to be reviewed\n\n"
        "Parts of the site configuration cannot be migrated automatically. The following\n"
        "parts of the configuration may have to be reviewed and adjusted manually:\n\n"
        "- Custom bookmarks (in users bookmark lists)\n"
        "- Hard coded site filters in custom dashboards, views, reports\n"
        "- Path in rrdcached journal files\n"
        "- NagVis maps or custom NagVis backend settings\n"
        "- Notification rule \"site\" conditions\n"
        "- Event Console rule \"site\" conditions\n"
        "- \"site\" field in \"Agent updater (Linux, Windows, Solaris)\" rules (CEE/CME only)\n"
        "- Alert handler rule \"site\" conditions (CEE/CME only)\n")
Exemple #10
0
def _extract_inventory_plugins(inf_info: Dict[InventoryPluginNameStr, InventoryInfo],) -> None:
    for plugin_name, plugin_info in sorted(inv_info.items()):
        try:
            agent_based_register.add_inventory_plugin(
                create_inventory_plugin_from_legacy(
                    plugin_name,
                    plugin_info,
                    # count inherited extra sections from check plugin:
                    len(config.check_info.get(plugin_name, {}).get("extra_sections", [])),
                ))
        except NotImplementedError:
            msg = config.AUTO_MIGRATION_ERR_MSG % ('inventory', plugin_name)
            if cmk.utils.debug.enabled():
                raise MKGeneralException(msg)
            console.warning(msg)
Exemple #11
0
def _do_inv_for_realhost(
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
    *,
    multi_host_sections: MultiHostSections,
    run_only_plugin_names: Optional[Set[InventoryPluginName]],
) -> InventoryTrees:
    tree_aggregator = _TreeAggregator()
    _set_cluster_property(tree_aggregator.trees.inventory, host_config)

    section.section_step("Executing inventory plugins")
    for inventory_plugin in agent_based_register.iter_all_inventory_plugins():
        if run_only_plugin_names and inventory_plugin.name not in run_only_plugin_names:
            continue

        kwargs = multi_host_sections.get_section_kwargs(
            HostKey(host_config.hostname, ipaddress, SourceType.HOST),
            inventory_plugin.sections,
        )
        if not kwargs:
            console.vverbose(" %s%s%s%s: skipped (no data)\n", tty.yellow,
                             tty.bold, inventory_plugin.name, tty.normal)
            continue

        # 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!

        exception = tree_aggregator.aggregate_results(
            inventory_plugin.inventory_function(**kwargs),
            inventory_plugin.name,
        )
        if exception:
            console.warning(" %s%s%s%s: failed: %s", tty.red, tty.bold,
                            inventory_plugin.name, tty.normal, exception)
        else:
            console.verbose(" %s%s%s%s", tty.green, tty.bold,
                            inventory_plugin.name, tty.normal)
            console.vverbose(": ok\n")
    console.verbose("\n")

    tree_aggregator.trees.inventory.normalize_nodes()
    tree_aggregator.trees.status_data.normalize_nodes()
    return tree_aggregator.trees
Exemple #12
0
def _do_inv_for_realhost(
    host_config: config.HostConfig,
    ipaddress: Optional[HostAddress],
    *,
    parsed_sections_broker: ParsedSectionsBroker,
    run_plugin_names: Container[InventoryPluginName],
) -> InventoryTrees:
    tree_aggregator = TreeAggregator()
    _set_cluster_property(tree_aggregator.trees.inventory, host_config)

    section.section_step("Executing inventory plugins")
    for inventory_plugin in agent_based_register.iter_all_inventory_plugins():
        if inventory_plugin.name not in run_plugin_names:
            continue

        for source_type in (SourceType.HOST, SourceType.MANAGEMENT):
            kwargs = get_section_kwargs(
                parsed_sections_broker,
                HostKey(host_config.hostname, ipaddress, source_type),
                inventory_plugin.sections,
            )
            if not kwargs:
                console.vverbose(" %s%s%s%s: skipped (no data)\n", tty.yellow,
                                 tty.bold, inventory_plugin.name, tty.normal)
                continue

            # 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(
                    inventory_plugin.inventory_ruleset_name)

            exception = tree_aggregator.aggregate_results(
                inventory_plugin.inventory_function(**kwargs), )
            if exception:
                console.warning(" %s%s%s%s: failed: %s", tty.red, tty.bold,
                                inventory_plugin.name, tty.normal, exception)
            else:
                console.verbose(" %s%s%s%s", tty.green, tty.bold,
                                inventory_plugin.name, tty.normal)
                console.vverbose(": ok\n")
    console.verbose("\n")

    tree_aggregator.trees.inventory.normalize_nodes()
    tree_aggregator.trees.status_data.normalize_nodes()
    return tree_aggregator.trees
Exemple #13
0
    def aggregate_results(
        self,
        inventory_generator: InventoryResult,
        plugin_name: InventoryPluginName,
    ) -> None:

        try:
            inventory_items = list(inventory_generator)
        except Exception as exc:
            if cmk.utils.debug.enabled():
                raise
            console.warning(f"Error in inventory plugin {plugin_name}: {exc}")
            return

        for item in inventory_items:
            if isinstance(item, Attributes):
                self._integrate_attributes(item)
            elif isinstance(item, TableRow):
                self._integrate_table_row(item)
            else:  # can't happen
                raise NotImplementedError()
Exemple #14
0
def _aggregate_inventory_results(
    inventory_generator: InventoryGenerator,
    inventory_tree: StructuredDataTree,
    status_data_tree: StructuredDataTree,
) -> None:

    try:
        inventory_items = list(inventory_generator)
    except Exception as exc:
        if cmk.utils.debug.enabled():
            raise
        console.warning("Error in plugin: %s" % exc)
        return

    for item in inventory_items:
        if isinstance(item, Attributes):
            _integrate_attributes(item, inventory_tree, status_data_tree)
        elif isinstance(item, TableRow):
            _integrate_table_row(item, inventory_tree, status_data_tree)
        else:  # can't happen
            raise NotImplementedError()
Exemple #15
0
    def get_sub_options(
        self, all_opts: Options
    ) -> Optional[Dict[OptionName, Union[Argument, int, bool]]]:
        if not self.sub_options:
            return None

        options: Dict[OptionName, Union[Argument, int, bool]] = {}

        for o, a in all_opts:
            for option in self.sub_options:
                if o not in option.options():
                    continue

                if option.is_deprecated_option(o):
                    console.warning("%r is deprecated in favour of option %r",
                                    o, option.name())

                if a and not option.takes_argument():
                    raise MKGeneralException("No argument to %s expected." % o)

                val: Union[Argument, bool] = a
                if not option.takes_argument():
                    if option.count:
                        value = options.setdefault(option.name(), 0)
                        if not isinstance(value, int):
                            raise TypeError()
                        options[option.name()] = value + 1
                        continue
                    val = True
                else:
                    if option.argument_conv:
                        try:
                            val = option.argument_conv(a)
                        except ValueError:
                            raise MKGeneralException("%s: Invalid argument" %
                                                     o)

                options[option.name()] = val

        return options
Exemple #16
0
def _commandline_inventory_on_host(
    *,
    host_config: config.HostConfig,
    run_plugin_names: Container[InventoryPluginName],
    selected_sections: SectionNameCollection,
) -> None:

    section.section_step("Inventorizing")

    inv_result = _inventorize_host(
        host_config=host_config,
        selected_sections=selected_sections,
        run_plugin_names=run_plugin_names,
        retentions_tracker=RetentionsTracker([]),
    )

    for subresult in check_parsing_errors(errors=inv_result.parsing_errors):
        for line in subresult.details:
            console.warning(line)

    # TODO: inv_results.source_results is completely ignored here.
    # We should process the results to make errors visible on the console
    count_i = inv_result.trees.inventory.count_entries()
    count_s = inv_result.trees.status_data.count_entries()
    section.section_success(f"Found {count_i} inventory entries")
    section.section_success(f"Found {count_s} status entries")

    if not host_config.inventory_export_hooks:
        return

    section.section_step("Execute inventory export hooks")

    _run_inventory_export_hooks(host_config, inv_result.trees.inventory)

    count = len(host_config.inventory_export_hooks)
    section.section_success(f"Sucessfully ran {count} export hooks")
Exemple #17
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))
Exemple #18
0
def commandline_inventory(
    hostnames: List[HostName],
    *,
    selected_sections: SectionNameCollection,
    run_plugin_names: Container[InventoryPluginName] = EVERYTHING,
) -> None:
    store.makedirs(cmk.utils.paths.inventory_output_dir)
    store.makedirs(cmk.utils.paths.inventory_archive_dir)

    for hostname in hostnames:
        section.section_begin(hostname)
        try:
            host_config = config.HostConfig.make_host_config(hostname)
            inv_result = _inventorize_host(
                host_config=host_config,
                selected_sections=selected_sections,
                run_plugin_names=run_plugin_names,
            )

            _run_inventory_export_hooks(host_config,
                                        inv_result.trees.inventory)
            # TODO: inv_results.source_results is completely ignored here.
            # We should process the results to make errors visible on the console
            _show_inventory_results_on_console(inv_result.trees)

            for detail in check_parsing_errors(
                    errors=inv_result.parsing_errors).details:
                console.warning(detail)

        except Exception as e:
            if cmk.utils.debug.enabled():
                raise

            section.section_error("%s" % e)
        finally:
            cmk.utils.cleanup.cleanup_globals()
Exemple #19
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))
Exemple #20
0
def get_check_preview(
    *,
    host_name: HostName,
    max_cachefile_age: cmk.core_helpers.cache.MaxAge,
    use_cached_snmp_data: bool,
    on_error: OnError,
) -> Tuple[CheckPreviewTable, QualifiedDiscovery[HostLabel]]:
    """Get the list of service of a host or cluster and guess the current state of
    all services if possible"""
    config_cache = config.get_config_cache()
    host_config = config_cache.get_host_config(host_name)

    ip_address = None if host_config.is_cluster else config.lookup_ip_address(
        host_config)

    cmk.core_helpers.cache.FileCacheFactory.use_outdated = True
    cmk.core_helpers.cache.FileCacheFactory.maybe = use_cached_snmp_data

    parsed_sections_broker, _source_results = make_broker(
        config_cache=config_cache,
        host_config=host_config,
        ip_address=ip_address,
        mode=Mode.DISCOVERY,
        file_cache_max_age=max_cachefile_age,
        selected_sections=NO_SELECTION,
        fetcher_messages=(),
        force_snmp_cache_refresh=not use_cached_snmp_data,
        on_scan_error=on_error,
    )

    host_labels = analyse_host_labels(
        host_config=host_config,
        ipaddress=ip_address,
        parsed_sections_broker=parsed_sections_broker,
        load_labels=True,
        save_labels=False,
        on_error=on_error,
    )

    for detail in check_parsing_errors(
            parsed_sections_broker.parsing_errors()).details:
        console.warning(detail)

    grouped_services = _get_host_services(
        host_config,
        ip_address,
        parsed_sections_broker,
        on_error,
    )

    with load_host_value_store(host_name,
                               store_changes=False) as value_store_manager:
        table = [
            _check_preview_table_row(
                host_config=host_config,
                ip_address=ip_address,
                service=service,
                check_source=check_source,
                parsed_sections_broker=parsed_sections_broker,
                found_on_nodes=found_on_nodes,
                value_store_manager=value_store_manager,
            )
            for check_source, services_with_nodes in grouped_services.items()
            for service, found_on_nodes in services_with_nodes
        ]

    return table, host_labels
Exemple #21
0
def _do_inv_for_realhost(
    host_config: config.HostConfig,
    *,
    parsed_sections_broker: ParsedSectionsBroker,
    run_plugin_names: Container[InventoryPluginName],
    retentions_tracker: RetentionsTracker,
) -> InventoryTrees:
    tree_aggregator = TreeAggregator()

    _set_cluster_property(tree_aggregator.trees.inventory, host_config)

    section.section_step("Executing inventory plugins")
    for inventory_plugin in agent_based_register.iter_all_inventory_plugins():
        if inventory_plugin.name not in run_plugin_names:
            continue

        for host_key in (host_config.host_key, host_config.host_key_mgmt):
            kwargs = get_section_kwargs(
                parsed_sections_broker,
                host_key,
                inventory_plugin.sections,
            )
            if not kwargs:
                console.vverbose(
                    " %s%s%s%s: skipped (no data)\n",
                    tty.yellow,
                    tty.bold,
                    inventory_plugin.name,
                    tty.normal,
                )
                continue

            # 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 = {
                    **kwargs,
                    "params":
                    host_config.inventory_parameters(
                        inventory_plugin.inventory_ruleset_name),
                }

            exception = tree_aggregator.aggregate_results(
                inventory_generator=inventory_plugin.inventory_function(
                    **kwargs),
                retentions_tracker=retentions_tracker,
                raw_cache_info=parsed_sections_broker.get_cache_info(
                    inventory_plugin.sections),
                is_legacy_plugin=inventory_plugin.module is None,
            )

            if exception:
                console.warning(
                    " %s%s%s%s: failed: %s",
                    tty.red,
                    tty.bold,
                    inventory_plugin.name,
                    tty.normal,
                    exception,
                )
            else:
                console.verbose(" %s%s%s%s", tty.green, tty.bold,
                                inventory_plugin.name, tty.normal)
                console.vverbose(": ok\n")

    console.verbose("\n")
    return tree_aggregator.trees
Exemple #22
0
def warning(text: str) -> None:
    g_configuration_warnings.append(text)
    console.warning("\n%s", text, stream=sys.stdout)
Exemple #23
0
def test_warning(stream):
    console.warning("  hello  ", stream=stream)
    assert read(stream) == console._format_warning("  hello  ")
Exemple #24
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
Exemple #25
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", "")

    # TODO (mo): Assumption here is that inventory plugins are significantly fewer
    #            than check plugins. We should pass an explicit list along, instead
    #            of this flag. That way we would also get rid of the import above.
    if for_inv:
        section_names = [PluginName(n) for n in inventory_plugins.inv_info]
        these_sections = [
            config.registered_snmp_sections[section_name]
            for section_name in section_names
            if section_name in config.registered_snmp_sections
        ]
    else:
        these_sections = list(config.registered_snmp_sections.values())

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

    for section_plugin in these_sections:

        try:

            if _evaluate_snmp_detection(
                    section_plugin.detect_spec,
                    host_config,
                    str(section_plugin.name),
                    do_snmp_scan,
            ):
                found_plugins.add(str(section_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" %
                                section_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