#!/usr/bin/env python3 # pylint: disable=missing-module-docstring, unused-argument, consider-using-f-string # pylint: disable=missing-function-docstring, line-too-long # import necessary elements from API version 2 from cmk.agent_based.v2 import ( AgentSection, CheckPlugin, Service, State, Metric, Result, DiscoveryResult, CheckResult, check_levels, ) def parse_traefik_tcp_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]) elif line[0] == "middlewares": parsed_data["num_middlewares"] = int(line[1]) parsed_data["num_middlewares_warn"] = int(line[2]) parsed_data["num_middlewares_crit"] = int(line[3]) return parsed_data def discover_traefik_tcp_components(section) -> DiscoveryResult: """the discover function""" yield Service() def check_traefik_tcp_components(params, section) -> CheckResult: """the check function""" _level_type, levels_percent_not_ok = params["levels_traefik_tcp_components_not_ok"] levels_min_routers = params["levels_traefik_min_tcp_routers"] levels_max_routers = params["levels_traefik_max_tcp_routers"] levels_min_services = params["levels_traefik_min_tcp_services"] levels_max_services = params["levels_traefik_max_tcp_services"] levels_min_middlewares = params["levels_traefik_min_tcp_middlewares"] levels_max_middlewares = params["levels_traefik_max_tcp_middlewares"] 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_middlewares: int = section["num_middlewares"] num_middlewares_warn: int = section["num_middlewares_warn"] num_middlewares_crit: int = section["num_middlewares_crit"] num_components: int = num_routers + num_services + num_middlewares components_warn: int = num_routers_warn + num_services_warn + num_middlewares_warn components_crit: int = num_routers_crit + num_services_crit + num_middlewares_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_tcp_components_not_ok", value=components_percent_not_ok, levels=levels_percent_not_ok, ) summary: str = f"Number of TCP routers/services/middlewares: {num_routers}/{num_services}/{num_middlewares}" 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_middlewares: str = f"Middlewares WARN: {num_middlewares_warn}\nMiddlewares CRIT: {num_middlewares_crit}\n\n" details = f"{details_routers}\n\n{details_services}\n\n{details_middlewares}" 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_tcp_routers", value=num_routers, levels_lower=levels_min_routers, levels_upper=levels_max_routers, label="Number of TCP routers", notice_only=True, render_func=lambda v: "%.0f" % v, ) yield from check_levels( metric_name="traefik_num_tcp_services", value=num_services, levels_lower=levels_min_services, levels_upper=levels_max_services, label="Number of TCP services", notice_only=True, render_func=lambda v: "%.0f" % v, ) yield from check_levels( metric_name="traefik_num_tcp_middlewares", value=num_middlewares, levels_lower=levels_min_middlewares, levels_upper=levels_max_middlewares, label="Number of TCP middlewares", 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_tcp_components = AgentSection( # "name" must exactly match the section name within the agent output name="traefik_tcp_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_tcp_components, ) # create the new check plugin, must begin with "check_plugin_" # and must be an instance of "CheckPlugin" check_plugin_traefik_tcp_components = CheckPlugin( # "name" should be the same as the corresponding section within the agent output name="traefik_tcp_components", service_name="Traefik TCP 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_tcp_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_tcp_components, # define the default parameters check_default_parameters={ "levels_traefik_min_tcp_routers": ("fixed", (0, 0)), "levels_traefik_max_tcp_routers": ("fixed", (25, 50)), "levels_traefik_min_tcp_services": ("fixed", (0, 0)), "levels_traefik_max_tcp_services": ("fixed", (25, 50)), "levels_traefik_min_tcp_middlewares": ("fixed", (0, 0)), "levels_traefik_max_tcp_middlewares": ("fixed", (25, 50)), "levels_traefik_tcp_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_tcp_components", )