def iter_active_check_services( check_name: str, active_info: Mapping[str, Any], hostname: str, host_attrs: config.ObjectAttributes, params: Dict[Any, Any], ) -> Iterator[Tuple[str, str]]: """Iterate active service descriptions and arguments This function is used to allow multiple active services per one WATO rule. This functionality is now used only in ICMP active check and it's NOT part of an official API. This function can be changed at any time. """ host_config = _get_host_address_config(hostname, host_attrs) if "service_generator" in active_info: for desc, args in active_info["service_generator"](host_config, params): yield str(desc), str(args) return description = config.active_check_service_description( host_config.hostname, host_config.alias, check_name, params ) arguments = active_check_arguments( host_config.hostname, description, active_info["argument_function"](params) ) yield description, arguments
def _merge_manual_services( host_config: config.HostConfig, services: ServicesTable, discovery_parameters: DiscoveryParameters, ) -> ServicesByTransition: """Add/replace manual and active checks and handle ignoration""" host_name = host_config.hostname # Find manual checks. These can override discovered checks -> "manual" manual_items = check_table.get_check_table(host_name, skip_autochecks=True) for service in manual_items.values(): services[service.id()] = ('manual', service, [host_name]) # Add custom checks -> "custom" for entry in host_config.custom_checks: services[(CheckPluginName('custom'), entry['service_description'])] = ( 'custom', Service( check_plugin_name=CheckPluginName('custom'), item=entry['service_description'], description=entry['service_description'], parameters=None, ), [host_name], ) # Similar for 'active_checks', but here we have parameters for plugin_name, entries in host_config.active_checks: for params in entries: descr = config.active_check_service_description( host_name, plugin_name, params) services[(CheckPluginName(plugin_name), descr)] = ( 'active', Service( check_plugin_name=CheckPluginName(plugin_name), item=descr, description=descr, parameters=params, ), [host_name], ) # Handle disabled services -> "ignored" for check_source, discovered_service, _found_on_nodes in services.values(): if check_source in ["legacy", "active", "custom"]: # These are ignored later in get_check_preview # TODO: This needs to be cleaned up. The problem here is that service_description() can not # calculate the description of active checks and the active checks need to be put into # "[source]_ignored" instead of ignored. continue if config.service_ignored(host_name, discovered_service.check_plugin_name, discovered_service.description): services[discovered_service.id()] = ("ignored", discovered_service, [host_name]) return _group_by_transition(services.values())
def _active_items(host_config: config.HostConfig) -> Iterable[Tuple[ServiceID, ServicesTableEntry]]: # Similar for 'active_checks', but here we have parameters host_name = host_config.hostname for plugin_name, entries in host_config.active_checks: for params in entries: descr = config.active_check_service_description(host_name, plugin_name, params) yield (CheckPluginName(plugin_name), descr), ( 'active', Service( check_plugin_name=CheckPluginName(plugin_name), item=descr, description=descr, parameters=params, ), [host_name], )
def get_active_check_descriptions( hostname: HostName, hostalias: str, host_attrs: ObjectAttributes, check_name: str, params: Dict, ) -> Iterator[str]: host_config = _get_host_address_config(hostname, host_attrs) active_check_info = config.active_check_info[check_name] if "service_generator" in active_check_info: for description, _ in active_check_info["service_generator"](host_config, params): yield str(description) return yield config.active_check_service_description(hostname, hostalias, check_name, params)
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"))