MKP 3.2.0 released, fixed bugs when users are deleted and rules without levels are active

This commit is contained in:
2026-03-09 11:25:48 +00:00
parent bf470d5d6c
commit 7f58381fd3
9 changed files with 87 additions and 40 deletions

View File

@@ -2,6 +2,7 @@
# pylint: disable=missing-module-docstring, unused-argument, missing-function-docstring
# pylint: disable=line-too-long
from typing import Final
from collections.abc import Mapping
from typing import NotRequired, TypedDict
@@ -18,6 +19,8 @@ from cmk.agent_based.v2 import (
DiscoveryResult,
)
NO_LEVELS: Final[str] = "no_levels"
class _ItemData(TypedDict):
dbtype: NotRequired[str]
@@ -49,14 +52,18 @@ def check_nextcloud_database(params, section) -> CheckResult:
size = section[key]["size"]
dbtype = section[key]["dbtype"]
version = section[key]["version"]
_level_type, levels = params["levels_database_opcache_hit_rate"]
level_type, levels = params["levels_database_opcache_hit_rate"]
# create graph for opcache hit rate
yield Metric(
"nc_database_opcache_hit_rate", opcache_hit_rate, levels=levels
)
if level_type == NO_LEVELS:
yield Metric("nc_database_opcache_hit_rate", opcache_hit_rate)
state = State.OK
else:
yield Metric(
"nc_database_opcache_hit_rate", opcache_hit_rate, levels=levels
)
state = get_state_lower(levels, opcache_hit_rate)
# create graph for database size
yield Metric("nc_database_size", size)
state = get_state_lower(levels, opcache_hit_rate)
summary = f"PHP OPCache hit rate: {render.percent(opcache_hit_rate)}"
if opcache_hit_rate == 0:
state = State.UNKNOWN

View File

