Esempio n. 1
0
        def wrapped_check_func(hostname: HostName, *args: Any,
                               **kwargs: Any) -> int:
            host_config = config.get_config_cache().get_host_config(hostname)
            exit_spec = host_config.exit_code_spec()

            status, infotexts, long_infotexts, perfdata = 0, [], [], []

            try:
                status, infotexts, long_infotexts, perfdata = check_func(
                    hostname, *args, **kwargs)

            except MKTimeout:
                if _in_keepalive_mode():
                    raise
                infotexts.append("Timed out")
                status = max(status, exit_spec.get("timeout", 2))

            except (MKAgentError, MKFetcherError, MKSNMPError,
                    MKIPAddressLookupError) as e:
                infotexts.append("%s" % e)
                status = exit_spec.get("connection", 2)

            except MKGeneralException as e:
                infotexts.append("%s" % e)
                status = max(status, exit_spec.get("exception", 3))

            except Exception:
                if cmk.utils.debug.enabled():
                    raise
                crash_output = cmk.base.crash_reporting.create_check_crash_dump(
                    host_name=hostname,
                    service_name=description,
                    plugin_name=check_plugin_name,
                    plugin_kwargs={},
                    is_manual=False,
                )
                infotexts.append(
                    crash_output.replace("Crash dump:\n", "Crash dump:\\n"))
                status = max(status, exit_spec.get("exception", 3))

            # Produce the service check result output
            output_txt = ", ".join(infotexts)
            if perfdata:
                output_txt += " | %s" % " ".join(perfdata)
            if long_infotexts:
                output_txt = "%s\n%s" % (output_txt, "\n".join(long_infotexts))
            output_txt += "\n"

            if _in_keepalive_mode():
                if not cmk_version.is_raw_edition():
                    import cmk.base.cee.keepalive as keepalive  # pylint: disable=no-name-in-module
                else:
                    keepalive = None  # type: ignore[assignment]

                keepalive.add_active_check_result(hostname, output_txt)
                console.verbose(ensure_str(output_txt))
            else:
                out.output(ensure_str(output_txt))

            return status
Esempio n. 2
0
 def _get_filepaths(self):
     # type: () -> List[Path]
     out.output("Collect diagnostics information:\n")
     filepaths = []
     for element in self.elements:
         filepath = element.add_or_get_file(self.tmp_dump_folder)
         if filepath is None:
             console.verbose("  %s: No informations\n" % element.ident)
             continue
         out.output("  %s\n" % element.description)
         filepaths.append(filepath)
     return filepaths
Esempio n. 3
0
def do_create_config(core, with_agents):
    # type: (MonitoringCore, bool) -> None
    out.output("Generating configuration for core (type %s)..." % config.monitoring_core)
    create_core_config(core)
    out.output(tty.ok + "\n")

    if with_agents:
        try:
            import cmk.base.cee.agent_bakery  # pylint: disable=redefined-outer-name,import-outside-toplevel
            cmk.base.cee.agent_bakery.bake_on_restart()
        except ImportError:
            pass
