diff --git a/cmk/base/legacy_checks/agent_ibmsvc.py b/cmk/base/legacy_checks/agent_ibmsvc.py deleted file mode 100644 index 9e5b3140608..00000000000 --- a/cmk/base/legacy_checks/agent_ibmsvc.py +++ /dev/null @@ -1,24 +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 collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.config import special_agent_info - - -def agent_ibmsvc_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str]: - args = ["-u", params["user"], "-i", ",".join(params["infos"])] - if params["accept-any-hostkey"] is True: - args += ["--accept-any-hostkey"] - - args.append(ipaddress or hostname) - return args - - -special_agent_info["ibmsvc"] = agent_ibmsvc_arguments diff --git a/cmk/gui/plugins/wato/special_agents/ibmsvc.py b/cmk/gui/plugins/wato/special_agents/ibmsvc.py deleted file mode 100644 index 6f02b153013..00000000000 --- a/cmk/gui/plugins/wato/special_agents/ibmsvc.py +++ /dev/null @@ -1,103 +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.utils.rulesets.definition import RuleGroup - -from cmk.gui.i18n import _ -from cmk.gui.plugins.wato.utils import HostRulespec, rulespec_registry -from cmk.gui.valuespec import Checkbox, Dictionary, ListChoice, TextInput -from cmk.gui.wato import RulespecGroupDatasourceProgramsHardware - - -def _valuespec_special_agents_ibmsvc() -> Dictionary: - return Dictionary( - title=_("IBM SVC / V7000 storage systems"), - help=_( - "This rule set selects the ibmsvc agent instead of the normal Checkmk Agent " - "and allows monitoring of IBM SVC / V7000 storage systems by calling " - "ls* commands there over SSH. " - "Make sure you have SSH key authentication enabled for your monitoring user. " - "That means: The user your monitoring is running under on the monitoring " - "system must be able to ssh to the storage system as the user you gave below " - "without password." - ), - elements=[ - ( - "user", - TextInput( - title=_("IBM SVC / V7000 user name"), - allow_empty=True, - help=_( - "User name on the storage system. Read only permissions are sufficient." - ), - ), - ), - ( - "accept-any-hostkey", - Checkbox( - title=_("Accept any SSH Host Key"), - label=_("Accept any SSH Host Key"), - default_value=False, - help=_( - "Accepts any SSH Host Key presented by the storage device. " - "Please note: This might be a security issue because man-in-the-middle " - "attacks are not recognized! Better solution would be to add the " - "SSH Host Key of the monitored storage devices to the .ssh/known_hosts " - "file for the user your monitoring is running under (on OMD: the site user)" - ), - ), - ), - ( - "infos", - ListChoice( - title=_("Retrieve information about..."), - choices=[ - ("lshost", _("Hosts Connected")), - ("lslicense", _("Licensing Status")), - ("lsmdisk", _("MDisks")), - ("lsmdiskgrp", _("MDisksGrps")), - ("lsnode", _("IO Groups")), - ("lsnodestats", _("Node Stats")), - ("lssystem", _("System Info")), - ("lssystemstats", _("System Stats")), - ("lseventlog", _("Event Log")), - ("lsportfc", _("FC Ports")), - ("lsportsas", _("SAS Ports")), - ("lsenclosure", _("Enclosures")), - ("lsenclosurestats", _("Enclosure Stats")), - ("lsarray", _("RAID Arrays")), - ("disks", _("Physical Disks")), - ], - default_value=[ - "lshost", - "lslicense", - "lsmdisk", - "lsmdiskgrp", - "lsnode", - "lsnodestats", - "lssystem", - "lssystemstats", - "lsportfc", - "lsenclosure", - "lsenclosurestats", - "lsarray", - "disks", - ], - allow_empty=False, - ), - ), - ], - optional_keys=[], - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("ibmsvc"), - valuespec=_valuespec_special_agents_ibmsvc, - ) -) diff --git a/cmk/plugins/ibmsvc/rulesets/special_agent.py b/cmk/plugins/ibmsvc/rulesets/special_agent.py new file mode 100644 index 00000000000..722235f73a2 --- /dev/null +++ b/cmk/plugins/ibmsvc/rulesets/special_agent.py @@ -0,0 +1,162 @@ +#!/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.rulesets.v1 import Help, Label, Title +from cmk.rulesets.v1.form_specs import ( + BooleanChoice, + DefaultValue, + DictElement, + Dictionary, + MultipleChoice, + MultipleChoiceElement, + String, + validators, +) +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + migrate=_migrate, + help_text=Help( + "This rule set selects the ibmsvc agent instead of the normal Checkmk Agent " + "and allows monitoring of IBM SVC / V7000 storage systems by calling " + "ls* commands there over SSH. " + "Make sure you have SSH key authentication enabled for your monitoring user. " + "That means: The user your monitoring is running under on the monitoring " + "system must be able to ssh to the storage system as the user you gave below " + "without password." + ), + elements={ + "user": DictElement( + required=True, + parameter_form=String( + title=Title("IBM SVC / V7000 user name"), + help_text=Help( + "User name on the storage system. Read-only permissions are sufficient." + ), + ), + ), + "accept_any_hostkey": DictElement( + required=True, + parameter_form=BooleanChoice( + title=Title("Accept any SSH Host Key"), + label=Label("Accept any SSH Host Key"), + prefill=DefaultValue(False), + help_text=Help( + "Accepts any SSH Host Key presented by the storage device. " + "Please note: This might be a security issue because man-in-the-middle " + "attacks are not recognized! Better solution would be to add the " + "SSH Host Key of the monitored storage devices to the .ssh/known_hosts " + "file for the user your monitoring is running under (on OMD: the site user)" + ), + ), + ), + "infos": DictElement( + required=True, + parameter_form=MultipleChoice( + title=Title("Retrieve information about..."), + elements=[ + MultipleChoiceElement( + name="lshost", + title=Title("Hosts Connected"), + ), + MultipleChoiceElement( + name="lslicense", + title=Title("Licensing Status"), + ), + MultipleChoiceElement( + name="lsmdisk", + title=Title("MDisks"), + ), + MultipleChoiceElement( + name="lsmdiskgrp", + title=Title("MDisksGrps"), + ), + MultipleChoiceElement( + name="lsnode", + title=Title("IO Groups"), + ), + MultipleChoiceElement( + name="lsnodestats", + title=Title("Node Stats"), + ), + MultipleChoiceElement( + name="lssystem", + title=Title("System Info"), + ), + MultipleChoiceElement( + name="lssystemstats", + title=Title("System Stats"), + ), + MultipleChoiceElement( + name="lseventlog", + title=Title("Event Log"), + ), + MultipleChoiceElement( + name="lsportfc", + title=Title("FC Ports"), + ), + MultipleChoiceElement( + name="lsportsas", + title=Title("SAS Ports"), + ), + MultipleChoiceElement( + name="lsenclosure", + title=Title("Enclosures"), + ), + MultipleChoiceElement( + name="lsenclosurestats", + title=Title("Enclosure Stats"), + ), + MultipleChoiceElement( + name="lsarray", + title=Title("RAID Arrays"), + ), + MultipleChoiceElement( + name="disks", + title=Title("Physical Disks"), + ), + ], + prefill=DefaultValue( + [ + "lshost", + "lslicense", + "lsmdisk", + "lsmdiskgrp", + "lsnode", + "lsnodestats", + "lssystem", + "lssystemstats", + "lsportfc", + "lsenclosure", + "lsenclosurestats", + "lsarray", + "disks", + ] + ), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + }, + ) + + +rule_spec_special_agent_ibmsvc = SpecialAgent( + name="ibmsvc", + title=Title("IBM SVC / V7000 storage systems"), + topic=Topic.STORAGE, + parameter_form=_parameter_form, +) + + +def _migrate(value: object) -> dict[str, object]: + if not isinstance(value, dict): + raise TypeError(object) + if "accept_any_hostkey" in value: + return value + return {k: v for k, v in value.items() if k != "accept-any-hostkey"} | { + "accept_any_hostkey": value["accept-any-hostkey"] + } diff --git a/cmk/plugins/ibmsvc/server_side_calls/special_agent.py b/cmk/plugins/ibmsvc/server_side_calls/special_agent.py new file mode 100644 index 00000000000..96478c5ae1e --- /dev/null +++ b/cmk/plugins/ibmsvc/server_side_calls/special_agent.py @@ -0,0 +1,34 @@ +#!/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 collections.abc import Iterable, Sequence + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand, SpecialAgentConfig + + +class _Params(BaseModel, frozen=True): + user: str + accept_any_hostkey: bool + infos: Sequence[str] + + +def _commands_function( + params: _Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + args = ["-u", params.user, "-i", ",".join(params.infos)] + if params.accept_any_hostkey: + args += ["--accept-any-hostkey"] + args.append(host_config.primary_ip_config.address) + yield SpecialAgentCommand(command_arguments=args) + + +special_agent_ibmsvc = SpecialAgentConfig( + name="ibmsvc", + parameter_parser=_Params.model_validate, + commands_function=_commands_function, +) diff --git a/cmk/utils/password_store/hack.py b/cmk/utils/password_store/hack.py index 90f5944f09a..47f34996c52 100644 --- a/cmk/utils/password_store/hack.py +++ b/cmk/utils/password_store/hack.py @@ -60,6 +60,7 @@ "hivemanager_ng": True, "hivemanager": True, "hp_msa": True, + "ibmsvc": False, # needs no secret } diff --git a/tests/unit/checks/test_agent_ibmsvc.py b/tests/unit/checks/test_agent_ibmsvc.py deleted file mode 100644 index ce6945ad9dd..00000000000 --- a/tests/unit/checks/test_agent_ibmsvc.py +++ /dev/null @@ -1,85 +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 collections.abc import Mapping - -import pytest - -from cmk.base.server_side_calls import SpecialAgentInfoFunctionResult - -from .checktestlib import SpecialAgent - -pytestmark = pytest.mark.checks - - -@pytest.mark.parametrize( - "params,expected_args", - [ - ( - { - "infos": [ - "lshost", - "lslicense", - "lsmdisk", - "lsmdiskgrp", - "lsnode", - "lsnodestats", - "lssystem", - "lssystemstats", - "lsportfc", - "lsenclosure", - "lsenclosurestats", - "lsarray", - "disks", - ], - "user": "user", - "accept-any-hostkey": True, - }, - [ - "-u", - "user", - "-i", - "lshost,lslicense,lsmdisk,lsmdiskgrp,lsnode,lsnodestats,lssystem,lssystemstats,lsportfc,lsenclosure,lsenclosurestats,lsarray,disks", - "--accept-any-hostkey", - "address", - ], - ), - ( - { - "infos": [ - "lshost", - "lslicense", - "lsmdisk", - "lsmdiskgrp", - "lsnode", - "lsnodestats", - "lssystem", - "lssystemstats", - "lsportfc", - "lsenclosure", - "lsenclosurestats", - "lsarray", - "disks", - ], - "user": "user", - "accept-any-hostkey": False, - }, - [ - "-u", - "user", - "-i", - "lshost,lslicense,lsmdisk,lsmdiskgrp,lsnode,lsnodestats,lssystem,lssystemstats,lsportfc,lsenclosure,lsenclosurestats,lsarray,disks", - "address", - ], - ), - ], -) -def test_ibmsvc_argument_parsing( - params: Mapping[str, object], expected_args: SpecialAgentInfoFunctionResult -) -> None: - """Tests if all required arguments are present.""" - agent = SpecialAgent("agent_ibmsvc") - arguments = agent.argument_func(params, "host", "address") - assert arguments == expected_args diff --git a/tests/unit/cmk/plugins/ibmsvc/__init__.py b/tests/unit/cmk/plugins/ibmsvc/__init__.py new file mode 100644 index 00000000000..c42b91132bf --- /dev/null +++ b/tests/unit/cmk/plugins/ibmsvc/__init__.py @@ -0,0 +1,4 @@ +#!/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. diff --git a/tests/unit/cmk/plugins/ibmsvc/server_side_calls/__init__.py b/tests/unit/cmk/plugins/ibmsvc/server_side_calls/__init__.py new file mode 100644 index 00000000000..c42b91132bf --- /dev/null +++ b/tests/unit/cmk/plugins/ibmsvc/server_side_calls/__init__.py @@ -0,0 +1,4 @@ +#!/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. diff --git a/tests/unit/cmk/plugins/ibmsvc/server_side_calls/test_special_agent.py b/tests/unit/cmk/plugins/ibmsvc/server_side_calls/test_special_agent.py new file mode 100644 index 00000000000..e722c584a13 --- /dev/null +++ b/tests/unit/cmk/plugins/ibmsvc/server_side_calls/test_special_agent.py @@ -0,0 +1,82 @@ +#!/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 collections.abc import Mapping + +import pytest + +from cmk.plugins.ibmsvc.server_side_calls.special_agent import special_agent_ibmsvc +from cmk.server_side_calls.v1 import HostConfig, IPv4Config, SpecialAgentCommand + + +@pytest.mark.parametrize( + ["raw_params", "host_config", "expected_result"], + [ + pytest.param( + { + "user": "user", + "accept_any_hostkey": False, + "infos": [ + "lshost", + "lslicense", + "lsmdisk", + ], + }, + HostConfig( + name="hostname", + ipv4_config=IPv4Config(address="1.2.3.4"), + ), + SpecialAgentCommand( + command_arguments=[ + "-u", + "user", + "-i", + "lshost,lslicense,lsmdisk", + "1.2.3.4", + ] + ), + id="do not accept any host key", + ), + pytest.param( + { + "user": "user", + "accept_any_hostkey": True, + "infos": [ + "lssystemstats", + "lsportfc", + "lsenclosure", + "lsenclosurestats", + "lsarray", + ], + }, + HostConfig( + name="hostname", + ipv4_config=IPv4Config(address="1.2.3.4"), + ), + SpecialAgentCommand( + command_arguments=[ + "-u", + "user", + "-i", + "lssystemstats,lsportfc,lsenclosure,lsenclosurestats,lsarray", + "--accept-any-hostkey", + "1.2.3.4", + ] + ), + id="accept any host key", + ), + ], +) +def test_command_creation( + raw_params: Mapping[str, object], + host_config: HostConfig, + expected_result: SpecialAgentCommand, +) -> None: + assert list( + special_agent_ibmsvc( + raw_params, + host_config, + ) + ) == [expected_result] diff --git a/tests/unit/cmk/plugins_consistency/test_special_agent_args.py b/tests/unit/cmk/plugins_consistency/test_special_agent_args.py index 5a8ebcc3469..d605c24c2ac 100644 --- a/tests/unit/cmk/plugins_consistency/test_special_agent_args.py +++ b/tests/unit/cmk/plugins_consistency/test_special_agent_args.py @@ -103,7 +103,6 @@ } UNMIGRATED = { - "ibmsvc", "innovaphone", "ipmi_sensors", "jira",