diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_disk_usage_params.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_disk_usage_params.py deleted file mode 100644 index 4c477353330..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_disk_usage_params.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersOperatingSystem, -) -from cmk.gui.valuespec import Dictionary, Percentage, Tuple - - -def _parameter_valuespec_proxmox_ve_disk_percentage_levels(): - return Dictionary( - elements=[ - ( - "levels", - Tuple( - title=_("Levels"), - elements=[ - Percentage( - title=_("Warning at"), - default_value=80.0, - ), - Percentage( - title=_("Critical at"), - default_value=90.0, - ), - ], - ), - ), - ], - required_keys=["levels"], # There is only one value, so its required - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - check_group_name="proxmox_ve_disk_percentage_used", - group=RulespecGroupCheckParametersOperatingSystem, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_disk_percentage_levels, - title=lambda: _("Proxmox VE disk percentage used"), - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_mem_usage_prams.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_mem_usage_prams.py deleted file mode 100644 index 4090f9a79c8..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_mem_usage_prams.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersOperatingSystem, -) -from cmk.gui.valuespec import Dictionary, Percentage, Tuple - - -def _parameter_valuespec_proxmox_ve_mem_usage(): - return Dictionary( - required_keys=["levels"], - elements=[ - ( - "levels", - Tuple( - title=_("Levels"), - elements=[ - Percentage(title=_("Warning at"), default_value=80.0), - Percentage(title=_("Critical at"), default_value=90.0), - ], - ), - ), - ], - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - check_group_name="proxmox_ve_mem_usage", - group=RulespecGroupCheckParametersOperatingSystem, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_mem_usage, - title=lambda: _("Proxmox VE memory percentage used"), - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_node_info_params.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_node_info_params.py deleted file mode 100644 index 99714de06e8..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_node_info_params.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersApplications, -) -from cmk.gui.valuespec import Dictionary, Optional, TextInput - - -def _parameter_valuespec_proxmox_ve_node_info(): - # use Dictionary as Optional returning an empty dict if empty - return Dictionary( - elements=[ - ( - "required_node_status", - Optional( - title=_("Node Status"), - label=_("Activate Check (off: ignore node status)"), - default_value=True, - valuespec=TextInput( - title=_("Warn if node status value is not"), - default_value="online", - ), - ), - ), - ( - "required_subscription_status", - Optional( - title=_("Subscription Status"), - label=_("Activate Check (off: ignore subscription status)"), - default_value=True, - valuespec=TextInput( - title=_("Warn if subscription status value is not"), - default_value="Active", - ), - ), - ), - ] - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - title=lambda: _("Proxmox VE Node Info"), - check_group_name="proxmox_ve_node_info", - group=RulespecGroupCheckParametersApplications, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_node_info, - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_snapshot_age.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_snapshot_age.py deleted file mode 100644 index a5e722667f5..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_snapshot_age.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2021 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersApplications, -) -from cmk.gui.valuespec import Age, Dictionary, Tuple - - -def _parameter_valuespec_proxmox_ve_snapshot_age_requirements(): - return Dictionary( - elements=[ - ( - "oldest_levels", - Tuple( - title=_("Max age of the oldest snapshot"), - elements=[ - Age( - title=_("Warning at"), - display=["days", "hours"], - default_value=int(60 * 60 * 24 * 1), - ), - Age( - title=_("Critical at"), - display=["days", "hours"], - default_value=int(60 * 60 * 24 * 2), - ), - ], - ), - ) - ] - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - title=lambda: _("Proxmox VE VM Snapshot Age"), - check_group_name="proxmox_ve_vm_snapshot_age", - group=RulespecGroupCheckParametersApplications, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_snapshot_age_requirements, - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_backup_status_params.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_backup_status_params.py deleted file mode 100644 index 0e02a8dd56b..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_backup_status_params.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersApplications, -) -from cmk.gui.valuespec import Age, Alternative, Dictionary, FixedValue, Float, Tuple - - -def _parameter_valuespec_proxmox_ve_vm_backup_requirements(): - # use Dictionary as Optional returning an empty dict if empty - return Dictionary( - elements=[ - ( - "age_levels_upper", - Alternative( - title=_("Age levels"), - elements=[ - Tuple( - title=_("Set conditions"), - elements=[ - Age( - title=_("Warning at"), - display=["days", "hours", "minutes"], - # bit more than a day - default_value=int(60 * 60 * 26), - ), - Age( - title=_("Critical at"), - display=["days", "hours", "minutes"], - # bit more than two days - default_value=int(60 * 60 * 50), - ), - ], - ), - FixedValue(value=None, title=_("No Conditions"), totext=""), - ], - ), - ), - ( - "duration_levels_upper", - Alternative( - title=_("Duration levels"), - elements=[ - Tuple( - title=_("Set conditions"), - elements=[ - Age( - title=_("Warning at"), - display=["hours", "minutes"], - default_value=60, - ), - Age( - title=_("Critical at"), - display=["hours", "minutes"], - default_value=int(60 * 3), - ), - ], - ), - FixedValue(value=None, title=_("No Conditions"), totext=""), - ], - ), - ), - ( - "bandwidth_levels_lower", - Alternative( - title=_("Bandwidth levels"), - elements=[ - Tuple( - title=_("Set conditions"), - elements=[ - Float(title=_("Warning below"), size=15, unit="MB/s"), - Float(title=_("Critical below"), size=15, unit="MB/s"), - ], - ), - FixedValue(value=None, title=_("No Conditions"), totext=""), - ], - ), - ), - ] - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - title=lambda: _("Proxmox VE VM Backup"), - check_group_name="proxmox_ve_vm_backup_status", - group=RulespecGroupCheckParametersApplications, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_vm_backup_requirements, - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_info_params.py b/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_info_params.py deleted file mode 100644 index 8ee198a162b..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/proxmox_ve_vm_info_params.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 -# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and -# conditions defined in the file COPYING, which is part of this source code package. - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import ( - CheckParameterRulespecWithoutItem, - rulespec_registry, - RulespecGroupCheckParametersApplications, -) -from cmk.gui.valuespec import Dictionary, Optional, TextInput - - -def _parameter_valuespec_proxmox_ve_vm_info(): - # use Dictionary as Optional returning an empty dict if empty - return Dictionary( - title=_("Check Parameter"), - elements=[ - ( - "required_vm_status", - Optional( - title=_("Modify: Check VM Status (off: keep default)"), - label=_("Activate Check (off: ignore VM status)"), - default_value=True, - valuespec=TextInput( - title=_("Warn if VM status value is not"), - default_value="running", - ), - ), - ) - ], - ) - - -rulespec_registry.register( - CheckParameterRulespecWithoutItem( - title=lambda: _("Proxmox VE VM Info"), - check_group_name="proxmox_ve_vm_info", - group=RulespecGroupCheckParametersApplications, - match_type="dict", - parameter_valuespec=_parameter_valuespec_proxmox_ve_vm_info, - ) -) diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_backup_status.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_backup_status.py index ff99c51730f..3e614d176a1 100644 --- a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_backup_status.py +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_backup_status.py @@ -100,7 +100,7 @@ def check_proxmox_ve_vm_backup_status( levels and define result status accordingly >>> for result in check_proxmox_ve_vm_backup_status( ... datetime.strptime("2020-12-07 21:28:02+01:00", '%Y-%m-%d %H:%M:%S%z'), - ... {'age_levels_upper': (93600, 180000)}, + ... {'age_levels_upper': (93600.0, 180000.0)}, ... parse_proxmox_ve_vm_backup_status([[ ... ' {"last_backup": {' ... ' "started_time": "2020-12-06 21:28:02+0000",' @@ -121,17 +121,18 @@ def check_proxmox_ve_vm_backup_status( Result(state=, summary='Bandwidth: 91.6 MB/s') Metric('backup_avgspeed', 91625968.975, boundaries=(0.0, None)) """ - age_levels_upper = params.get("age_levels_upper") - duration_levels_upper = params.get("duration_levels_upper") - bandwidth_levels_lower_bytes = params.get("bandwidth_levels_lower") - bandwidth_levels_lower = ( - ( - bandwidth_levels_lower_bytes[0] * 1000 * 1000, - bandwidth_levels_lower_bytes[1] * 1000 * 1000, - ) - if bandwidth_levels_lower_bytes - else None + + age_levels_upper = ( + int(params["age_levels_upper"][0]), + int(params["age_levels_upper"][1]), ) + duration_levels_upper = None + if params.get("duration_levels_upper") is not None: + duration_levels_upper = ( + int(params["duration_levels_upper"][0]), + int(params["duration_levels_upper"][1]), + ) + last_backup = section.get("last_backup") if not last_backup: yield ( @@ -203,7 +204,7 @@ def check_proxmox_ve_vm_backup_status( yield from check_levels_v1( value=bandwidth, - levels_lower=bandwidth_levels_lower, + levels_lower=params["bandwidth_levels_lower"], metric_name="backup_avgspeed", render_func=render.iobandwidth, label="Bandwidth", diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_cpu_util.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_cpu_util.py new file mode 100644 index 00000000000..3c420350c92 --- /dev/null +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_cpu_util.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +import json +from collections.abc import Mapping +from typing import Any + +from cmk.agent_based.v1 import check_levels as check_levels_v1 +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + CheckResult, + DiscoveryResult, + get_value_store, + Result, + Service, + State, + StringTable, +) +from cmk.plugins.lib.cpu_util import check_cpu_util + +Section = Mapping[str, float] + + +def parse_proxmox_ve_cpu_util(string_table: StringTable) -> Section: + return {key: float(value) for key, value in json.loads(string_table[0][0]).items()} + + +def discover_single(section: Section) -> DiscoveryResult: + yield Service() + + +def check_proxmox_ve_cpu_util(params: Mapping[str, Any], section: Section) -> CheckResult: + """ + >>> for result in check_proxmox_ve_cpu_util( + ... { + ... "util": (90.0, 95.0), + ... }, + ... parse_proxmox_ve_cpu_util([['{"max_cpu": 16.0, "cpu": 0.319682438494757, "uptime": 2427306.0}']])): + ... print(result) + Result(state=, summary='Total CPU: 31.97%') + Metric('util', 31.9682438494757, levels=(90.0, 95.0), boundaries=(0.0, 100.0)) + Result(state=, summary='CPU cores assigned: 16') + Result(state=, summary='CPU Core usage: 5.11') + Metric('cpu_core_usage', 5.11, levels=(14.4, 15.2), boundaries=(0.0, 16.0) + """ + max_cpu = int(section.get("max_cpu", 0)) + cpu_util = float(section.get("cpu", 0)) + uptime = int(section.get("uptime", 0)) + + value_store = get_value_store() + + yield from check_cpu_util( + util=cpu_util * 100, + params=params, + value_store=value_store, + this_time=uptime, + ) + + yield Result(state=State.OK, summary=f"CPU cores assigned: {max_cpu}") + + if params["util"] is not None: + (warn, crit) = params["util"] + cores_levels = (warn * max_cpu / 100, crit * max_cpu / 100) + else: + cores_levels = None + + yield from check_levels_v1( + value=round(max_cpu * cpu_util, 2), + levels_upper=cores_levels, + metric_name="cpu_core_usage", + label="CPU Core usage", + boundaries=(0.0, max_cpu), + ) + + +agent_section_proxmox_ve_cpu_util = AgentSection( + name="proxmox_ve_cpu_util", + parse_function=parse_proxmox_ve_cpu_util, +) + +check_plugin_proxmox_ve_cpu_util = CheckPlugin( + name="proxmox_ve_cpu_util", + service_name="Proxmox VE CPU Utilization", + discovery_function=discover_single, + check_function=check_proxmox_ve_cpu_util, + check_ruleset_name="proxmox_ve_cpu_util", + check_default_parameters={ + "util": (90.0, 95.0), + }, +) diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_throughput.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_throughput.py new file mode 100644 index 00000000000..0ee48f8afaf --- /dev/null +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_throughput.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +import json +from collections.abc import Mapping +from typing import Any + +from cmk.agent_based.v1 import check_levels as check_levels_v1 +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + CheckResult, + DiscoveryResult, + get_value_store, + render, + Service, + StringTable, +) + +Section = Mapping[str, int] + + +def parse_proxmox_ve_disk_throughput(string_table: StringTable) -> Section: + return {key: int(value) for key, value in json.loads(string_table[0][0]).items()} + + +def discover_single(section: Section) -> DiscoveryResult: + yield Service() + + +def check_proxmox_ve_disk_throughput(params: Mapping[str, Any], section: Section) -> CheckResult: + """ + >>> for result in check_proxmox_ve_disk_throughput( + ... { + ... "read_levels": None, + ... "write_levels": None, + ... }, + ... parse_proxmox_ve_disk_throughput([['{"disk_read": 234944108544, "disk_write": 5909099398656, "uptime": 2343655}']])): + ... print(result) + Result(state=, summary='Read IO: 8.53 B/s') + Result(state=, summary='Write IO: 2.90 MB/s') + Metric('disk_read_throughput', 2184.533333333333, levels=None, boundaries=(0.0, None)) + Metric('disk_write_throughput', 2738558.780952381, levels=None, boundaries=(0.0, None)) + """ + disk_read = section.get("disk_read", 0) + disk_write = section.get("disk_write", 0) + uptime = section.get("uptime", 0) + + value_store = get_value_store() + + last_read = value_store.get("last_read", 0) + last_write = value_store.get("last_write", 0) + last_uptime = value_store.get("last_uptime", 0) + + if uptime == 0: + read_throughput = float(disk_read) + write_throughput = float(disk_write) + elif uptime > last_uptime: + read_throughput = (disk_read - last_read) / (uptime - last_uptime) + write_throughput = (disk_write - last_write) / (uptime - last_uptime) + else: + read_throughput = disk_read / uptime + write_throughput = disk_write / uptime + + value_store["last_read"] = disk_read + value_store["last_write"] = disk_write + value_store["last_uptime"] = uptime + + yield from check_levels_v1( + value=read_throughput, + levels_upper=params["read_levels"], + metric_name="disk_read_throughput", + render_func=render.iobandwidth, + label="Read", + boundaries=(0, None), + ) + + yield from check_levels_v1( + value=write_throughput, + levels_upper=params["write_levels"], + metric_name="disk_write_throughput", + render_func=render.iobandwidth, + label="Write", + boundaries=(0, None), + ) + + +agent_section_proxmox_ve_disk_throughput = AgentSection( + name="proxmox_ve_disk_throughput", + parse_function=parse_proxmox_ve_disk_throughput, +) + +check_plugin_proxmox_ve_disk_throughput = CheckPlugin( + name="proxmox_ve_disk_throughput", + service_name="Proxmox VE Disk Throughput", + discovery_function=discover_single, + check_function=check_proxmox_ve_disk_throughput, + check_ruleset_name="proxmox_ve_disk_throughput", + check_default_parameters={ + "read_levels": None, + "write_levels": None, + }, +) diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_usage.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_usage.py index 5d4bf1e6769..8075039d9aa 100644 --- a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_usage.py +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_disk_usage.py @@ -74,7 +74,8 @@ def check_proxmox_ve_disk_usage(params: Mapping[str, Any], section: Section) -> label="Used", ) yield Result( - state=State.OK, summary=f"{render.disksize(used_bytes)} of {render.disksize(total_bytes)}" + state=State.OK, + summary=f"{render.disksize(used_bytes)} of {render.disksize(total_bytes)}", ) yield Metric( diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_network_throughput.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_network_throughput.py new file mode 100644 index 00000000000..b69723e8958 --- /dev/null +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_network_throughput.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +import json +from collections.abc import Mapping +from typing import Any + +from cmk.agent_based.v1 import check_levels as check_levels_v1 +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + CheckResult, + DiscoveryResult, + get_value_store, + render, + Service, + StringTable, +) + +Section = Mapping[str, int] + + +def parse_proxmox_ve_network_throughput(string_table: StringTable) -> Section: + return {key: int(value) for key, value in json.loads(string_table[0][0]).items()} + + +def discover_single(section: Section) -> DiscoveryResult: + yield Service() + + +def check_proxmox_ve_network_throughput(params: Mapping[str, Any], section: Section) -> CheckResult: + """ + >>> for result in check_proxmox_ve_network_throughput( + ... { + ... "in_levels": None, + ... "out_levels": None, + ... }, + ... parse_proxmox_ve_network_throughput([['{"net_in": 18999433043, "net_out": 25363852710, "uptime": 2406220}']])): + ... print(result) + Result(state=, summary='Inbound: 1.29 kB/s') + Result(state=, summary='Outbound: 855 B/s') + Metric('net_in_throughput', 1285.7333333333333, levels=None, boundaries=(0.0, None)) + Metric('net_out_throughput', 855.3166666666667, levels=None, boundaries=(0.0, None)) + """ + net_in = section.get("net_in", 0) + net_out = section.get("net_out", 0) + uptime = section.get("uptime", 0) + + value_store = get_value_store() + + last_in = value_store.get("last_in", 0) + last_out = value_store.get("last_out", 0) + last_uptime = value_store.get("last_uptime", 0) + + if uptime == 0: + in_throughput = float(net_in) + out_throughput = float(net_out) + elif uptime > last_uptime: + in_throughput = (net_in - last_in) / (uptime - last_uptime) + out_throughput = (net_out - last_out) / (uptime - last_uptime) + else: + in_throughput = net_in / uptime + out_throughput = net_out / uptime + + value_store["last_in"] = net_in + value_store["last_out"] = net_out + value_store["last_uptime"] = uptime + + yield from check_levels_v1( + value=in_throughput, + levels_upper=params["in_levels"], + metric_name="net_in_throughput", + render_func=render.iobandwidth, + label="Inbound", + boundaries=(0, None), + ) + + yield from check_levels_v1( + value=out_throughput, + levels_upper=params["out_levels"], + metric_name="net_out_throughput", + render_func=render.iobandwidth, + label="Outbound", + boundaries=(0, None), + ) + + +agent_section_proxmox_ve_network_throughput = AgentSection( + name="proxmox_ve_network_throughput", + parse_function=parse_proxmox_ve_network_throughput, +) + +check_plugin_proxmox_ve_network_throughput = CheckPlugin( + name="proxmox_ve_network_throughput", + service_name="Proxmox VE Network Throughput", + discovery_function=discover_single, + check_function=check_proxmox_ve_network_throughput, + check_ruleset_name="proxmox_ve_network_throughput", + check_default_parameters={ + "in_levels": None, + "out_levels": None, + }, +) diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_snapshot_age.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_snapshot_age.py index e09e7f77cef..c056b13699b 100644 --- a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_snapshot_age.py +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_snapshot_age.py @@ -40,13 +40,14 @@ def check_proxmox_ve_snapshot_age(params: Mapping[str, Any], section: Section) - # timestamps and timezones... age = max(time.time() - min(section["snaptimes"]), 0) + oldest_levels = (int(params["oldest_levels"][0]), int(params["oldest_levels"][1])) yield from check_levels_v1( age, - levels_upper=params["oldest_levels"], + levels_upper=oldest_levels, metric_name="age", render_func=render.timespan, label="Age", - boundaries=params["oldest_levels"], + boundaries=oldest_levels, ) @@ -63,8 +64,8 @@ def check_proxmox_ve_snapshot_age(params: Mapping[str, Any], section: Section) - check_ruleset_name="proxmox_ve_vm_snapshot_age", check_default_parameters={ "oldest_levels": ( - 60 * 60 * 24 * 1, - 60 * 60 * 24 * 2, + 60.0 * 60.0 * 24.0 * 1.0, + 60.0 * 60.0 * 24.0 * 2.0, ) }, ) diff --git a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_vm_info.py b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_vm_info.py index 25b5e359414..d6d097ab878 100644 --- a/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_vm_info.py +++ b/cmk/plugins/proxmox_ve/agent_based/proxmox_ve_vm_info.py @@ -3,6 +3,7 @@ # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. +import datetime import json from collections.abc import Mapping from typing import Any @@ -38,13 +39,16 @@ def check_proxmox_ve_vm_info(params: Mapping[str, Any], section: Section) -> Che ... ' "node": "pve-muc",' ... ' "status": "running",' ... ' "type": "qemu",' - ... ' "vmid": "109"}' + ... ' "vmid": "109",' + ... ' "uptime": "265421"}' ... ]])): ... print(result) Result(state=, summary='VM ID: 109') Result(state=, summary='Status: running') Result(state=, summary='Type: qemu') Result(state=, summary='Host: pve-muc') + Result(state=, summary='Up since 2025-02-01 15:33:09') + Result(state=, summary='Uptime: 3 days 1 hours') """ vm_status = section.get("status", "n/a").lower() req_vm_status = (params.get("required_vm_status") or "").lower() @@ -55,6 +59,15 @@ def check_proxmox_ve_vm_info(params: Mapping[str, Any], section: Section) -> Che ) yield Result(state=State.OK, summary=f"Type: {section.get('type')}") yield Result(state=State.OK, summary=f"Host: {section.get('node')}") + td = datetime.timedelta(seconds=section.get("uptime", 0)) + startup_date = datetime.datetime.today() - td + startup_string = startup_date.strftime("%Y-%m-%d %H:%M:%S") + if td.days % 365 > 0: + uptime_string = f"Uptime: {td.days % 365} years {td.days // 365} days" + else: + uptime_string = f"Uptime: {td.days} days {td.seconds // 3600} hours" + yield Result(state=State.OK, summary=f"Up since {startup_string}") + yield Result(state=State.OK, summary=f"Up since {uptime_string}") agent_section_proxmox_ve_vm_info = AgentSection( diff --git a/cmk/plugins/proxmox_ve/checkman/proxmox_ve_cpu_util b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_cpu_util new file mode 100644 index 00000000000..90c2d4bf578 --- /dev/null +++ b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_cpu_util @@ -0,0 +1,11 @@ +title: Proxmox VE: CPU utilization +agents: proxmox_ve +catalog: os/misc +license: GPLv2 +distribution: check_mk +description: + This check is OK when CPU utilization is below a configurable set of levels or if no levels have + been set. It shows CPU utilization as a percentage, as well as a core count. + +discovery: + One service per system is created. diff --git a/cmk/plugins/proxmox_ve/checkman/proxmox_ve_disk_throughput b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_disk_throughput new file mode 100644 index 00000000000..307d34ca78f --- /dev/null +++ b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_disk_throughput @@ -0,0 +1,11 @@ +title: Proxmox VE: Disk Throughput +agents: proxmox_ve +catalog: os/misc +license: GPLv2 +distribution: check_mk +description: + This check is OK when disk throughput is below a configurable set of levels or if no levels have + been set. It shows the current disk read/write throughput. + +discovery: + One service per system is created. diff --git a/cmk/plugins/proxmox_ve/checkman/proxmox_ve_network_throughput b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_network_throughput new file mode 100644 index 00000000000..f0cdc717a77 --- /dev/null +++ b/cmk/plugins/proxmox_ve/checkman/proxmox_ve_network_throughput @@ -0,0 +1,11 @@ +title: Proxmox VE: Network Throughput +agents: proxmox_ve +catalog: os/misc +license: GPLv2 +distribution: check_mk +description: + This check is OK when network throughput is below a configurable set of levels or if no levels have + been set. It shows the current network in/out throughput. + +discovery: + One service per system is created. diff --git a/cmk/plugins/proxmox_ve/graphing/proxmox_ve_cpu_util.py b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_cpu_util.py new file mode 100644 index 00000000000..5ba8266c6de --- /dev/null +++ b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_cpu_util.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. + +from cmk.graphing.v1 import graphs, metrics, Title + +metric_disk_read_throughput = metrics.Metric( + name="cpu_core_usage", + title=Title("CPU Core Usage"), + unit=metrics.Unit(metrics.DecimalNotation(""), metrics.StrictPrecision(digits=2)), + color=metrics.Color.BLUE, +) + +graph_cpu_usage = graphs.Graph( + name="cpu_core_usage", + title=Title("CPU Cores"), + compound_lines=["cpu_core_usage"], + simple_lines=[ + metrics.WarningOf("cpu_core_usage"), + metrics.CriticalOf("cpu_core_usage"), + ], +) diff --git a/cmk/plugins/proxmox_ve/graphing/proxmox_ve_disk_throughput.py b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_disk_throughput.py new file mode 100644 index 00000000000..dc00f0f8295 --- /dev/null +++ b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_disk_throughput.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. + +from cmk.graphing.v1 import graphs, metrics, perfometers, Title + +UNIT_BYTES_PER_SECOND = metrics.Unit(metrics.IECNotation("B/s")) + +metric_disk_read_throughput = metrics.Metric( + name="disk_read_throughput", + title=Title("Disk read"), + unit=UNIT_BYTES_PER_SECOND, + color=metrics.Color.BLUE, +) + +metric_disk_write_throughput = metrics.Metric( + name="disk_write_throughput", + title=Title("Disk write"), + unit=UNIT_BYTES_PER_SECOND, + color=metrics.Color.GREEN, +) + +perfometer_disk_throughput = perfometers.Bidirectional( + name="disk_throughput", + left=perfometers.Perfometer( + name="disk_read_throughput", + focus_range=perfometers.FocusRange(perfometers.Closed(0), perfometers.Open(9000000)), + segments=["disk_read_throughput"], + ), + right=perfometers.Perfometer( + name="disk_write_throughput", + focus_range=perfometers.FocusRange(perfometers.Closed(0), perfometers.Open(9000000)), + segments=["disk_write_throughput"], + ), +) + +graph_disk_throughput = graphs.Bidirectional( + name="disk_throughput", + title=Title("Disk Throughput"), + lower=graphs.Graph( + name="disk_read_throughput", + title=Title("Read Throughput"), + compound_lines=["disk_read_throughput"], + simple_lines=[ + metrics.WarningOf("disk_read_throughput"), + metrics.CriticalOf("disk_read_throughput"), + ], + ), + upper=graphs.Graph( + name="disk_write_throughput", + title=Title("Write Throughput"), + compound_lines=["disk_write_throughput"], + simple_lines=[ + metrics.WarningOf("disk_write_throughput"), + metrics.CriticalOf("disk_write_throughput"), + ], + ), +) diff --git a/cmk/plugins/proxmox_ve/graphing/proxmox_ve_network_throughput.py b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_network_throughput.py new file mode 100644 index 00000000000..5ce5f1108dd --- /dev/null +++ b/cmk/plugins/proxmox_ve/graphing/proxmox_ve_network_throughput.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. + +from cmk.graphing.v1 import graphs, metrics, perfometers, Title + +UNIT_BYTES_PER_SECOND = metrics.Unit(metrics.IECNotation("B/s")) + +metric_net_in_throughput = metrics.Metric( + name="net_in_throughput", + title=Title("Network Inbound"), + unit=UNIT_BYTES_PER_SECOND, + color=metrics.Color.BLUE, +) + +metric_net_out_throughput = metrics.Metric( + name="net_out_throughput", + title=Title("Network Outbound"), + unit=UNIT_BYTES_PER_SECOND, + color=metrics.Color.GREEN, +) + +perfometer_network_throughput = perfometers.Bidirectional( + name="network_throughput", + left=perfometers.Perfometer( + name="net_in_throughput", + focus_range=perfometers.FocusRange(perfometers.Closed(0), perfometers.Open(9000000)), + segments=["net_in_throughput"], + ), + right=perfometers.Perfometer( + name="net_out_throughput", + focus_range=perfometers.FocusRange(perfometers.Closed(0), perfometers.Open(9000000)), + segments=["net_out_throughput"], + ), +) + +graph_network_throughput = graphs.Bidirectional( + name="network_throughput", + title=Title("Network Throughput"), + lower=graphs.Graph( + name="net_in_throughput", + title=Title("In Throughput"), + compound_lines=["net_in_throughput"], + simple_lines=[ + metrics.WarningOf("net_in_throughput"), + metrics.CriticalOf("net_in_throughput"), + ], + ), + upper=graphs.Graph( + name="net_out_throughput", + title=Title("Out Throughput"), + compound_lines=["net_out_throughput"], + simple_lines=[ + metrics.WarningOf("net_out_throughput"), + metrics.CriticalOf("net_out_throughput"), + ], + ), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_cpu_util_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_cpu_util_params.py new file mode 100644 index 00000000000..4130be9a1c6 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_cpu_util_params.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + Integer, + LevelDirection, + Percentage, + SimpleLevels, + validators, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_cpu_util(): + return Dictionary( + elements={ + "util": DictElement( + required=True, + parameter_form=SimpleLevels( + title=Title("CPU Utilization levels"), + prefill_fixed_levels=DefaultValue(value=(90.0, 95.0)), + level_direction=LevelDirection.UPPER, + form_spec_template=Percentage(), + ), + ), + "average": DictElement( + required=False, + parameter_form=Integer( + title=Title("Average CPU Value over"), + unit_symbol="minutes", + prefill=DefaultValue(1), + custom_validate=(validators.NumberInRange(min_value=1),), + ), + ), + } + ) + + +rule_spec_proxmox_ve_cpu_util = CheckParameters( + name="proxmox_ve_cpu_util", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_cpu_util, + title=Title("Proxmox VE CPU Utilization"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_throughput_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_throughput_params.py new file mode 100644 index 00000000000..9eed35b9265 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_throughput_params.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + DataSize, + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + Levels, + migrate_to_upper_integer_levels, + PredictiveLevels, + SIMagnitude, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_disk_throughput(): + return Dictionary( + elements={ + "read_levels": DictElement( + required=True, + parameter_form=Levels( + title=Title("Read levels (per second)"), + level_direction=LevelDirection.UPPER, + form_spec_template=DataSize( + label=Label("/s"), + displayed_magnitudes=[SIMagnitude.MEGA], + ), + prefill_fixed_levels=DefaultValue(value=(50_000_000, 100_000_000)), + predictive=PredictiveLevels( + reference_metric="disk_read_throughput", + prefill_abs_diff=DefaultValue(value=(0.0, 0.0)), + ), + migrate=migrate_to_upper_integer_levels, + ), + ), + "write_levels": DictElement( + required=True, + parameter_form=Levels( + title=Title("Write levels (per second)"), + level_direction=LevelDirection.UPPER, + form_spec_template=DataSize( + label=Label("/s"), + displayed_magnitudes=[SIMagnitude.MEGA], + ), + prefill_fixed_levels=DefaultValue(value=(50_000_000, 100_000_000)), + predictive=PredictiveLevels( + reference_metric="disk_write_throughput", + prefill_abs_diff=DefaultValue(value=(0.0, 0.0)), + ), + migrate=migrate_to_upper_integer_levels, + ), + ), + } + ) + + +rule_spec_proxmox_ve_disk_throughput = CheckParameters( + name="proxmox_ve_disk_throughput", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_disk_throughput, + title=Title("Proxmox VE disk throughput"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_usage_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_usage_params.py new file mode 100644 index 00000000000..4ea9c8d82e5 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_disk_usage_params.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + Percentage, + SimpleLevels, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_disk_percentage_levels(): + return Dictionary( + elements={ + "levels": DictElement( + required=True, + parameter_form=SimpleLevels( + title=Title("Levels"), + level_direction=LevelDirection.UPPER, + form_spec_template=Percentage(), + prefill_fixed_levels=DefaultValue(value=(80.0, 90.0)), + ), + ) + } + ) + + +rule_spec_proxmox_ve_disk_percentage_used = CheckParameters( + name="proxmox_ve_disk_percentage_used", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_disk_percentage_levels, + title=Title("Proxmox VE disk percentage used"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_mem_usage_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_mem_usage_params.py new file mode 100644 index 00000000000..d012986196a --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_mem_usage_params.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + Percentage, + SimpleLevels, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_mem_usage(): + return Dictionary( + elements={ + "levels": DictElement( + required=True, + parameter_form=SimpleLevels( + title=Title("Levels"), + level_direction=LevelDirection.UPPER, + form_spec_template=Percentage(), + prefill_fixed_levels=DefaultValue(value=(80.0, 90.0)), + ), + ) + } + ) + + +rule_spec_proxmox_ve_mem_usage = CheckParameters( + name="proxmox_ve_mem_usage", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_mem_usage, + title=Title("Proxmox VE memory percentage used"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_network_throughput_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_network_throughput_params.py new file mode 100644 index 00000000000..afe9230bae7 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_network_throughput_params.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + DataSize, + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + Levels, + migrate_to_upper_integer_levels, + PredictiveLevels, + SIMagnitude, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_network_throughput(): + return Dictionary( + elements={ + "in_levels": DictElement( + required=True, + parameter_form=Levels( + title=Title("Inbound levels (per second)"), + level_direction=LevelDirection.UPPER, + form_spec_template=DataSize( + label=Label("/s"), + displayed_magnitudes=[SIMagnitude.MEGA], + ), + prefill_fixed_levels=DefaultValue(value=(50_000_000, 100_000_000)), + predictive=PredictiveLevels( + reference_metric="net_in_throughput", + prefill_abs_diff=DefaultValue(value=(0.0, 0.0)), + ), + migrate=migrate_to_upper_integer_levels, + ), + ), + "out_levels": DictElement( + required=True, + parameter_form=Levels( + title=Title("Outbound levels (per second)"), + level_direction=LevelDirection.UPPER, + form_spec_template=DataSize( + label=Label("/s"), + displayed_magnitudes=[SIMagnitude.MEGA], + ), + prefill_fixed_levels=DefaultValue(value=(50_000_000, 100_000_000)), + predictive=PredictiveLevels( + reference_metric="net_out_throughput", + prefill_abs_diff=DefaultValue(value=(0.0, 0.0)), + ), + migrate=migrate_to_upper_integer_levels, + ), + ), + } + ) + + +rule_spec_proxmox_ve_network_throughput = CheckParameters( + name="proxmox_ve_network_throughput", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_network_throughput, + title=Title("Proxmox VE network throughput"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_node_info_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_node_info_params.py new file mode 100644 index 00000000000..4eb44276dfc --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_node_info_params.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + String, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_node_info(): + return Dictionary( + elements={ + "required_node_status": DictElement( + required=False, + parameter_form=String( + title=Title("Node Status (off: ignore node status)"), + label=Label("Warn if node status value is not"), + prefill=DefaultValue("online"), + ), + ), + "required_subscription_status": DictElement( + required=False, + parameter_form=String( + title=Title("Subscription Status (off: ignore subscription status)"), + label=Label("Warn if subscription status value is not"), + prefill=DefaultValue("Active"), + ), + ), + } + ) + + +rule_spec_proxmox_ve_node_info = CheckParameters( + name="proxmox_ve_node_info", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_node_info, + title=Title("Proxmox VE Node Info"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_snapshot_age_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_snapshot_age_params.py new file mode 100644 index 00000000000..c7d90887054 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_snapshot_age_params.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + SimpleLevels, + TimeMagnitude, + TimeSpan, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_snapshot_age_requirements(): + return Dictionary( + elements={ + "oldest_levels": DictElement( + required=True, + parameter_form=SimpleLevels( + title=Title("Max age of the oldest snapshot"), + level_direction=LevelDirection.UPPER, + form_spec_template=TimeSpan( + displayed_magnitudes=[ + TimeMagnitude.DAY, + TimeMagnitude.HOUR, + ] + ), + prefill_fixed_levels=DefaultValue( + value=(60.0 * 60.0 * 24.0, 60.0 * 60.0 * 24.0 * 2.0) + ), + ), + ) + } + ) + + +rule_spec_proxmox_ve_vm_snapshot_age = CheckParameters( + name="proxmox_ve_vm_snapshot_age", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_snapshot_age_requirements, + title=Title("Proxmox VE VM Snapshot Age"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_backup_status_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_backup_status_params.py new file mode 100644 index 00000000000..fda93473430 --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_backup_status_params.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + DataSize, + DefaultValue, + DictElement, + Dictionary, + LevelDirection, + SIMagnitude, + SimpleLevels, + TimeMagnitude, + TimeSpan, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_vm_backup_requirements(): + return Dictionary( + elements={ + "age_levels_upper": DictElement( + required=False, + parameter_form=SimpleLevels( + title=Title("Age levels"), + level_direction=LevelDirection.UPPER, + form_spec_template=TimeSpan( + displayed_magnitudes=[ + TimeMagnitude.DAY, + TimeMagnitude.HOUR, + TimeMagnitude.MINUTE, + ] + ), + prefill_fixed_levels=DefaultValue( + value=( + 60.0 * 60.0 * 26.0, # a bit more than a day + 60.0 * 60.0 * 50.0, # a bit more than two days + ) + ), + ), + ), + "duration_levels_upper": DictElement( + required=False, + parameter_form=SimpleLevels( + title=Title("Duration levels"), + level_direction=LevelDirection.UPPER, + form_spec_template=TimeSpan( + displayed_magnitudes=[ + TimeMagnitude.HOUR, + TimeMagnitude.MINUTE, + ] + ), + prefill_fixed_levels=DefaultValue(value=(60.0, 60.0 * 3.0)), + ), + ), + "bandwidth_levels_lower": DictElement( + required=False, + parameter_form=SimpleLevels( + title=Title("Bandwidth levels (per second)"), + level_direction=LevelDirection.LOWER, + form_spec_template=DataSize( + label=Label("/s"), + displayed_magnitudes=[SIMagnitude.MEGA], + ), + prefill_fixed_levels=DefaultValue(value=(10_000_000, 5_000_000)), + ), + ), + } + ) + + +rule_spec_proxmox_ve_vm_backup_status = CheckParameters( + name="proxmox_ve_vm_backup_status", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_vm_backup_requirements, + title=Title("Proxmox VE VM Backup"), + condition=HostCondition(), +) diff --git a/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_info_params.py b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_info_params.py new file mode 100644 index 00000000000..181d033dffa --- /dev/null +++ b/cmk/plugins/proxmox_ve/rulesets/proxmox_ve_vm_info_params.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2 +# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and +# conditions defined in the file COPYING, which is part of this source code package. +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + String, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + + +def _parameter_valuespec_proxmox_ve_vm_info(): + return Dictionary( + title=Title("Check Parameter"), + elements={ + "required_vm_status": DictElement( + required=False, + parameter_form=String( + title=Title("Modify: Check VM Status (off: ignore VM status)"), + label=Label("Warn if VM status value is not"), + prefill=DefaultValue("running"), + ), + ) + }, + ) + + +rule_spec_proxmox_ve_vm_info = CheckParameters( + name="proxmox_ve_vm_info", + topic=Topic.CLOUD, + parameter_form=_parameter_valuespec_proxmox_ve_vm_info, + title=Title("Proxmox VE VM Info"), + condition=HostCondition(), +) diff --git a/cmk/special_agents/agent_proxmox_ve.py b/cmk/special_agents/agent_proxmox_ve.py index 6db87e1e050..0a0c6eceb44 100755 --- a/cmk/special_agents/agent_proxmox_ve.py +++ b/cmk/special_agents/agent_proxmox_ve.py @@ -41,7 +41,10 @@ SectionWriter, special_agent_main, ) -from cmk.special_agents.v0_unstable.argument_parsing import Args, create_default_argument_parser +from cmk.special_agents.v0_unstable.argument_parsing import ( + Args, + create_default_argument_parser, +) from cmk.special_agents.v0_unstable.misc import JsonCachedData, to_bytes LOGGER = logging.getLogger("agent_proxmox_ve") @@ -84,7 +87,11 @@ def __init__(self, line: int, msg: str) -> None: self.line = line def __repr__(self) -> str: - return "%s(%d, %r)" % (self.__class__.__name__, self.line, super().__str__()) + return "%s(%d, %r)" % ( + self.__class__.__name__, + self.line, + super().__str__(), + ) class LogParseWarning(LogParseError): """Less critical version of LogParseError""" @@ -215,10 +222,27 @@ def _extract_logs( ) } required_keys = ( - {"started_time", "total_duration", "bytes_written_bandwidth", "bytes_written_size"}, + { + "started_time", + "total_duration", + "bytes_written_bandwidth", + "bytes_written_size", + }, {"started_time", "total_duration", "transfer_size", "transfer_time"}, - {"started_time", "total_duration", "upload_amount", "upload_time", "upload_total"}, - {"started_time", "total_duration", "backup_amount", "backup_time", "backup_total"}, + { + "started_time", + "total_duration", + "upload_amount", + "upload_time", + "upload_total", + }, + { + "started_time", + "total_duration", + "backup_amount", + "backup_time", + "backup_total", + }, {"started_time", "total_duration", "archive_name", "archive_size"}, ) @@ -369,7 +393,9 @@ def duration_from_string(string: str) -> float: return result, errors -def collect_vm_backup_info(backup_tasks: Iterable[BackupTask]) -> Mapping[str, BackupInfo]: +def collect_vm_backup_info( + backup_tasks: Iterable[BackupTask], +) -> Mapping[str, BackupInfo]: backup_data: dict[str, BackupInfo] = {} for task in backup_tasks: LOGGER.info("%s", task) @@ -587,6 +613,7 @@ def date_to_utc(naive_string: str, tz: str) -> str: "type": vm["type"], "status": vm["status"], "name": vm["name"], + "uptime": vm["uptime"], } ) if vm["type"] != "qemu": @@ -597,6 +624,14 @@ def date_to_utc(naive_string: str, tz: str) -> str: "max_disk": vm["maxdisk"], } ) + with SectionWriter("proxmox_ve_disk_throughput") as writer: + writer.append_json( + { + "disk_read": vm["diskread"], + "disk_write": vm["diskwrite"], + "uptime": vm["uptime"], + } + ) with SectionWriter("proxmox_ve_mem_usage") as writer: writer.append_json( { @@ -604,6 +639,22 @@ def date_to_utc(naive_string: str, tz: str) -> str: "max_mem": vm["maxmem"], } ) + with SectionWriter("proxmox_ve_cpu_util") as writer: + writer.append_json( + { + "cpu": vm["cpu"], + "max_cpu": vm["maxcpu"], + "uptime": vm["uptime"], + } + ) + with SectionWriter("proxmox_ve_network_throughput") as writer: + writer.append_json( + { + "net_in": vm["netin"], + "net_out": vm["netout"], + "uptime": vm["uptime"], + } + ) with SectionWriter("proxmox_ve_vm_backup_status") as writer: writer.append_json( { @@ -804,7 +855,9 @@ def is_list_of_subtree_names(data: RequestStructure) -> bool: for elem in data ) - def extract_request_subtree(request_tree: RequestStructure) -> RequestStructure: + def extract_request_subtree( + request_tree: RequestStructure, + ) -> RequestStructure: """If list if given return first (and only) element return the provided data tree""" return ( request_tree