#!/usr/bin/env python3 # pylint: disable=missing-module-docstring, unused-argument, consider-using-f-string # pylint: disable=missing-function-docstring, line-too-long from pprint import pprint from cmk.utils import debug # import necessary elements from API version 2 from cmk.agent_based.v2 import ( AgentSection, CheckPlugin, Service, State, Metric, Result, DiscoveryResult, CheckResult, check_levels, ) def get_state_upper( levels: tuple[int | float, int | float], value: int | float ) -> State: """returns OK/WARN/CRIT depending on the given parameters""" warn, crit = levels if value >= crit: return State.CRIT if value >= warn: return State.WARN return State.OK def parse_traefik_udp_components(string_table): """the parse function""" parsed_data = {} for line in string_table: if line[0] == "routers": parsed_data["num_routers"] = int(line[1]) parsed_data["num_routers_warn"] = int(line[2]) parsed_data["num_routers_crit"] = int(line[3]) elif line[0] == "services": parsed_data["num_services"] = int(line[1]) parsed_data["num_services_warn"] = int(line[2]) parsed_data["num_services_crit"] = int(line[3]) return parsed_data def discover_traefik_udp_components(section) -> DiscoveryResult: """the discover function""" yield Service() def check_traefik_udp_components(params, section) -> CheckResult: """the check function""" if debug.enabled(): pprint(section) _level_type, levels_percent_not_ok = params["levels_traefik_udp_components_not_ok"] levels_min_routers = params["levels_traefik_min_udp_routers"] levels_max_routers = params["levels_traefik_max_udp_routers"] levels_min_services = params["levels_traefik_min_udp_services"] levels_max_services = params["levels_traefik_max_udp_services"] num_routers: int = section["num_routers"] num_routers_warn: int = section["num_routers_warn"] num_routers_crit: int = section["num_routers_crit"] num_services: int = section["num_services"] num_services_warn: int = section["num_services_warn"] num_services_crit: int = section["num_services_crit"] num_components: int = num_routers + num_services components_warn: int = num_routers_warn + num_services_warn components_crit: int = num_routers_crit + num_services_crit components_percent_not_ok: float = 0.0 if num_components > 0: components_percent_not_ok = ( (components_warn + components_crit) * 100 / num_components ) yield Metric( name="traefik_percent_udp_components_not_ok", value=components_percent_not_ok, levels=levels_percent_not_ok, ) summary: str = f"Number of UDP routers/services: {num_routers}/{num_services}" details_routers: str = ( f"Routers WARN: {num_routers_warn}\nRouters CRIT: {num_routers_crit}" ) details_services: str = ( f"Services WARN: {num_services_warn}\nServices CRIT: {num_services_crit}" ) details = f"{details_routers}\n\n{details_services}" state: State = State.OK if components_warn > 0: state = State.WARN if components_crit > 0: state = State.CRIT yield Result( state=state, summary=summary, details=details, ) yield from check_levels( metric_name="traefik_num_udp_routers", value=num_routers, levels_lower=levels_min_routers, levels_upper=levels_max_routers, label="Number of UDP routers", notice_only=True, render_func=lambda v: "%.0f" % v, ) yield from check_levels( metric_name="traefik_num_udp_services", value=num_services, levels_lower=levels_min_services, levels_upper=levels_max_services, label="Number of UDP services", notice_only=True, render_func=lambda v: "%.0f" % v, ) # create the new agent section, must begin with "agent_section_" # and must be an instance of "AgentSection" agent_section_traefik_udp_components = AgentSection( # "name" must exactly match the section name within the agent output name="traefik_udp_components", # define the parse function, name is arbitrary, a good choice is to choose # "parse_" as prefix and append the section name parse_function=parse_traefik_udp_components, ) # create the new check plugin, must begin with "check_plugin_" # and must be an instance of "CheckPlugin" check_plugin_traefik_udp_components = CheckPlugin( # "name" should be the same as the corresponding section within the agent output name="traefik_udp_components", service_name="Traefik UDP components", # define the discovery function, name is arbitrary, a good choice is to choose # "discover_" as prefix and append the section name discovery_function=discover_traefik_udp_components, # define the check function, name is arbitrary, a good choice is to choose # "check_" as prefix and append the section name check_function=check_traefik_udp_components, # define the default parameters check_default_parameters={ "levels_traefik_min_udp_routers": ("fixed", (0, 0)), "levels_traefik_max_udp_routers": ("fixed", (25, 50)), "levels_traefik_min_udp_services": ("fixed", (0, 0)), "levels_traefik_max_udp_services": ("fixed", (25, 50)), "levels_traefik_udp_components_not_ok": ("fixed", (0.5, 1.0)), }, # connect to the ruleset where parameters can be defined # must match the name of the ruleset exactly check_ruleset_name="traefik_udp_components", )