def test_active_check_arguments_list_with_invalid_type(): with pytest.raises(MKGeneralException): core_config.active_check_arguments( HostName("bla"), "blub", [None] # type: ignore[list-item] )
def test_active_check_arguments_wrong_types(): with pytest.raises(MKGeneralException): core_config.active_check_arguments("bla", "blub", 1) # type: ignore[arg-type] with pytest.raises(MKGeneralException): core_config.active_check_arguments("bla", "blub", (1, 2)) # type: ignore[arg-type]
def test_active_check_arguments_basics(): assert core_config.active_check_arguments("bla", "blub", u"args 123 -x 1 -y 2") \ == u"args 123 -x 1 -y 2" assert core_config.active_check_arguments("bla", "blub", ["args", "123", "-x", "1", "-y", "2"]) \ == "'args' '123' '-x' '1' '-y' '2'" assert core_config.active_check_arguments("bla", "blub", ["args", "1 2 3", "-d=2", "--hallo=eins", 9]) \ == "'args' '1 2 3' '-d=2' '--hallo=eins' 9" with pytest.raises(MKGeneralException): core_config.active_check_arguments("bla", "blub", (1, 2)) # type: ignore[arg-type]
def test_active_check_arguments_password_store(monkeypatch, pw): monkeypatch.setattr(config, "stored_passwords", {"pw-id": { "password": pw, }}) assert core_config.active_check_arguments("bla", "blub", ["arg1", ("store", "pw-id", "--password=%s"), "arg3"]) \ == "--pwstore=2@11@pw-id 'arg1' '--password=%s' 'arg3'" % ("*" * len(pw))
def test_active_check_arguments_not_existing_password(capsys): assert (core_config.active_check_arguments( HostName("bla"), "blub", ["arg1", ("store", "pw-id", "--password=%s"), "arg3" ]) == "--pwstore=2@11@pw-id 'arg1' '--password=***' 'arg3'") stderr = capsys.readouterr().err assert 'The stored password "pw-id" used by service "blub" on host "bla"' in stderr
def test_active_check_arguments_list_with_pwstore_reference(): assert ( core_config.active_check_arguments( HostName("bla"), "blub", ["a", ("store", "pw1", "--password=%s")] ) == "--pwstore=2@11@pw1 'a' '--password=***'" )
def test_active_check_arguments_password_store(pw): password_store.save({"pw-id": pw}) assert core_config.active_check_arguments( HostName("bla"), "blub", ["arg1", ("store", "pw-id", "--password=%s"), "arg3" ]) == "--pwstore=2@11@pw-id 'arg1' '--password=%s' 'arg3'" % ("*" * len(pw))
def _source_args(self): # type: () -> str info_func = config.special_agent_info[self._special_agent_id] agent_configuration = info_func(self._params, self._hostname, self._ipaddress) return core_config.active_check_arguments(self._hostname, None, agent_configuration)
def _make_source_args( hostname: HostName, ipaddress: Optional[HostAddress], special_agent_id: str, params: Dict, ) -> str: info_func = config.special_agent_info[special_agent_id] agent_configuration = info_func(params, hostname, ipaddress) return core_config.active_check_arguments(hostname, None, agent_configuration)
def test_active_check_arguments(mocker): with pytest.raises(MKGeneralException): core_config.active_check_arguments("bla", "blub", 1) # type: ignore[arg-type] with pytest.raises(MKGeneralException): core_config.active_check_arguments("bla", "blub", (1, 2)) # type: ignore[arg-type] prepare_check_command = mocker.patch.object(config, "prepare_check_command") core_config.active_check_arguments("bla", "blub", u"args 123 -x 1 -y 2") assert prepare_check_command.called_once()
def test_active_check_arguments_list_with_numbers(): assert core_config.active_check_arguments("bla", "blub", [1, 1.2]) == "1 1.2"
def test_active_check_arguments_list(): assert core_config.active_check_arguments("bla", "blub", ["a", "123"]) == "'a' '123'"
def test_active_check_arguments_str(): assert core_config.active_check_arguments( "bla", "blub", u"args 123 -x 1 -y 2") == 'args 123 -x 1 -y 2'
def test_active_check_arguments_not_existing_password(capsys): assert core_config.active_check_arguments("bla", "blub", ["arg1", ("store", "pw-id", "--password=%s"), "arg3"]) \ == "--pwstore=2@11@pw-id 'arg1' '--password=***' 'arg3'" stderr = capsys.readouterr().err assert "The stored password \"pw-id\" used by service \"blub\" on host \"bla\"" in stderr
def test_active_check_arguments_str(): assert (core_config.active_check_arguments( HostName("bla"), "blub", "args 123 -x 1 -y 2") == "args 123 -x 1 -y 2")
def _create_nagios_servicedefs(cfg, config_cache, hostname, host_attrs): # type: (NagiosConfig, ConfigCache, HostName, ObjectAttributes) -> None import cmk.base.check_table as check_table # pylint: disable=import-outside-toplevel host_config = config_cache.get_host_config(hostname) check_mk_attrs = core_config.get_service_attributes( hostname, "Check_MK", config_cache) # _____ # |___ / # |_ \ # ___) | # |____/ 3. Services def do_omit_service(hostname, description): # type: (HostName, ServiceName) -> bool if config.service_ignored(hostname, None, description): return True if hostname != config_cache.host_of_clustered_service( hostname, description): return True return False def get_dependencies(hostname, servicedesc): # type: (HostName, ServiceName) -> str result = "" for dep in config.service_depends_on(hostname, servicedesc): result += _format_nagios_object( "servicedependency", { "use": config.service_dependency_template, "host_name": hostname, "service_description": dep, "dependent_host_name": hostname, "dependent_service_description": servicedesc, }) return result services = check_table.get_check_table(hostname, remove_duplicates=True).values() have_at_least_one_service = False used_descriptions = { } # type: Dict[ServiceName, Tuple[CheckPluginName, Item]] for service in sorted(services, key=lambda s: (s.check_plugin_name, s.item)): if service.check_plugin_name not in config.check_info: continue # simply ignore missing checks # Make sure, the service description is unique on this host if service.description in used_descriptions: cn, it = used_descriptions[service.description] # TODO: Remove "type: ignore" once we are on python3 core_config.warning( "ERROR: Duplicate service description '%s' for host '%s'!\n" # type: ignore[arg-type] " - 1st occurrance: checktype = %s, item = %r\n" " - 2nd occurrance: checktype = %s, item = %r\n" % (service.description, hostname, cn, it, service.check_plugin_name, service.item)) continue used_descriptions[service.description] = (service.check_plugin_name, service.item) if config.check_info[service.check_plugin_name].get( "has_perfdata", False): template = config.passive_service_template_perf else: template = config.passive_service_template # Services Dependencies for autochecks cfg.write(get_dependencies(hostname, service.description)) service_spec = { "use": template, "host_name": hostname, "service_description": service.description, "check_command": "check_mk-%s" % service.check_plugin_name, } service_spec.update( core_config.get_cmk_passive_service_attributes( config_cache, host_config, service, check_mk_attrs)) service_spec.update( _extra_service_conf_of(cfg, config_cache, hostname, service.description)) cfg.write(_format_nagios_object("service", service_spec)) cfg.checknames_to_define.add(service.check_plugin_name) have_at_least_one_service = True # Active check for check_mk if have_at_least_one_service: service_spec = { "use": config.active_service_template, "host_name": hostname, "service_description": "Check_MK", } service_spec.update(check_mk_attrs) service_spec.update( _extra_service_conf_of(cfg, config_cache, hostname, "Check_MK")) cfg.write(_format_nagios_object("service", service_spec)) # legacy checks via active_checks actchecks = [] for plugin_name, entries in host_config.active_checks: cfg.active_checks_to_define.add(plugin_name) act_info = config.active_check_info[plugin_name] for params in entries: actchecks.append((plugin_name, act_info, params)) if actchecks: cfg.write("\n\n# Active checks\n") for acttype, act_info, params in actchecks: # Make hostname available as global variable in argument functions check_api_utils.set_hostname(hostname) has_perfdata = act_info.get('has_perfdata', False) description = config.active_check_service_description( hostname, acttype, params) if do_omit_service(hostname, description): continue # compute argument, and quote ! and \ for Nagios args = core_config.active_check_arguments( hostname, description, act_info["argument_function"](params)).replace( "\\", "\\\\").replace("!", "\\!") if description in used_descriptions: cn, it = used_descriptions[description] # If we have the same active check again with the same description, # then we do not regard this as an error, but simply ignore the # second one. That way one can override a check with other settings. if cn == "active(%s)" % acttype: continue # TODO: Remove "type: ignore" once we are on python3 core_config.warning( "ERROR: Duplicate service description (active check) '%s' for host '%s'!\n" # type: ignore[arg-type] " - 1st occurrance: checktype = %s, item = %r\n" " - 2nd occurrance: checktype = active(%s), item = None\n" % (description, hostname, cn, it, acttype)) continue used_descriptions[description] = ("active(" + acttype + ")", description) template = "check_mk_perf," if has_perfdata else "" if host_attrs["address"] in ["0.0.0.0", "::"]: command_name = "check-mk-custom" command = command_name + "!echo \"CRIT - Failed to lookup IP address and no explicit IP address configured\" && exit 2" cfg.custom_commands_to_define.add(command_name) else: command = "check_mk_active-%s!%s" % (acttype, args) service_spec = { "use": "%scheck_mk_default" % template, "host_name": hostname, "service_description": description, "check_command": _simulate_command(cfg, command), "active_checks_enabled": str(1), } service_spec.update( core_config.get_service_attributes(hostname, description, config_cache)) service_spec.update( _extra_service_conf_of(cfg, config_cache, hostname, description)) cfg.write(_format_nagios_object("service", service_spec)) # write service dependencies for active checks cfg.write(get_dependencies(hostname, description)) # Legacy checks via custom_checks custchecks = host_config.custom_checks if custchecks: cfg.write("\n\n# Custom checks\n") for entry in custchecks: # entries are dicts with the following keys: # "service_description" Service description to use # "command_line" (optional) Unix command line for executing the check # If this is missing, we create a passive check # "command_name" (optional) Name of Monitoring command to define. If missing, # we use "check-mk-custom" # "has_perfdata" (optional) If present and True, we activate perf_data description = config.get_final_service_description( hostname, entry["service_description"]) has_perfdata = entry.get("has_perfdata", False) command_name = entry.get("command_name", "check-mk-custom") command_line = entry.get("command_line", "") if do_omit_service(hostname, description): continue if command_line: command_line = core_config.autodetect_plugin( command_line).replace("\\", "\\\\").replace("!", "\\!") if "freshness" in entry: freshness = { "check_freshness": 1, "freshness_threshold": 60 * entry["freshness"]["interval"], } command_line = "echo %s && exit %d" % (_quote_nagios_string( entry["freshness"]["output"]), entry["freshness"]["state"]) else: freshness = {} cfg.custom_commands_to_define.add(command_name) if description in used_descriptions: cn, it = used_descriptions[description] # If we have the same active check again with the same description, # then we do not regard this as an error, but simply ignore the # second one. if cn == "custom(%s)" % command_name: continue # TODO: Remove "type: ignore" once we are on python3 core_config.warning( "ERROR: Duplicate service description (custom check) '%s' for host '%s'!\n" # type: ignore[arg-type] " - 1st occurrance: checktype = %s, item = %r\n" " - 2nd occurrance: checktype = custom(%s), item = %r\n" % (description, hostname, cn, it, command_name, description)) continue used_descriptions[description] = ("custom(%s)" % command_name, description) template = "check_mk_perf," if has_perfdata else "" command = "%s!%s" % (command_name, command_line) service_spec = { "use": "%scheck_mk_default" % template, "host_name": hostname, "service_description": description, "check_command": _simulate_command(cfg, command), "active_checks_enabled": str(1 if (command_line and not freshness) else 0), } service_spec.update(freshness) service_spec.update( core_config.get_service_attributes(hostname, description, config_cache)) service_spec.update( _extra_service_conf_of(cfg, config_cache, hostname, description)) cfg.write(_format_nagios_object("service", service_spec)) # write service dependencies for custom checks cfg.write(get_dependencies(hostname, description)) service_discovery_name = config_cache.service_discovery_name() # Inventory checks - if user has configured them. params = host_config.discovery_check_parameters if host_config.add_service_discovery_check(params, service_discovery_name): service_spec = { "use": config.inventory_check_template, "host_name": hostname, "service_description": service_discovery_name, } service_spec.update( core_config.get_service_attributes(hostname, service_discovery_name, config_cache)) service_spec.update( _extra_service_conf_of(cfg, config_cache, hostname, service_discovery_name)) service_spec.update({ "check_interval": params["check_interval"], "retry_interval": params["check_interval"], }) cfg.write(_format_nagios_object("service", service_spec)) if have_at_least_one_service: cfg.write( _format_nagios_object( "servicedependency", { "use": config.service_dependency_template, "host_name": hostname, "service_description": "Check_MK", "dependent_host_name": hostname, "dependent_service_description": service_discovery_name, })) # No check_mk service, no legacy service -> create PING service if not have_at_least_one_service and not actchecks and not custchecks: _add_ping_service(cfg, config_cache, host_config, host_attrs["address"], host_config.is_ipv6_primary and 6 or 4, "PING", host_attrs.get("_NODEIPS")) if host_config.is_ipv4v6_host: if host_config.is_ipv6_primary: _add_ping_service(cfg, config_cache, host_config, host_attrs["_ADDRESS_4"], 4, "PING IPv4", host_attrs.get("_NODEIPS_4")) else: _add_ping_service(cfg, config_cache, host_config, host_attrs["_ADDRESS_6"], 6, "PING IPv6", host_attrs.get("_NODEIPS_6"))