Esempio n. 4
0
        def wrapped_check_func(hostname, *args, **kwargs):
            # type: (HostName, Any, Any) -> int
            host_config = config.get_config_cache().get_host_config(hostname)
            exit_spec = host_config.exit_code_spec()

            status, infotexts, long_infotexts, perfdata = 0, [], [], []

            try:
                status, infotexts, long_infotexts, perfdata = check_func(
                    hostname, *args, **kwargs)

            except MKTimeout:
                if _in_keepalive_mode():
                    raise
                infotexts.append("Timed out")
                status = max(status, cast(int, exit_spec.get("timeout", 2)))

            except (MKAgentError, MKSNMPError, MKIPAddressLookupError) as e:
                infotexts.append("%s" % e)
                status = cast(int, exit_spec.get("connection", 2))

            except MKGeneralException as e:
                infotexts.append("%s" % e)
                status = max(status, cast(int, exit_spec.get("exception", 3)))

            except Exception:
                if cmk.utils.debug.enabled():
                    raise
                crash_output = cmk.base.crash_reporting.create_check_crash_dump(
                    hostname, check_plugin_name, None, False, None,
                    description, [])
                infotexts.append(
                    crash_output.replace("Crash dump:\n", "Crash dump:\\n"))
                status = max(status, cast(int, exit_spec.get("exception", 3)))

            # Produce the service check result output
            output_txt = "%s - %s" % (defines.short_service_state_name(status),
                                      ", ".join(infotexts))
            if perfdata:
                output_txt += " | %s" % " ".join(perfdata)
            if long_infotexts:
                output_txt = "%s\n%s" % (output_txt, "\n".join(long_infotexts))
            output_txt += "\n"

            if _in_keepalive_mode():
                keepalive.add_keepalive_active_check_result(
                    hostname, output_txt)
                console.verbose(six.ensure_str(output_txt))
            else:
                out.output(six.ensure_str(output_txt))

            return status
Esempio n. 5
0
def do_check_nagiosconfig() -> bool:
    """Execute nagios config verification to ensure the created check_mk_objects.cfg is valid"""
    command = [
        cmk.utils.paths.nagios_binary, "-vp",
        cmk.utils.paths.nagios_config_file
    ]
    console.verbose("Running '%s'\n" % subprocess.list2cmdline(command))
    out.output("Validating Nagios configuration...")

    p = subprocess.Popen(  # pylint:disable=consider-using-with
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        close_fds=True,
        encoding="utf-8",
    )
    stdout = p.communicate()[0]
    exit_status = p.returncode
    if not exit_status:
        out.output(tty.ok + "\n")
        return True

    out.output("ERROR:\n")
    out.output(stdout, stream=sys.stderr)
    return False
Esempio n. 6
0
def do_check_nagiosconfig():
    # type: () -> bool
    command = [
        cmk.utils.paths.nagios_binary, "-vp",
        cmk.utils.paths.nagios_config_file
    ]
    console.verbose("Running '%s'\n" % subprocess.list2cmdline(command))
    out.output("Validating Nagios configuration...")

    p = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        close_fds=True,
        encoding="utf-8",
    )
    stdout, stderr = p.communicate()
    exit_status = p.returncode
    if not exit_status:
        out.output(tty.ok + "\n")
        return True

    out.output("ERROR:\n")
    out.output(stdout, stderr)
    return False
Esempio n. 7
0
def do_create_config(core: MonitoringCore) -> None:
    """Creating the monitoring core configuration and additional files

    Ensures that everything needed by the monitoring core and it's helper processes is up-to-date
    and available for starting the monitoring.
    """
    out.output("Generating configuration for core (type %s)..." % core.name())
    try:
        _create_core_config(core)
        out.output(tty.ok + "\n")
    except Exception as e:
        if cmk.utils.debug.enabled():
            raise
        raise MKGeneralException("Error creating configuration: %s" % e)

    _bake_on_restart()
Esempio n. 8
0
        def wrapped_check_func(hostname: HostName, *args: Any,
                               **kwargs: Any) -> int:
            host_config = config.get_config_cache().get_host_config(hostname)
            exit_spec = host_config.exit_code_spec()
            try:
                status, output_text = _combine_texts(
                    check_func(hostname, *args, **kwargs))

            except MKTimeout:
                if _in_keepalive_mode():
                    raise
                status = exit_spec.get("timeout", 2)
                output_text = "Timed out\n"

            except (MKAgentError, MKFetcherError, MKSNMPError,
                    MKIPAddressLookupError) as e:
                status = exit_spec.get("connection", 2)
                output_text = f"{e}\n"

            except MKGeneralException as e:
                status = exit_spec.get("exception", 3)
                output_text = f"{e}\n"

            except Exception:
                if cmk.utils.debug.enabled():
                    raise
                status = exit_spec.get("exception", 3)
                output_text = cmk.base.crash_reporting.create_check_crash_dump(
                    host_name=hostname,
                    service_name=description,
                    plugin_name=check_plugin_name,
                    plugin_kwargs={},
                    is_manual=False,
                ).replace("Crash dump:\n", "Crash dump:\\n")

            if _in_keepalive_mode():
                import cmk.base.cee.keepalive as keepalive  # pylint: disable=no-name-in-module

                keepalive.add_active_check_result(hostname, output_text)
                console.verbose(output_text)
            else:
                out.output(output_text)

            return status