@@ -3,6 +3,7 @@
# pylint: disable=line-too-long, too-many-branches, too-many-locals, too-many-statements
from datetime import datetime
from typing import Final
from cmk.agent_based.v2 import (
AgentSection,
@@ -17,6 +18,7 @@ from cmk.agent_based.v2 import (
DiscoveryResult,
)
NO_LEVELS: Final[str] = "no_levels"
def get_state_upper(levels, value):
warn, crit = levels
@@ -43,8 +45,8 @@ def discover_nextcloud_info(section) -> DiscoveryResult:
def check_nextcloud_info(params, section) -> CheckResult:
for key in section:
if key == "nextcloud":
_level_type, levels_free_space = params["levels_free_space"]
_level_type, levels_number_of_files = params["levels_number_of_files"]
level_type_free_space, levels_free_space = params["levels_free_space"]
level_type_number_of_files, levels_number_of_files = params["levels_number_of_files"]
# update infos are available only from Nextcloud version 28 onwards
try:
last_update = section[key]["last_update"]
@@ -89,19 +91,28 @@ def check_nextcloud_info(params, section) -> CheckResult:
# Create result for free space on disk
# Levels for free space are given in GBytes, we have to adjust this here
warn, crit = levels_free_space
warn = warn * 1024 * 1024 * 1024
crit = crit * 1024 * 1024 * 1024
state = get_state_lower((warn, crit), free_space)
# create graph for free space on disk
yield Metric("nc_free_space", free_space, levels=(warn, crit))
if level_type_free_space != NO_LEVELS:
warn, crit = levels_free_space
warn = warn * 1024 * 1024 * 1024
crit = crit * 1024 * 1024 * 1024
state = get_state_lower((warn, crit), free_space)
# create graph for free space on disk
yield Metric("nc_free_space", free_space, levels=(warn, crit))
else:
# a rule with no levels set is active, assume OK state
state = State.OK
yield Metric("nc_free_space", free_space)
notice = f"Remaining free space on disk: {render.bytes(free_space)}"
if state != State.OK:
yield Result(state=state, notice=notice)
# Create result for number of files
warn, crit = levels_number_of_files
state = get_state_upper((warn, crit), num_files)
if level_type_number_of_files != NO_LEVELS:
warn, crit = levels_number_of_files
state = get_state_upper((warn, crit), num_files)
else:
# a rule with no levels set is active, assume OK state
state = State.OK
notice = f"Number of files: {num_files}"
if state != State.OK:
yield Result(state=state, notice=notice)
@@ -139,14 +150,22 @@ def check_nextcloud_info(params, section) -> CheckResult:
else:
app_versions = ""
# create graphs for number of apps
_level_type, levels = params["levels_apps_with_updates_available"]
level_type, levels = params["levels_apps_with_updates_available"]
yield Metric("nc_num_apps_installed", num_apps_installed)
yield Metric(
"nc_apps_with_updates_available",
num_apps_with_updates_available,
levels=levels,
)
state = get_state_upper(levels, num_apps_with_updates_available)
if level_type != NO_LEVELS:
yield Metric(
"nc_apps_with_updates_available",
num_apps_with_updates_available,
levels=levels,
)
state = get_state_upper(levels, num_apps_with_updates_available)
else:
# a rule with no levels set is active, assume OK state
yield Metric(
"nc_apps_with_updates_available",
num_apps_with_updates_available,
)
state = State.OK
if app_versions == "":
notice = f"Number of installed apps: {num_apps_installed}\nNumber of apps with updates available: {num_apps_with_updates_available}"
else:

View File

@@ -3,7 +3,7 @@
# pylint: disable=line-too-long, too-many-locals
from time import time
from pprint import pprint
from typing import Final
from cmk.agent_based.v2 import (
AgentSection,
@@ -18,6 +18,7 @@ from cmk.agent_based.v2 import (
DiscoveryResult,
)
NO_LEVELS: Final[str] = "no_levels"
def get_state_upper(levels, value):
warn, crit = levels
@@ -43,6 +44,10 @@ def discover_nextcloud_users(section) -> DiscoveryResult:
def check_nextcloud_users(item, params, section) -> CheckResult:
attr = section.get(item)
if not attr:
yield Result(state=State.UNKNOWN, summary="User not found anymore, maybe it has been deleted.")
return
userid = item
quota_used_percent = section[item][0]
quota_used_bytes = section[item][1]
@@ -56,8 +61,8 @@ def check_nextcloud_users(item, params, section) -> CheckResult:
quota_is_set = False
else:
quota_is_set = True
_level_type, levels_quota_used = params["levels_users_quota_used"]
_level_type, levels_free_space = params["levels_users_free_space"]
level_type_quota_used, levels_quota_used = params["levels_users_quota_used"]
level_type_free_space, levels_free_space = params["levels_users_free_space"]
if (last_login_human == "never") or (not quota_is_set):
details = f"User ID is '{userid}', Last login: {last_login_human}"
summary = (
@@ -65,19 +70,29 @@ def check_nextcloud_users(item, params, section) -> CheckResult:
)
else:
# Levels are given in MBytes, we have to adjust this here
warn, crit = levels_free_space
warn = warn * 1024 * 1024
crit = crit * 1024 * 1024
state = get_state_lower((warn, crit), free_space)
if level_type_free_space != NO_LEVELS:
warn, crit = levels_free_space
warn = warn * 1024 * 1024
crit = crit * 1024 * 1024
state = get_state_lower((warn, crit), free_space)
yield Metric("nc_users_free_space", free_space, levels=(warn, crit))
else:
# a rule with no levels set is active, so assume OK state
state = State.OK
yield Metric("nc_users_free_space", free_space)
details = f"User ID is '{userid}'\nLast login: {last_login_human} ({last_login_since} ago)\nFree space: {render.bytes(free_space)}"
summary = f"Used quota of '{display_name}' is {render.percent(quota_used_percent)}, {render.bytes(quota_used_bytes)}/{render.bytes(quota_total_bytes)} used"
notice = f"Remaining free space: {render.bytes(free_space)}"
yield Metric("nc_users_free_space", free_space, levels=(warn, crit))
if state != State.OK:
yield Result(state=state, notice=notice)
yield Metric("nc_users_free_space", free_space, levels=(warn, crit))
yield Metric("nc_users_quota_used", quota_used_percent, levels=levels_quota_used)
state = get_state_upper(levels_quota_used, quota_used_percent)
if level_type_quota_used != NO_LEVELS:
yield Metric("nc_users_quota_used", quota_used_percent, levels=levels_quota_used)
state = get_state_upper(levels_quota_used, quota_used_percent)
else:
# a rule with no levels set is active, so assume OK state
yield Metric("nc_users_quota_used", quota_used_percent)
state = State.OK
yield Result(state=state, summary=summary, details=details)