init first version of pbs_special_agent
build / Build Checkmk package (push) Failing after 36s
build-release / Build Release Package (push) Failing after 35s
Lint / flake8_py3 (push) Failing after 18s
pytest / pytest (push) Failing after 32s

This commit is contained in:
Simon Zeyer
2026-03-10 19:28:57 +00:00
commit 19cf015e95
29 changed files with 1229 additions and 0 deletions
@@ -0,0 +1,243 @@
#!/usr/bin/env python3
import itertools
import json
from datetime import datetime
from cmk.agent_based.v2 import (
AgentSection,
CheckPlugin,
Service,
Result,
State,
Metric,
get_value_store,
)
from cmk.plugins.lib.df import (
df_check_filesystem_single,
FILESYSTEM_DEFAULT_LEVELS,
)
ITEM_STATUS = "API Status"
ITEM_DS_USAGE = "Datastore Usage "
ITEM_SYNC_JOBS = "Sync Job "
ITEM_GC = "Garbage Collection "
ITEM_PRUNE = "Prune Job "
ITEM_VERIFY = "Verify Job "
ITEM_FS_ROOT = "HD Space (root)"
ITEM_FS_SWAP = "Swap Usage"
ITEM_CPU = "CPU Usage"
ITEM_MEM = "Memory Usage"
ITEM_LOAD = "Load Average"
def parse_jobs(item: str, item_key: str, section: dict, section_key: str, section_item_key: str):
if item.startswith(item_key):
for s in section[section_key]:
if item.replace(item_key, '') == s[section_item_key]:
next_run = ""
if "last-run-state" in s:
if 'next-run' in s:
next_run = (
f", next run: "
f"{datetime.fromtimestamp(s['next-run'])}"
)
if s["last-run-state"] == "OK":
yield Result(
state=State.OK,
summary=(
f"last run state: OK"
f"{next_run}"
),
)
else:
yield Result(
state=State.CRIT,
summary=(
f"last run state: {s["last-run-state"]}"
f"{next_run}"
),
)
else:
yield Result(
state=State.OK,
summary=(
"Job running"
),
)
def parse_pbs_special_agent(string_table):
flatlist = list(itertools.chain.from_iterable(string_table))
# parsed = json.loads(" ".join(flatlist).replace("'", "\""))
parsed = json.loads(" ".join(flatlist))
return parsed
def discover_pbs_special_agent(section):
yield Service(item=ITEM_STATUS)
if "status" in section:
yield Service(item=ITEM_CPU)
yield Service(item=ITEM_MEM)
yield Service(item=ITEM_LOAD)
if "sync" in section:
for s in section["sync"]:
yield Service(item=ITEM_SYNC_JOBS + s["id"])
if "gc" in section:
for gc in section["gc"]:
yield Service(item=ITEM_GC + gc["store"])
if "prune" in section:
for prune in section["prune"]:
yield Service(item=ITEM_PRUNE + prune["id"])
if "verify" in section:
for verify in section["verify"]:
yield Service(item=ITEM_VERIFY + verify["id"])
def discover_pbs_special_agent_storage(section):
if "ds_usage" in section:
for ds in section["ds_usage"]:
yield Service(item=ITEM_DS_USAGE + ds["store"])
if "status" in section:
yield Service(item=ITEM_FS_ROOT)
# yield Service(item=ITEM_FS_SWAP)
def check_pbs_special_agent(item, section):
# pprint(section)
if "error" in section:
if item == ITEM_STATUS:
yield Result(state=State.CRIT, summary=section["error"])
return
if item == ITEM_STATUS:
status = section["status"]
version = section["version"]
yield Result(
state=State.OK,
summary=(
f"Version {version['version']}."
f"{version['release']}"
),
details=(
f"CPU: {status['cpuinfo']["model"]}, "
f"{status['cpuinfo']['sockets']} sockets, "
f"{status['cpuinfo']['cpus']} cores\n"
f"Kernel: {status['current-kernel']["sysname"]} "
f"{status['current-kernel']["release"]} "
f"{status['current-kernel']["machine"]} "
f"{status['current-kernel']["version"]}\n"
f"Bios: {status['boot-info']['mode']}, "
f"secureboot: {'on' if status['boot-info']['secureboot'] else 'off'}\n"
)
)
yield from parse_jobs(item, ITEM_SYNC_JOBS, section, "sync", "id")
yield from parse_jobs(item, ITEM_GC, section, "gc", "store")
yield from parse_jobs(item, ITEM_PRUNE, section, "prune", "id")
yield from parse_jobs(item, ITEM_VERIFY, section, "verify", "id")
if item == ITEM_CPU:
status = section["status"]
cpu_busy = float(status.get("cpu", 0.0)) * 100 # Prozent
cpu_wait = float(status.get("wait", 0.0)) * 100
yield Result(
state=State.OK,
summary=f"CPU Busy: {cpu_busy:.1f}%, IOWait: {cpu_wait:.1f}%"
)
yield Metric("cpu_busy", cpu_busy)
yield Metric("cpu_wait", cpu_wait)
if item == ITEM_MEM:
status = section["status"]
mem = status.get("memory", {})
total = mem.get("total", 0)
used = mem.get("used", 0)
free = mem.get("free", 0)
yield Result(
state=State.OK,
summary=f"Memory used: {used}, free: {free}, total: {total}",
)
yield Metric("mem_total", total)
yield Metric("mem_used", used)
yield Metric("mem_free", free)
if item == ITEM_LOAD:
status = section["status"]
loadavg = status.get("loadavg", [0.0, 0.0, 0.0])
load1, load5, load15 = [float(x) for x in loadavg]
yield Result(
state=State.OK,
summary=f"Load avg: {load1:.2f}, {load5:.2f}, {load15:.2f}",
)
yield Metric("load1", load1)
yield Metric("load5", load5)
yield Metric("load15", load15)
def check_pbs_special_agent_storage(item: str, params: list, section: dict):
if "error" in section:
return
if item.startswith(ITEM_DS_USAGE):
for ds in section["ds_usage"]:
if item.replace(ITEM_DS_USAGE, '') == ds["store"]:
try:
size_mb = float(ds['total']) / (1024 * 1024)
avail_mb = float(ds['avail']) / (1024 * 1024)
value_store = get_value_store()
yield from df_check_filesystem_single(
value_store=value_store,
mountpoint=ds["store"],
filesystem_size=size_mb,
free_space=avail_mb,
reserved_space=0,
inodes_total=None,
inodes_avail=None,
params=params,
this_time=None,
)
except Exception:
yield Result(
state=State.UNKNOWN,
summary="error checking datastore status"
)
if item == ITEM_FS_ROOT:
try:
fs_root = section["status"]["root"]
size_mb = float(fs_root['total'])/1024/1024 #ds['total'] returning bytes instead of mb
avail_mb = float(fs_root['avail'])/1024/1024 #ds['avail'] returning bytes instead of mb
print(size_mb)
value_store = get_value_store()
yield from df_check_filesystem_single(
value_store=value_store,
mountpoint="/root",
filesystem_size=size_mb,
free_space=avail_mb,
reserved_space=0, # See df.py: ... if (filesystem_size is None) or (free_space is None) or (reserved_space is None): yield Result(state=State.OK, summary="no filesystem size information")
inodes_total=None,
inodes_avail=None,
params=params,
this_time=None,
)
except Exception as e:
yield Result(
state=State.UNKNOWN,
summary=f"error checking root fs status"
)
agent_section_pbs_special_agent = AgentSection(
name = "pbs_special_agent",
parse_function = parse_pbs_special_agent,
)
check_plugin_pbs_special_agent_status = CheckPlugin(
name = "pbs_special_agent_status",
sections = [ "pbs_special_agent" ],
service_name = "PBS %s",
discovery_function = discover_pbs_special_agent,
check_function = check_pbs_special_agent,
)
check_plugin_pbs_special_agent_datastore = CheckPlugin(
name = "pbs_special_agent_ds",
sections = [ "pbs_special_agent" ],
service_name = "PBS %s",
discovery_function = discover_pbs_special_agent_storage,
check_function = check_pbs_special_agent_storage,
check_default_parameters=FILESYSTEM_DEFAULT_LEVELS,
check_ruleset_name="filesystem",
)