Esempio n. 9
0
    def execute(self, cmd: str, args: List[str]) -> Any:
        self._handle_generic_arguments(args)

        try:
            try:
                automation = self._automations[cmd]
            except KeyError:
                raise MKAutomationError("Automation command '%s' is not implemented." % cmd)

            if automation.needs_checks:
                with redirect_stdout(open(os.devnull, "w")):
                    log.setup_console_logging()
                    config.load_all_agent_based_plugins(
                        check_api.get_check_api_context,
                        inventory_plugins.load_legacy_inventory_plugins,
                    )

            if automation.needs_config:
                config.load(validate_hosts=False)

            result = automation.execute(args)

        except (MKAutomationError, MKTimeout) as e:
            console.error("%s\n" % e)
            if cmk.utils.debug.enabled():
                raise
            return 1

        except Exception as e:
            if cmk.utils.debug.enabled():
                raise
            console.error("%s\n" % e)
            return 2

        finally:
            profiling.output_profile()

        out.output(result.serialize())
        out.output("\n")

        return 0
Esempio n. 10
0
def do_create_config(core: MonitoringCore, hosts_to_update: HostsToUpdate = None) -> None:
    """Creating the monitoring core configuration and additional files

    Ensures that everything needed by the monitoring core and it's helper processes is up-to-date
    and available for starting the monitoring.
    """
    out.output("Generating configuration for core (type %s)...\n" % core.name())
    if hosts_to_update is not None:
        out.output(
            "Reuse old configuration, create new configuration for %s and dependant hosts\n"
            % ", ".join(hosts_to_update)
        )

    try:
        _create_core_config(core, hosts_to_update=hosts_to_update)
    except Exception as e:
        if cmk.utils.debug.enabled():
            raise
        raise MKGeneralException("Error creating configuration: %s" % e)

    _bake_on_restart()
Esempio n. 11
0
def do_core_action(action: CoreAction, quiet: bool = False) -> None:
    if not quiet:
        out.output("%sing monitoring core..." % action.value.title())

    if config.monitoring_core == "nagios":
        os.putenv("CORE_NOVERIFY", "yes")
        command = ["%s/etc/init.d/core" % cmk.utils.paths.omd_root, action.value]
    else:
        command = ["omd", action.value, "cmc"]

    completed_process = subprocess.run(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        close_fds=True,
        check=False,
    )
    if completed_process.returncode != 0:
        if not quiet:
            out.output("ERROR: %r\n" % completed_process.stdout)
        raise MKGeneralException(
            "Cannot %s the monitoring core: %r" % (action.value, completed_process.stdout)
        )
    if not quiet:
        out.output(tty.ok + "\n")
Esempio n. 12
0
def do_core_action(action: CoreAction, quiet: bool = False) -> None:
    if not quiet:
        out.output("%sing monitoring core..." % action.value.title())

    if config.monitoring_core == "nagios":
        os.putenv("CORE_NOVERIFY", "yes")
        command = [
            "%s/etc/init.d/core" % cmk.utils.paths.omd_root, action.value
        ]
    else:
        command = ["omd", action.value, "cmc"]

    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         close_fds=True)
    result = p.wait()
    if result != 0:
        assert p.stdout is not None
        output = p.stdout.read()
        if not quiet:
            out.output("ERROR: %r\n" % output)
        raise MKGeneralException("Cannot %s the monitoring core: %r" %
                                 (action.value, output))
    if not quiet:
        out.output(tty.ok + "\n")
Esempio n. 13
0
def output_profile() -> None:
    if not _profile:
        return

    _profile.dump_stats(str(_profile_path))
    show_profile = _profile_path.with_name("show_profile.py")

    with show_profile.open("w") as f:
        f.write("""#!/usr/bin/env python3
import sys
import pstats
try:
    profile_file = sys.argv[1]
except IndexError:
    profile_file = "%s"
stats = pstats.Stats(profile_file)
stats.sort_stats('time').print_stats()""" % _profile_path)

    show_profile.chmod(0o755)
    out.output("Profile '%s' written. Please run %s.\n" %
               (_profile_path, show_profile),
               stream=sys.stderr)
Esempio n. 14
0
    def execute(self, cmd: str, args: List[str]) -> Any:
        self._handle_generic_arguments(args)

        try:
            try:
                automation = self._automations[cmd]
            except KeyError:
                raise MKAutomationError(
                    "Automation command '%s' is not implemented." % cmd)

            if automation.needs_checks:
                config.load_all_agent_based_plugins(
                    check_api.get_check_api_context)

            if automation.needs_config:
                config.load(validate_hosts=False)

            result = automation.execute(args)

        except (MKAutomationError, MKTimeout) as e:
            console.error("%s\n" % e)
            if cmk.utils.debug.enabled():
                raise
            return 1

        except Exception as e:
            if cmk.utils.debug.enabled():
                raise
            console.error("%s\n" % e)
            return 2

        finally:
            profiling.output_profile()

        out.output(python_printer.pformat(result))
        out.output('\n')

        return 0
Esempio n. 15
0
def do_create_config(core: MonitoringCore) -> None:
    """Creating the monitoring core configuration and additional files

    Ensures that everything needed by the monitoring core and it's helper processes is up-to-date
    and available for starting the monitoring.
    """
    with _backup_objects_file(core):
        out.output("Generating configuration for core (type %s)..." %
                   config.monitoring_core)
        try:
            _create_core_config(core)
            out.output(tty.ok + "\n")
        except Exception as e:
            if cmk.utils.debug.enabled():
                raise
            raise MKGeneralException("Error creating configuration: %s" % e)

    core.precompile()

    try:
        import cmk.base.cee.bakery.agent_bakery  # pylint: disable=redefined-outer-name,import-outside-toplevel
        cmk.base.cee.bakery.agent_bakery.bake_on_restart()
    except ImportError:
        pass
Esempio n. 16
0
def do_check_nagiosconfig() -> bool:
    """Execute nagios config verification to ensure the created check_mk_objects.cfg is valid"""
    command = [
        cmk.utils.paths.nagios_binary, "-vp",
        cmk.utils.paths.nagios_config_file
    ]
    console.verbose("Running '%s'\n" % subprocess.list2cmdline(command))
    out.output("Validating Nagios configuration...")

    completed_process = subprocess.run(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        close_fds=True,
        encoding="utf-8",
        check=False,
    )
    if not completed_process.returncode:
        out.output(tty.ok + "\n")
        return True

    out.output("ERROR:\n")
    out.output(completed_process.stdout, stream=sys.stderr)
    return False
Esempio n. 17
0
def test_output_with_args(stream):
    out.output("hello %s %i", "bob", 42, stream=stream)
    assert read(stream) == "hello bob 42"
Esempio n. 18
0
def test_output_without_args(stream):
    out.output("hello", stream=stream)
    assert read(stream) == "hello"
Esempio n. 19
0
 def dot(color, dot='o'):
     # type: (str, str) -> None
     if not silent:
         out.output(tty.bold + color + dot + tty.normal)
Esempio n. 20
0
def dump_host(hostname: HostName) -> None:
    config_cache = config.get_config_cache()
    host_config = config_cache.get_host_config(hostname)

    out.output("\n")
    if host_config.is_cluster:
        nodes = host_config.nodes
        if nodes is None:
            raise RuntimeError()
        color = tty.bgmagenta
        add_txt = " (cluster of " + (", ".join(nodes)) + ")"
    else:
        color = tty.bgblue
        add_txt = ""
    out.output("%s%s%s%-78s %s\n" %
               (color, tty.bold, tty.white, hostname + add_txt, tty.normal))

    ipaddress = _ip_address_for_dump_host(
        host_config, family=host_config.default_address_family)

    addresses: Optional[str] = ""
    if not host_config.is_ipv4v6_host:
        addresses = ipaddress
    else:
        try:
            secondary = _ip_address_for_dump_host(
                host_config,
                family=socket.AF_INET
                if host_config.is_ipv6_primary else socket.AF_INET6,
            )
        except Exception:
            secondary = "X.X.X.X"

        addresses = "%s, %s" % (ipaddress, secondary)
        if host_config.is_ipv6_primary:
            addresses += " (Primary: IPv6)"
        else:
            addresses += " (Primary: IPv4)"

    out.output(tty.yellow + "Addresses:              " + tty.normal +
               (addresses if addresses is not None else "No IP") + "\n")

    tag_template = tty.bold + "[" + tty.normal + "%s" + tty.bold + "]" + tty.normal
    tags = [(tag_template % ":".join(t))
            for t in sorted(host_config.tag_groups.items())]
    out.output(tty.yellow + "Tags:                   " + tty.normal +
               ", ".join(tags) + "\n")

    labels = [
        tag_template % ":".join(l) for l in sorted(host_config.labels.items())
    ]
    out.output(tty.yellow + "Labels:                 " + tty.normal +
               ", ".join(labels) + "\n")

    # TODO: Clean this up once cluster parent handling has been moved to HostConfig
    if host_config.is_cluster:
        parents_list = host_config.nodes
        if parents_list is None:
            raise RuntimeError()
    else:
        parents_list = host_config.parents
    if len(parents_list) > 0:
        out.output(tty.yellow + "Parents:                " + tty.normal +
                   ", ".join(parents_list) + "\n")
    out.output(tty.yellow + "Host groups:            " + tty.normal +
               ", ".join(host_config.hostgroups) + "\n")
    out.output(tty.yellow + "Contact groups:         " + tty.normal +
               ", ".join(host_config.contactgroups) + "\n")

    agenttypes = [
        source.description
        for source in sources.make_sources(host_config, ipaddress)
    ]

    if host_config.is_ping_host:
        agenttypes.append("PING only")

    out.output(tty.yellow + "Agent mode:             " + tty.normal)
    out.output(host_config.agent_description + "\n")

    out.output(tty.yellow + "Type of agent:          " + tty.normal)
    if len(agenttypes) == 1:
        out.output(agenttypes[0] + "\n")
    else:
        out.output("\n  ")
        out.output("\n  ".join(agenttypes) + "\n")

    out.output(tty.yellow + "Services:" + tty.normal + "\n")

    headers = ["checktype", "item", "params", "description", "groups"]
    colors = [tty.normal, tty.blue, tty.normal, tty.green, tty.normal]

    table_data = []
    for service in sorted(check_table.get_check_table(hostname).values(),
                          key=lambda s: s.description):
        table_data.append([
            str(service.check_plugin_name),
            str(service.item),
            _evaluate_params(service.parameters),
            service.description,
            ",".join(
                config_cache.servicegroups_of_service(hostname,
                                                      service.description)),
        ])

    tty.print_table(headers, colors, table_data, "  ")
Esempio n. 21
0
 def dot(color: str, dot: str = 'o') -> None:
     if not silent:
         out.output(tty.bold + color + dot + tty.normal)
Esempio n. 22
0
def do_scan_parents(hosts: List[HostName]) -> None:
    config_cache = config.get_config_cache()

    if not hosts:
        hosts = list(sorted(config_cache.all_active_realhosts()))

    parent_hosts = []
    parent_ips: Dict[HostName, HostAddress] = {}
    parent_rules = []
    gateway_hosts: Set[HostName] = set()

    if config.max_num_processes < 1:
        config.max_num_processes = 1

    outfilename = cmk.utils.paths.check_mk_config_dir + "/parents.mk"

    if not traceroute_available():
        raise MKGeneralException('The program "traceroute" was not found.\n'
                                 'The parent scan needs this program.\n'
                                 'Please install it and try again.')

    if os.path.exists(outfilename):
        first_line = open(outfilename, "r").readline()
        if not first_line.startswith(
                '# Automatically created by --scan-parents at'):
            raise MKGeneralException(
                "conf.d/parents.mk seems to be created manually.\n\n"
                "The --scan-parents function would overwrite this file.\n"
                "Please rename it to keep the configuration or delete "
                "the file and try again.")

    out.output("Scanning for parents (%d processes)..." %
               config.max_num_processes)
    while hosts:
        chunk: List[HostName] = []
        while len(chunk) < config.max_num_processes and len(hosts) > 0:
            host = hosts.pop()

            host_config = config_cache.get_host_config(host)

            # skip hosts that already have a parent
            if host_config.parents:
                console.verbose("(manual parent) ")
                continue
            chunk.append(host)

        gws = scan_parents_of(config_cache, chunk)

        for host, (gw, _unused_state, _unused_ping_fails,
                   _unused_message) in zip(chunk, gws):
            if gw:
                gateway, gateway_ip, dns_name = gw
                if not gateway:  # create artificial host
                    if dns_name:
                        gateway = dns_name
                    else:
                        gateway = "gw-%s" % (gateway_ip.replace(".", "-"))
                    if gateway not in gateway_hosts:
                        gateway_hosts.add(gateway)
                        parent_hosts.append("%s|parent|ping" % gateway)
                        parent_ips[gateway] = gateway_ip
                        if config.monitoring_host:
                            parent_rules.append(
                                (config.monitoring_host,
                                 [gateway]))  # make Nagios a parent of gw
                parent_rules.append((gateway, [host]))
            elif host != config.monitoring_host and config.monitoring_host:
                # make monitoring host the parent of all hosts without real parent
                parent_rules.append((config.monitoring_host, [host]))

    with open(outfilename, "w") as file:
        file.write("# Automatically created by --scan-parents at %s\n\n" %
                   time.asctime())
        file.write("# Do not edit this file. If you want to convert an\n")
        file.write("# artificial gateway host into a permanent one, then\n")
        file.write("# move its definition into another *.mk file\n")

        file.write("# Parents which are not listed in your all_hosts:\n")
        file.write("all_hosts += %s\n\n" % pprint.pformat(parent_hosts))

        file.write("# IP addresses of parents not listed in all_hosts:\n")
        file.write("ipaddresses.update(%s)\n\n" % pprint.pformat(parent_ips))

        file.write("# Parent definitions\n")
        file.write("parents += %s\n\n" % pprint.pformat(parent_rules))
    out.output("\nWrote %s\n" % outfilename)
Esempio n. 23
0
def test_output_with_wrong_args(stream):
    with pytest.raises(TypeError):
        out.output("hello %s %i", "wrong", "args", stream=stream)
Esempio n. 24
0
def test_output_ignores_stream_errors(stream, mocker, monkeypatch):
    mock = mocker.Mock(side_effect=IOError("bad luck"))
    monkeypatch.setattr(stream, "flush", mock)

    out.output("hello", stream=stream)
    assert read(stream) == "hello"
Esempio n. 25
0
def create_diagnostics_dump():
    # type: () -> None
    dump = DiagnosticsDump()
    dump.create()
    out.output("Created diagnostics dump:\n")
    out.output("  '%s'\n" % _get_short_filepath(dump.tarfile_path))