diff --git a/.aspect/cli/config.yaml b/.aspect/cli/config.yaml new file mode 100644 index 00000000000..e8f9490a0d8 --- /dev/null +++ b/.aspect/cli/config.yaml @@ -0,0 +1,3 @@ +lint: + aspects: + - //packages/cmk-agent-based:linters.bzl%ruff diff --git a/.bazeliskrc b/.bazeliskrc new file mode 100644 index 00000000000..f5220d9d847 --- /dev/null +++ b/.bazeliskrc @@ -0,0 +1,2 @@ +BAZELISK_BASE_URL=https://github.com/aspect-build/aspect-cli/releases/download +USE_BAZEL_VERSION=aspect/5.10.15 diff --git a/.bazelrc b/.bazelrc index 0a53e097ceb..63bcf311688 100644 --- a/.bazelrc +++ b/.bazelrc @@ -25,11 +25,6 @@ build --flag_alias=cmk_version=//:cmk_version # valgrind-clean again, which is a crucial feature for debugging the NEB & CMC! build --copt="-DRE2_ON_VALGRIND" -# Don't require system python for bootstrapping -# See: https://github.com/bazelbuild/rules_python/commit/f5b19dce7bc0837396ac03a425cdb9b64643cf61 -# TODO: should be dropped as soon as this becomes the default -build --@rules_python//python/config_settings:bootstrap_impl=script - clean --async # all bazel-created temporary and build output files # clean --expunge @@ -53,6 +48,13 @@ common:ci --@//:filesystem_layout=FILESYSTEM_LAYOUT_INVALID ## For specific commands # build:ci ... +# Don't require system python for bootstrapping +# See: https://github.com/bazelbuild/rules_python/commit/f5b19dce7bc0837396ac03a425cdb9b64643cf61 +# TODO: should be dropped as soon as this becomes the default +# TODO: this should be the overall default, see discussions in +# https://tribe29.slack.com/archives/C03PW9280U9/p1728303949973099 +build:ci --@rules_python//python/config_settings:bootstrap_impl=script + # clean:ci ... # run:ci ... # test:ci ... diff --git a/.clangd b/.clangd new file mode 100644 index 00000000000..fa8caec073e --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +Diagnostics: + UnusedIncludes: None + MissingIncludes: None diff --git a/.gitignore b/.gitignore index 8069a3be0f8..103b58a485c 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ tests/.hypothesis/ /buildscripts/docker_image_aliases/docker-image-alias-resolve-error.txt /bazel-* /bazel_log* +bazel-memory.profile user.bazelrc # Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode diff --git a/.gitmodules b/.gitmodules index da9592bbf93..caea9396c18 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,4 @@ path = tests/qa-test-data url = ../qa-test-data branch = master + ignore = all diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 517c16661d4..999aa5c7225 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,7 @@ repos: rev: 'v0.4.4' hooks: - id: ruff + - id: ruff-format - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: @@ -58,16 +59,6 @@ repos: language: script entry: scripts/run-autoflake types: [file, python] - - id: format - name: Run format - entry: scripts/run-format - language: script - types: [file, python] - - id: sort - name: Run sort imports - entry: scripts/run-sort - language: script - types: [file, python] - id: bandit name: Run bandit # -l level low -ll = level medium -lll level high diff --git a/.werks/10848 b/.werks/10848 index ca0eb8437b8..4c3bf0e8b4e 100644 --- a/.werks/10848 +++ b/.werks/10848 @@ -8,11 +8,12 @@ Knowledge: undoc Level: 1 Version: 2.0.0i1 -An configuration directory for mk_oracle has been added. mk_oracle -usually reads mk_oracle.cfg. Now it also reads all files with *.cfg from -$MK_CONFDIR/mk_oracle.d This feauture is needed for setups with bakery and +A configuration directory for mk_oracle has been added. mk_oracle +usually reads mk_oracle.cfg. Now, it also reads all files with *.cfg from +$MK_CONFDIR/mk_oracle.d. This feauture is needed for setups with bakery and local changes on the database server. It is possible to configure through -the bakery and add custom SQLs in configuration directory. +the bakery and add custom SQLs in configuration directory mk_oracle.d. -All variables in files from mk_oracle.d will oerwrite possible entries from -mk_oracle.cfg. +All variables defined in files from the mk_oracle.d directory will overwrite entries with the same name from +mk_oracle.cfg. Further, all variables defined in *.cfg files within the mk_oracle.d, must be unique, otherwise the last +read file wins. diff --git a/.werks/14237.md b/.werks/14237.md new file mode 100644 index 00000000000..825aa8cabe7 --- /dev/null +++ b/.werks/14237.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# Fixed performance problems for various command line operations + +key | value +---------- | --- +date | 2024-09-27T10:40:03+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +With larger setups (>10000 hosts), loading the host configuration took considerably longer ( **O(n^2)** ) than normal. +The ‘Parameters for this service’ page, for example, requires the complete host configuration. diff --git a/.werks/16251.md b/.werks/16251.md new file mode 100644 index 00000000000..fd2afb3d182 --- /dev/null +++ b/.werks/16251.md @@ -0,0 +1,14 @@ +[//]: # (werk v2) +# Update monitoring-plugins to 2.4.0 + +key | value +---------- | --- +date | 2024-09-04T14:11:06+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + + diff --git a/.werks/16254.md b/.werks/16254.md new file mode 100644 index 00000000000..0cc7cf63f7e --- /dev/null +++ b/.werks/16254.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# Add metric translations mrpe based windows checks + +key | value +---------- | --- +date | 2024-10-07T08:14:51+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + +Metrics provided by `check_ping.exe` or `check_tcp.exe` have now a metric translation and are +displayed in a correct manner. diff --git a/.werks/16255.md b/.werks/16255.md new file mode 100644 index 00000000000..f5bd0330153 --- /dev/null +++ b/.werks/16255.md @@ -0,0 +1,17 @@ +[//]: # (werk v2) +# Stop shipping check_ircd from monitoring-plugins + +key | value +---------- | --- +date | 2024-10-10T11:13:32+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + +Since the update of monitoring-plugins to 2.4.0, `check_ircd` requires the perl module `IO::Socket::IP`. +As we cannot guarantee that the required perl version is available under all distros supported by Checkmk, we decided to stop shipping the plugin. + +In case you need this plugin, you can install it manually to the local hierarchy of your site. diff --git a/.werks/16557.md b/.werks/16557.md new file mode 100644 index 00000000000..b61e15aac0d --- /dev/null +++ b/.werks/16557.md @@ -0,0 +1,19 @@ +[//]: # (werk v2) +# Distributed agent bakery: cached packages remain on remote site + +key | value +---------- | --- +date | 2024-10-02T11:56:57+00:00 +version | 2.4.0b1 +class | fix +edition | cee +component | agents +level | 1 +compatible | yes + +When using the agent bakery and (automatically) downloading agent packages from a remote site, +the remote site caches the provided packages until they are invalidated by the central site. +This happens automatically on every call from the agent updater. + +This mechanism recently failed to delete unneeded cached packages from the remote site, leading +to an increased disk usage. diff --git a/.werks/16567.md b/.werks/16567.md new file mode 100644 index 00000000000..91cb2b78936 --- /dev/null +++ b/.werks/16567.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# Re-add missing "History action type" filter + +key | value +---------- | --- +date | 2024-10-02T08:34:26+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | ec +level | 1 +compatible | yes + +The "History action type" filter has been added back to the "Recent event +history" view. It was accidentally removed during the development of 2.3. diff --git a/.werks/16778.md b/.werks/16778.md new file mode 100644 index 00000000000..d7b2df9a9b3 --- /dev/null +++ b/.werks/16778.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# fortisandbox plugin: expand monitored models + +key | value +---------- | --- +date | 2024-09-26T11:57:53+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + +Previously, the fortisandbox plugins discovered and monitored only the Fortinet _fsa3000E_ devices. +With this change, the plugin monitors all available models discoverable under the oid _1.3.6.1.4.1.12356.118.1._. diff --git a/.werks/16895.md b/.werks/16895.md new file mode 100644 index 00000000000..f2cfe41e216 --- /dev/null +++ b/.werks/16895.md @@ -0,0 +1,20 @@ +[//]: # (werk v2) +# omd: curl wrapper not used for all supported versions of SLES and EL + +key | value +---------- | --- +compatible | yes +version | 2.4.0b1 +date | 2024-09-17T15:13:20+00:00 +level | 1 +class | fix +component | omd +edition | cre + +Some OMD makefile rules have to be (de-)activated for certain versions of SLES or EL +(Enterprise Linux), but would not respect all affected versions due to the redundant +implementation of the check. This led to {{curl}} not being wrapped as needed for SLES15-SP3. + +This change makes use of string prefixes rather than explicit listing of all supported +versions of e.g. SLES15[-sp*], which fixes the mentioned issue and also takes care of +future releases of SLES15 or EL based distros. \ No newline at end of file diff --git a/.werks/16897.md b/.werks/16897.md new file mode 100644 index 00000000000..d9c6802b579 --- /dev/null +++ b/.werks/16897.md @@ -0,0 +1,19 @@ +[//]: # (werk v2) +# chrony: wrong handling of 'n/a' values for 'Ref time (UTC)' and 'Stratum' + +key | value +---------- | --- +date | 2024-09-25T11:16:41+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +A chrony status without a valid server also contains invalid values for 'Stratum' and 'Ref time', +resulting in a 'Time since last sync' of 54 years 256 days being reported (which is the difference +to epoc := 1.1.1970). + +This change just skips reporting 'Stratum' and 'Time since last sync' if we don't have a valid +server (address). diff --git a/.werks/16898.md b/.werks/16898.md new file mode 100644 index 00000000000..dffe6aaa0d5 --- /dev/null +++ b/.werks/16898.md @@ -0,0 +1,16 @@ +[//]: # (werk v2) +# active_checks:httpv2: support macros in 'user_agent' field + +key | value +---------- | --- +date | 2024-10-08T11:32:55+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + +While the `endpoint.url` element in httpv2 active check configuration support macro replacement, +`user_agent` doesn't. +This change adds support for macro replacement also for the `user_agent` field. diff --git a/.werks/17036.md b/.werks/17036.md deleted file mode 100644 index d193e06587b..00000000000 --- a/.werks/17036.md +++ /dev/null @@ -1,17 +0,0 @@ -[//]: # (werk v2) -# heartbeat_crm: Handle cases when pacemaker service is not running - -key | value ----------- | --- -date | 2024-09-16T21:35:09+00:00 -version | 2.4.0b1 -class | fix -edition | cre -component | checks -level | 1 -compatible | yes - -The creation of the agent section depended on the pacemaker service being running. If this was not the case, the section was left empty, causing the services to become stale. -From now on, if the pacemaker service is not running, the service will go into CRIT state and the summary will indicate that the connection was not possible/refused. - -Also, the agent now checks for the existence of 'crm_mon' on the system, as this is a prerequisite for further command execution. diff --git a/.werks/17038.md b/.werks/17038.md new file mode 100644 index 00000000000..0cd33ae4c84 --- /dev/null +++ b/.werks/17038.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# emka_modules: Fix parsing error + +key | value +---------- | --- +date | 2024-09-29T23:11:58+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +When upgrading from 2.2 to 2.3, a parsing error caused services related to the 'emka_modules' check plugin to receive no data and go to 'UNKN'. +This has now been fixed and the check plugin will behave as it did in 2.2. diff --git a/.werks/17039.md b/.werks/17039.md new file mode 100644 index 00000000000..489df193182 --- /dev/null +++ b/.werks/17039.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# db2_sort_overflow: Fix typo in service summary + +key | value +---------- | --- +date | 2024-10-06T17:19:11+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +There was a typo in the summary. When the state was WARN or CRIT, the summary said "leves at" instead of "levels at". +This is now fixed. diff --git a/.werks/17088.md b/.werks/17088.md new file mode 100644 index 00000000000..2d14089f6a1 --- /dev/null +++ b/.werks/17088.md @@ -0,0 +1,18 @@ +[//]: # (werk v2) +# mk_logwatch: Remove colored output support in debug mode + +key | value +---------- | --- +date | 2024-09-23T08:58:40+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + +Until now the debug mode ("-d" flag) would color the lines of the mk_logwatch output depending on their log level. This causes problems when processing the output, leading to the e.g. `maxcontextlines` setting no longer being effective. +To improve the stability of the agent plugin, its output will no longer be colored. +If you need the output to be colored, you can do so via e.g. + + mk_logwatch.py -d | sed -e 's/^C .*/\x1b[1;31m&\x1b[0m/' -e 's/^W .*/\x1b[1;33m&\x1b[0m/' -e 's/^O .*/\x1b[1;32m&\x1b[0m/' -e 's/^I .*/\x1b[1;34m&\x1b[0m/' diff --git a/.werks/17095.md b/.werks/17095.md new file mode 100644 index 00000000000..9d8902aa303 --- /dev/null +++ b/.werks/17095.md @@ -0,0 +1,50 @@ +[//]: # (werk v2) +# Sanitize Host and Folder Credentials in Audit Log + +key | value +---------- | --- +date | 2024-10-07T05:57:04+00:00 +version | 2.4.0b1 +class | security +edition | cre +component | wato +level | 1 +compatible | no + +Before this Werk, adding, changing, or removing SNMP and IMPI credentials in a host or folder's properties would log those credentials in the WATO audit log. Now, credentials are masked before being written to the log. + +The affected logs, both via the rendering functionality in WATO as well as the files on the file system, are only accessible to authenticated users. + +This issue was found during internal review. + +*Affected Versions*: + +* 2.3.0 +* 2.2.0 +* 2.1.0 +* 2.0.0 (EOL) + +*Recommendations*: + +We have marked this Werk incompatible because we recommend taking manual action: + +Consider rotating affected credentials. +If that is not feasible, consider sanitizing the log files. +Also take into account that log files containing credentials might have been written to backups. + +The affected log files can be found in `~/var/check_mk/wato/log`. + +Note that, before Checkmk 2.3.0p18, entries in the files were not separated by newlines but by null bytes. +So they would appear as one long line. +Entries that might contain credentials are all entries where the `'action'` is `'edit-folder'` or `'edit-host'`, and the `'diff_text'` contains any of the following strings: + + * `Attribute "snmp_community"` + * `Value of "snmp_community"` + * `Attribute "management_snmp_community"` + * `Value of "management_snmp_community"` + * `Attribute "management_ipmi_credentials"` + * `Value of "management_ipmi_credentials"` + +*Vulnerability Management*: + +We have rated the issue with a CVSS Score of 5.1 Medium (`CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:N`) and assigned `CVE-2024-38862`. diff --git a/.werks/17096.md b/.werks/17096.md new file mode 100644 index 00000000000..476fd2d3563 --- /dev/null +++ b/.werks/17096.md @@ -0,0 +1,35 @@ +[//]: # (werk v2) +# CSRF token leaked in URL parameters (CVE-2024-38863) + +key | value +---------- | --- +date | 2024-10-07T05:48:40+00:00 +version | 2.4.0b1 +class | security +edition | cre +component | wato +level | 1 +compatible | yes + +Before this Werk, the CSRF token was mistakenly included as a query parameter in certain URLs when navigating Checkmk, which could result in the token being saved in bookmarks. +This increased the risk of unintentional exposure, such as when sharing bookmarks with other users. +The issue has been resolved. + +While storing or unintentionally exposing the token doesn't present an immediate security threat, it could potentially enable phishing attacks targeting the specific user for the duration of the token's validity. +In Checkmk, CSRF tokens remain valid for the session's duration (configured under Global settings > Session management). + +This issue was found during internal review. + +*Affected Versions*: + +* 2.3.0 +* 2.2.0 +* 2.1.0 + +*Mitigations*: + +Avoid sharing or exposing URLs that contain the query parameter `csrf_token=`. + +*Vulnerability Management*: + +We have rated the issue with a CVSS Score of 2.0 Low (`CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:L/VI:N/VA:N/SC:L/SI:L/SA:L`) and assigned `CVE-2024-38863`. diff --git a/.werks/17124.md b/.werks/17124.md new file mode 100644 index 00000000000..a33934a1b6e --- /dev/null +++ b/.werks/17124.md @@ -0,0 +1,17 @@ +[//]: # (werk v2) +# mk_postgres: Fix 'Argument list too long' + +key | value +---------- | --- +date | 2024-07-04T07:22:11+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +The execution of large queries might run into an OS specific restriction +regarding the length of arguments. In order to bypass the above error we use +`psql -f ` instead of using `echo`, `cat` or similar for passing the +SQL to `pyql`. diff --git a/.werks/17135.md b/.werks/17135.md new file mode 100644 index 00000000000..996cde55eaf --- /dev/null +++ b/.werks/17135.md @@ -0,0 +1,22 @@ +[//]: # (werk v2) +# HW/SW Inventory update: Do not archive remote tree if only retention intervals have changed + +key | value +---------- | --- +date | 2024-09-27T09:53:35+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | inv +level | 1 +compatible | yes + +If retention intervals are configured for remote trees then these trees are updated with new +timestamps for the relevant fields. The inventory updater gets the zipped inventory data and +archives the received trees if the timestamps of these trees themselves differ from the timestamps +of the current trees although there are no contentual differences. This leads to superflous archived +trees. +Now the zipped inventory data contain information whether the tree has to be archived or not. + +Note: The central and remote site has to be at least of this version in order to make this work +properly. diff --git a/.werks/17194.md b/.werks/17194.md new file mode 100644 index 00000000000..764a8555e44 --- /dev/null +++ b/.werks/17194.md @@ -0,0 +1,28 @@ +[//]: # (werk v2) +# Disallow ancient 'check_parameters' variable in .mk files + +key | value +---------- | --- +date | 2024-09-23T21:28:13+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + +This only affects users that use the ancient `check_parameters` variable in custom '.mk' files to configure services. + +This variable is not recognized anymore. +Affected users will see the message + +`Cannot read in configuration file : name 'check_parameters' is not defined` + +during `cmk-update-config`. + +This situation is detected before the actual update is started, leaving the site unchanged. + +If you are affected, please remove all references to that variable from your '.mk' files. +Use the rulesets found in the _Setup_ menu _"Service monitoring rules"_ to configure check plugins. + + diff --git a/.werks/17195.md b/.werks/17195.md new file mode 100644 index 00000000000..ffed01ebcde --- /dev/null +++ b/.werks/17195.md @@ -0,0 +1,29 @@ +[//]: # (werk v2) +# Combined clustering of discovered and enforced services + +key | value +---------- | --- +date | 2024-09-24T13:17:51+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + +This only affects users that have clustered services that are enforced on some of the clusters nodes, and discovered on others. + +If this affects you, we strongly recommend you change your configuration to enforce the services on all nodes (or none of them). + +### Previous behavior +In the case where a service was enforced on some nodes and discovered on others, the type of the resulting service on the cluster was determined by which service occured _last_ in the list of the nodes. +In case a discovered service was encountered last, the service on the node would have been a discovered one, being run with whichever parameters where configured on the _cluster_. +In case an enforced service was encountered last, the service would appear as enforced service on the cluster, being checked with the parameters as configured in the _"Enforces services"_ ruleset. + +### New behavior +We now changed the logic, such that enforced services always win, regardless of the order they are encountered in. +This is in line with the behavior on an individual node where an enforced services always overrides a discovered one. + +The parameters that are used for checking are derived by merging all encountered enforced services parameters, where the nodes precedence is defined by their order in the clusters definition. This again is in line with how Checkmk behaves in other situations when merging parameters. + +However, to repeat: **We strongly recommend to always configure the exact same enforced services on all nodes, in case they are clustered**, to avoid any confusion. diff --git a/.werks/17196.md b/.werks/17196.md new file mode 100644 index 00000000000..19f40fa95db --- /dev/null +++ b/.werks/17196.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# Crash in during HW/SW inventory on Windows + +key | value +---------- | --- +date | 2024-10-08T19:44:30+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +This fixes a crash in case software package names contained a pipe character (`|`). +Affected users need to redeploy the Checkmk agent. diff --git a/.werks/17197.md b/.werks/17197.md new file mode 100644 index 00000000000..65fc35677a0 --- /dev/null +++ b/.werks/17197.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# esx_vsphere_vm_snapshot: Correctly compute creation time + +key | value +---------- | --- +date | 2024-10-09T10:07:31+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +The creation time of snapshots has been computed incorrectly. +The time stamp (like `2024-10-09T12:10:00.123456Z`) has been treated as local time, while in fact refering to UTC. diff --git a/.werks/17207.md b/.werks/17207.md index e80637cd6a5..c46b358c681 100644 --- a/.werks/17207.md +++ b/.werks/17207.md @@ -18,4 +18,5 @@ but without the hanging. Here is a recapitulation of what this Werk does: If a user runs `omd update`, then the output is written to both `$OMD_ROOT/var/log/update.log` and stdout. However, the output of site configuration verification - Werk #16408 was missing. This has been fixed. + Werk #16408 was missing in the `update.log`. +This has been fixed. diff --git a/.werks/17209.md b/.werks/17209.md new file mode 100644 index 00000000000..488bd515036 --- /dev/null +++ b/.werks/17209.md @@ -0,0 +1,21 @@ +[//]: # (werk v2) +# if64: Use Uptime instead of Check Time + +key | value +---------- | --- +date | 2024-09-23T08:36:11+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 2 +compatible | yes + +The check plugin `if64` monitors network interfaces via SNMP. +The plugin reports a number of rates, e.g. `Input octets` and `Output packets`. +In the past, these rates were computed by using the time the check function is being run. +However, the SNMP output is always older, and the check time does not accurately reflect the age of the counters inside the SNMP output. +These inaccuracies were especially noticeable for clustered services. +With this Werk, the rates are based on `sysUpTime`, i.e., the time since the network management portion of the system was last re-initialized. +If the system is re-intialized, or `sysUpTime` overflows, no rates are reported, but the state remains OK. +The check will report 'time anomaly detected'. diff --git a/.werks/17210.md b/.werks/17210.md new file mode 100644 index 00000000000..f55a8d64a39 --- /dev/null +++ b/.werks/17210.md @@ -0,0 +1,17 @@ +[//]: # (werk v2) +# smart: Allow Usage with POSIX Shell + +key | value +---------- | --- +date | 2024-10-08T14:13:08+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + +In the past, the agent plugin `smart` specified `/bin/bash` as an interpreter directive. +bash is not available on FreeBSD. +With this Werk, the interpreter is changed to `/bin/sh`. +Moreover, the syntax within the plugin was adopted to be POSIX compliant. diff --git a/.werks/17244.md b/.werks/17244.md new file mode 100644 index 00000000000..58d4be5a238 --- /dev/null +++ b/.werks/17244.md @@ -0,0 +1,26 @@ +[//]: # (werk v2) +# Gerrit: monitor version of deployed instance + +key | value +---------- | --- +date | 2024-09-19T14:45:40+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | checks +level | 1 +compatible | yes + +This check compares a currently deployed Gerrit instance with newer available releases. + +Since Gerrit uses a release cycle similar to semantic versioning [1], this check can monitor when +a major, minor, or patch release is available. With the service configuration, a user can specify +the specific type of release(s) they would like to be notified about. + +For example, an administrator may only want to be notified when there is a new patch release, but +isn't concerned about major or minor releases. + +[1] **Be aware**: we detected breaking changes in minor and patch releases. Therefore, don't assume +that Gerrit is 100% compliant with semantic versioning. So always check the respective release notes +(linked beside each new version) before upgrading Gerrit. For more information on semantic +versioning, check out: [https://semver.org](https://semver.org). diff --git a/.werks/17257.md b/.werks/17257.md new file mode 100644 index 00000000000..48adcd1c2ee --- /dev/null +++ b/.werks/17257.md @@ -0,0 +1,26 @@ +[//]: # (werk v2) +# postfix_mailq: Fix service reporting missing item after upgrade + +key | value +---------- | --- +date | 2024-09-18T11:36:57+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + +In Werk #16377 we renamed the postfix_mailq services in the case where +only a single such service existed. There was a bug which occured in +combination with various linux agents where the service would show up as +UNKNOWN after applying an update, even after rediscovering. + +With this werk, the postfix_mailq service will no longer show up as +UNKNOWN. + +**Incompatibility** + +In various linux agents, the postfix_mailq service will report state +UNKNOWN saying "Item not found in monitoring data" after upgrading. If +that is the case in your environment, simply rediscover the services. diff --git a/.werks/17258.md b/.werks/17258.md new file mode 100644 index 00000000000..1263153d0bd --- /dev/null +++ b/.werks/17258.md @@ -0,0 +1,18 @@ +[//]: # (werk v2) +# Fix host renaming failing when host is node of cluster + +key | value +---------- | --- +compatible | yes +version | 2.4.0b1 +date | 2024-09-19T14:33:30+00:00 +level | 1 +class | fix +component | wato +edition | cre + +There was a bug when renaming a host which is a node of a cluster and inside a +folder. The cluster would show the new name but the host itself would keep its +old name. + +With this werk, hosts are now properly renamed as expected. \ No newline at end of file diff --git a/.werks/17259.md b/.werks/17259.md new file mode 100644 index 00000000000..1c3ed9e4030 --- /dev/null +++ b/.werks/17259.md @@ -0,0 +1,30 @@ +[//]: # (werk v2) +# Fix mismatching network interface and switch port services + +key | value +---------- | --- +date | 2024-09-25T14:37:14+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | no + + +When configuring network interfaces to be discovered by alias or +description (rule "Network interface and switch port discovery"), there +was a chance of a mismatch between the discovered service item and the +interface checked by the service. + +This happened if the alias or description of one interface matched the +index of another interface. For example, if the interface discovery is +configured to discover interfaces by alias, then the service "Interface +5" is supposed to check the interface with the alias "5". Instead, it +checked the interface with the index 5. + +**Compatibility Hint** + +To apply the fix, you need to remove the interface services and +rediscover them. If you do not remove and rediscover them, the fix will +not be applied and you might still have mismatched services. diff --git a/.werks/17276.md b/.werks/17276.md new file mode 100644 index 00000000000..5768abeeffd --- /dev/null +++ b/.werks/17276.md @@ -0,0 +1,14 @@ +[//]: # (werk v2) +# NagVis: Updated to 1.9.44 + +key | value +---------- | --- +date | 2024-09-30T11:43:15+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | packages +level | 1 +compatible | yes + + diff --git a/.werks/17306.md b/.werks/17306.md new file mode 100644 index 00000000000..523920d7667 --- /dev/null +++ b/.werks/17306.md @@ -0,0 +1,15 @@ +[//]: # (werk v2) +# Render large numbers with thin space as thousands separator in decimal notation + +key | value +---------- | --- +date | 2024-09-25T06:15:18+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | multisite +level | 1 +compatible | yes + +As of this werk, in decimal notation, metric values that are rendered using the thin space as +thousand separator. For example, "10673.1 Hz" is now rendered as "10 673.1 Hz". diff --git a/.werks/17307.md b/.werks/17307.md new file mode 100644 index 00000000000..1a104bd5f4d --- /dev/null +++ b/.werks/17307.md @@ -0,0 +1,19 @@ +[//]: # (werk v2) +# Do not separate numerical value and unit symbol by space if unit symbol starts with "/" + +key | value +---------- | --- +date | 2024-09-25T17:51:13+00:00 +version | 2.4.0b1 +class | feature +edition | cre +component | multisite +level | 1 +compatible | yes + +When rendering metric values, Checkmk separates the numerical value and the unit symbol by a space, +for example "12 s" or "4.67 KiB". As of this werk, in the special case where the unit symbol starts +with a slash, the separating space is avoided: "12/s" instead of "12 /s". + +Note that the separator continues to be inserted in case the metric is rendered for example in SI +notation with a prefix: "5.6 M/s" (and not "5.6M/s"). diff --git a/.werks/17308.md b/.werks/17308.md new file mode 100644 index 00000000000..a09d4e2e405 --- /dev/null +++ b/.werks/17308.md @@ -0,0 +1,16 @@ +[//]: # (werk v2) +# mem_win: Interpret configured averaging horizon correctly + +key | value +---------- | --- +date | 2024-10-08T14:40:43+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +The memory check for Windows systems misinterpreted the configured averaging horizon (if any). Both +the actual value used for computing the averages and the value displayed in the service output were +too large by a factor of 60. diff --git a/.werks/17311.md b/.werks/17311.md new file mode 100644 index 00000000000..8e7c6ca603b --- /dev/null +++ b/.werks/17311.md @@ -0,0 +1,17 @@ +[//]: # (werk v2) +# mk_logwatch: Apply context to informational (OK) messages + +key | value +---------- | --- +date | 2024-10-02T12:21:15+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +With the `maxcontextlines` option the output of the mk_logwatch agent plugin can be reduced to a certain number of lines before and after relevant messages. +Previously the messages were seen as relevant if they had the level `W`(warning) or `C`(critical). +With this werk messages that are marked with `O` (OK/informational) are also considered relevant and will have the context applied. + diff --git a/.werks/17330.md b/.werks/17330.md new file mode 100644 index 00000000000..bf82f7837e4 --- /dev/null +++ b/.werks/17330.md @@ -0,0 +1,22 @@ +[//]: # (werk v2) +# Fix comment selection affecting comments across multiple sites + +key | value +---------- | --- +date | 2024-10-01T06:11:33+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | multisite +level | 1 +compatible | yes + +When selecting comments in a view with comments from multiple sites, +rows were selected by comment id regardless of which site they were +from. This led to cases where trying to delete a single comment with +comment id `1` from one site led to all comments with the comment id `1` +being deleted from all sites. + +With this werk, comment selection in view is site and id dependent, +allowing the user to delete single comments even if they share an id +with a comment on a different site. diff --git a/.werks/17331.md b/.werks/17331.md new file mode 100644 index 00000000000..841ad27ee4b --- /dev/null +++ b/.werks/17331.md @@ -0,0 +1,24 @@ +[//]: # (werk v2) +# azure: Fix app registration crashing while parsing agent output + +key | value +---------- | --- +date | 2024-10-01T11:37:14+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +When using a `|` symbol in the display name of an azure app, the +azure_app_registration check would fail with +`WARNING: Parsing of section azure_app_registration failed - please submit a crash report!`. + +With this werk, we fix this error and support the `|` symbol in the +display name of azure apps. + +**User action required** + +To apply the fix, you need to rediscover the `azure_app_registration` +services. diff --git a/.werks/17355.md b/.werks/17355.md new file mode 100644 index 00000000000..08f81b17c22 --- /dev/null +++ b/.werks/17355.md @@ -0,0 +1,22 @@ +[//]: # (werk v2) +# raritan_pdu_plugs.py: respect user defined parameters + +key | value +---------- | --- +date | 2024-10-09T14:49:53+00:00 +version | 2.4.0b1 +class | fix +edition | cre +component | checks +level | 1 +compatible | yes + +Currently, the check disregards the custom parameters set by the user, always returning the state +defined by the SNMP mapping. With this change, the service now compares the current state with the +required state defined by the user in the check parameters. If there is a mismatch, a "CRIT" result +will be yielded, comparing the actual and expected plug state. Otherwise, an "OK" result will be +yielded with the plug state. + +Note: if these parameters are not explicitly set for your service, the service will compare the +current state with the state set during service discovery. If you do have configured parameters, +there are no changes needed for this fix. diff --git a/.werks/first_free b/.werks/first_free index ede2d40793b..1338993ab85 100644 --- a/.werks/first_free +++ b/.werks/first_free @@ -1 +1 @@ -17320 +17360 diff --git a/BUILD b/BUILD index f0483af854c..61dcb9ef436 100644 --- a/BUILD +++ b/BUILD @@ -1,9 +1,12 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") +load("@repo_license//:license.bzl", "REPO_LICENSE") exports_files([ "Pipfile", "Pipfile.lock", + "pyproject.toml", + "requirements_lock.txt", ]) string_flag( @@ -33,6 +36,23 @@ config_setting( flag_values = {":filesystem_layout": "fhs"}, ) +string_flag( + name = "repo_license", + build_setting_default = REPO_LICENSE, + visibility = ["//visibility:public"], +) + +config_setting( + name = "gpl_repo", + flag_values = {":repo_license": "gpl"}, +) + +config_setting( + # We really mean the license here, editions are handled differently! + name = "gpl+enterprise_repo", + flag_values = {":repo_license": "gpl+enterprise"}, +) + # Generate `compile_commands.json` with `bazel run //:refresh_compile_commands`. refresh_compile_commands( name = "refresh_compile_commands", @@ -46,3 +66,8 @@ refresh_compile_commands( "//packages/unixcat:all": "", }, ) + +alias( + name = "requirements.update", + actual = "//cmk:requirements.update", +) diff --git a/MODULE.bazel b/MODULE.bazel index 52570b1c9c3..8fbd3ad0394 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,3 +1,6 @@ +repo_license = use_repo_rule("//omd/packages/rules:repo_license.bzl", "detect_repo_license") +repo_license(name = "repo_license") + # Hedron's Compile Commands Extractor for Bazel # https://github.com/hedronvision/bazel-compile-commands-extractor bazel_dep(name = "hedron_compile_commands", dev_dependency = True) @@ -32,14 +35,14 @@ python.toolchain( ) bazel_dep(name = "aspect_rules_py", version = "0.7.4") -bazel_dep(name = "aspect_rules_lint", version = "1.0.0-rc9") +bazel_dep(name = "aspect_rules_lint", version = "1.0.2") pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") pip.parse( hub_name = "cmk_agent_based", python_version = PYTHON_VERSION, requirements_by_platform = { - "//packages/cmk-agent-based:requirements_lock.txt": "linux_*,osx_*", + "//packages/cmk-agent-based:requirements_lock.txt": "linux_*", }, ) use_repo(pip, "cmk_agent_based") @@ -47,7 +50,22 @@ pip.parse( hub_name = "cmk_werks", python_version = PYTHON_VERSION, requirements_by_platform = { - "//packages/cmk-werks:requirements_lock.txt": "linux_*,osx_*", + "//packages/cmk-werks:requirements_lock.txt": "linux_*", }, ) use_repo(pip, "cmk_werks") +pip.parse( + hub_name = "cmk_py", + python_version = PYTHON_VERSION, + requirements_by_platform = { + "@//:requirements_lock.txt": "linux_*", + }, + environment = { + # Hack for building extensions from source. + # See also: https://github.com/bazelbuild/rules_python/issues/1463 + "CC": "gcc-13" + }, +) +use_repo(pip, "cmk_py") + +bazel_dep(name = "protobuf", version = "28.2", repo_name = "com_google_protobuf") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0abc3a0d5db..df0233345a7 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,6 +1,6 @@ { "lockFileVersion": 6, - "moduleFileHash": "c4579a6c4929e06cb910dcf9ad6b9a62fa434c2167e53c04aa0ba08de99a47bd", + "moduleFileHash": "71d6306a758719af3f861180f35167ec852566fbe0df08873e1d9c381fec4b80", "flags": { "cmdRegistries": [ "https://bcr.bazel.build/" @@ -24,13 +24,43 @@ "executionPlatformsToRegister": [], "toolchainsToRegister": [], "extensionUsages": [ + { + "extensionBzlFile": "//:MODULE.bazel", + "extensionName": "_repo_rules", + "usingModule": "", + "location": { + "file": "@@//:MODULE.bazel", + "line": 0, + "column": 0 + }, + "imports": { + "repo_license": "repo_license" + }, + "devImports": [], + "tags": [ + { + "tagName": "//omd/packages/rules:repo_license.bzl%detect_repo_license", + "attributeValues": { + "name": "repo_license" + }, + "devDependency": false, + "location": { + "file": "@@//:MODULE.bazel", + "line": 2, + "column": 13 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, { "extensionBzlFile": "@rules_python//python/extensions:python.bzl", "extensionName": "python", "usingModule": "", "location": { "file": "@@//:MODULE.bazel", - "line": 27, + "line": 30, "column": 23 }, "imports": {}, @@ -45,7 +75,7 @@ "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 28, + "line": 31, "column": 17 } } @@ -59,12 +89,13 @@ "usingModule": "", "location": { "file": "@@//:MODULE.bazel", - "line": 37, + "line": 40, "column": 20 }, "imports": { "cmk_agent_based": "cmk_agent_based", - "cmk_werks": "cmk_werks" + "cmk_werks": "cmk_werks", + "cmk_py": "cmk_py" }, "devImports": [], "tags": [ @@ -74,13 +105,13 @@ "hub_name": "cmk_agent_based", "python_version": "3.12.3", "requirements_by_platform": { - "//packages/cmk-agent-based:requirements_lock.txt": "linux_*,osx_*" + "//packages/cmk-agent-based:requirements_lock.txt": "linux_*" } }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 38, + "line": 41, "column": 10 } }, @@ -90,13 +121,32 @@ "hub_name": "cmk_werks", "python_version": "3.12.3", "requirements_by_platform": { - "//packages/cmk-werks:requirements_lock.txt": "linux_*,osx_*" + "//packages/cmk-werks:requirements_lock.txt": "linux_*" } }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 46, + "line": 49, + "column": 10 + } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "cmk_py", + "python_version": "3.12.3", + "requirements_by_platform": { + "@//:requirements_lock.txt": "linux_*" + }, + "environment": { + "CC": "gcc-13" + } + }, + "devDependency": false, + "location": { + "file": "@@//:MODULE.bazel", + "line": 57, "column": 10 } } @@ -111,7 +161,8 @@ "rules_rust": "rules_rust@0.49.3", "rules_python": "rules_python@_", "aspect_rules_py": "aspect_rules_py@0.7.4", - "aspect_rules_lint": "aspect_rules_lint@1.0.0-rc9", + "aspect_rules_lint": "aspect_rules_lint@1.0.2", + "com_google_protobuf": "protobuf@28.2", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" } @@ -435,7 +486,7 @@ "rules_license": "rules_license@0.0.8", "rules_proto": "rules_proto@6.0.2", "build_bazel_apple_support": "apple_support@1.13.0", - "com_google_protobuf": "protobuf@24.4", + "com_google_protobuf": "protobuf@28.2", "aspect_rules_js": "aspect_rules_js@1.40.0", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" @@ -572,7 +623,7 @@ "rules_cc": "rules_cc@0.0.9", "platforms": "platforms@0.0.8", "rules_proto": "rules_proto@6.0.2", - "com_google_protobuf": "protobuf@24.4", + "com_google_protobuf": "protobuf@28.2", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" } @@ -672,10 +723,10 @@ } } }, - "aspect_rules_lint@1.0.0-rc9": { + "aspect_rules_lint@1.0.2": { "name": "aspect_rules_lint", - "version": "1.0.0-rc9", - "key": "aspect_rules_lint@1.0.0-rc9", + "version": "1.0.2", + "key": "aspect_rules_lint@1.0.2", "repoName": "aspect_rules_lint", "executionPlatformsToRegister": [], "toolchainsToRegister": [], @@ -683,9 +734,9 @@ { "extensionBzlFile": "@rules_multitool//multitool:extension.bzl", "extensionName": "multitool", - "usingModule": "aspect_rules_lint@1.0.0-rc9", + "usingModule": "aspect_rules_lint@1.0.2", "location": { - "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.0-rc9/MODULE.bazel", + "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/MODULE.bazel", "line": 27, "column": 26 }, @@ -701,7 +752,7 @@ }, "devDependency": false, "location": { - "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.0-rc9/MODULE.bazel", + "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/MODULE.bazel", "line": 28, "column": 14 } @@ -713,7 +764,7 @@ }, "devDependency": false, "location": { - "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.0-rc9/MODULE.bazel", + "file": "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/MODULE.bazel", "line": 29, "column": 14 } @@ -741,17 +792,314 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/aspect-build/rules_lint/releases/download/v1.0.0-rc9/rules_lint-v1.0.0-rc9.tar.gz" + "https://github.com/aspect-build/rules_lint/releases/download/v1.0.2/rules_lint-v1.0.2.tar.gz" ], - "integrity": "sha256-L23cp6Fb1mEvcNRl/Gj24UUkNrV/S2uYaTxYKPLW3/0=", - "strip_prefix": "rules_lint-1.0.0-rc9", + "integrity": "sha256-fV/u+a2F8Lp4zFdXqUePj6mcWKjKvBZg1hCykdwkLps=", + "strip_prefix": "rules_lint-1.0.2", "remote_patches": { - "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.0-rc9/patches/module_dot_bazel_version.patch": "sha256-2Dk700Mmjdlb+G0gztlklKdKYy1er9tHkxHFx83N9G4=" + "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/patches/module_dot_bazel_version.patch": "sha256-lrs3vjcMnYJiQZssc3tOoL02LOyd7AXIk+FdyxHRiOQ=" }, "remote_patch_strip": 1 } } }, + "protobuf@28.2": { + "name": "protobuf", + "version": "28.2", + "key": "protobuf@28.2", + "repoName": "com_google_protobuf", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [ + "@rust_toolchains//:all" + ], + "extensionUsages": [ + { + "extensionBzlFile": "@rules_python//python/extensions:python.bzl", + "extensionName": "python", + "usingModule": "protobuf@28.2", + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 38, + "column": 23 + }, + "imports": { + "system_python": "python_3_12" + }, + "devImports": [], + "tags": [ + { + "tagName": "toolchain", + "attributeValues": { + "is_default": false, + "python_version": "3.8" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 40, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "is_default": false, + "python_version": "3.9" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 40, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "is_default": false, + "python_version": "3.10" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 40, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "is_default": false, + "python_version": "3.11" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 40, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "is_default": true, + "python_version": "3.12" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 40, + "column": 21 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_python//python/extensions:pip.bzl", + "extensionName": "pip", + "usingModule": "protobuf@28.2", + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 47, + "column": 20 + }, + "imports": { + "pip_deps": "pip_deps" + }, + "devImports": [], + "tags": [ + { + "tagName": "parse", + "attributeValues": { + "hub_name": "pip_deps", + "python_version": "3.8", + "requirements_lock": "//python:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 49, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "pip_deps", + "python_version": "3.9", + "requirements_lock": "//python:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 49, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "pip_deps", + "python_version": "3.10", + "requirements_lock": "//python:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 49, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "pip_deps", + "python_version": "3.11", + "requirements_lock": "//python:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 49, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "pip_deps", + "python_version": "3.12", + "requirements_lock": "//python:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 49, + "column": 14 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_rust//rust:extensions.bzl", + "extensionName": "rust", + "usingModule": "protobuf@28.2", + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 58, + "column": 21 + }, + "imports": { + "rust_toolchains": "rust_toolchains" + }, + "devImports": [], + "tags": [ + { + "tagName": "toolchain", + "attributeValues": { + "edition": "2021" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 59, + "column": 15 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_rust//crate_universe:extension.bzl", + "extensionName": "crate", + "usingModule": "protobuf@28.2", + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 62, + "column": 22 + }, + "imports": { + "crate_index": "crates" + }, + "devImports": [], + "tags": [ + { + "tagName": "spec", + "attributeValues": { + "package": "googletest", + "version": ">0.0.0" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 63, + "column": 11 + } + }, + { + "tagName": "spec", + "attributeValues": { + "package": "paste", + "version": ">=1" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 67, + "column": 11 + } + }, + { + "tagName": "from_specs", + "attributeValues": {}, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel", + "line": 71, + "column": 17 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + } + ], + "deps": { + "com_google_absl": "abseil-cpp@20240116.1", + "bazel_skylib": "bazel_skylib@1.6.1", + "jsoncpp": "jsoncpp@1.9.5", + "rules_cc": "rules_cc@0.0.9", + "rules_fuzzing": "rules_fuzzing@0.5.2", + "rules_java": "rules_java@7.4.0", + "rules_jvm_external": "rules_jvm_external@5.1", + "rules_pkg": "rules_pkg@0.7.0", + "rules_python": "rules_python@_", + "rules_rust": "rules_rust@0.49.3", + "platforms": "platforms@0.0.8", + "zlib": "zlib@1.3.1", + "rules_proto": "rules_proto@6.0.2", + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/protocolbuffers/protobuf/releases/download/v28.2/protobuf-28.2.zip" + ], + "integrity": "sha256-4BBolY8Sl0eYin++Cd3nzGSXTjs1Mx7kHuKCnwlh1HI=", + "strip_prefix": "protobuf-28.2", + "remote_patches": {}, + "remote_patch_strip": 0 + } + } + }, "bazel_tools@_": { "name": "bazel_tools", "version": "", @@ -898,8 +1246,8 @@ "rules_python": "rules_python@_", "buildozer": "buildozer@6.4.0.2", "platforms": "platforms@0.0.8", - "com_google_protobuf": "protobuf@24.4", - "zlib": "zlib@1.3", + "com_google_protobuf": "protobuf@28.2", + "zlib": "zlib@1.3.1", "build_bazel_apple_support": "apple_support@1.13.0", "local_config_platform": "local_config_platform@_" } @@ -1131,109 +1479,6 @@ } } }, - "protobuf@24.4": { - "name": "protobuf", - "version": "24.4", - "key": "protobuf@24.4", - "repoName": "protobuf", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [ - { - "extensionBzlFile": "@protobuf//:non_module_deps.bzl", - "extensionName": "non_module_deps", - "usingModule": "protobuf@24.4", - "location": { - "file": "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel", - "line": 20, - "column": 32 - }, - "imports": { - "utf8_range": "utf8_range" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - }, - { - "extensionBzlFile": "@rules_jvm_external//:extensions.bzl", - "extensionName": "maven", - "usingModule": "protobuf@24.4", - "location": { - "file": "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel", - "line": 28, - "column": 22 - }, - "imports": { - "maven": "maven" - }, - "devImports": [], - "tags": [ - { - "tagName": "install", - "attributeValues": { - "name": "maven", - "artifacts": [ - "com.google.code.findbugs:jsr305:3.0.2", - "com.google.code.gson:gson:2.8.9", - "com.google.errorprone:error_prone_annotations:2.3.2", - "com.google.j2objc:j2objc-annotations:1.3", - "com.google.guava:guava:31.1-jre", - "com.google.guava:guava-testlib:31.1-jre", - "com.google.truth:truth:1.1.2", - "junit:junit:4.13.2", - "org.mockito:mockito-core:4.3.1" - ] - }, - "devDependency": false, - "location": { - "file": "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel", - "line": 30, - "column": 14 - } - } - ], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "bazel_skylib": "bazel_skylib@1.6.1", - "rules_python": "rules_python@_", - "rules_cc": "rules_cc@0.0.9", - "rules_proto": "rules_proto@6.0.2", - "rules_java": "rules_java@7.4.0", - "rules_pkg": "rules_pkg@0.7.0", - "platforms": "platforms@0.0.8", - "com_google_absl": "abseil-cpp@20230802.0.bcr.1", - "zlib": "zlib@1.3", - "upb": "upb@0.0.0-20230516-61a97ef", - "rules_jvm_external": "rules_jvm_external@5.1", - "com_google_googletest": "googletest@1.14.0", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "urls": [ - "https://github.com/protocolbuffers/protobuf/releases/download/v24.4/protobuf-24.4.tar.gz" - ], - "integrity": "sha256-YWuzU2rB//P7GhQUUPoouHXphXEhcOp/G/5eX8QeLNg=", - "strip_prefix": "protobuf-24.4", - "remote_patches": { - "https://bcr.bazel.build/modules/protobuf/24.4/patches/0001-Add-MODULE.bazel.patch": "sha256-nF6uuO4jHJpzOqJyhWhSZ8aRWznjbgrdSM50IiT0GhY=", - "https://bcr.bazel.build/modules/protobuf/24.4/patches/0002-Add-utf8_range-dependency.patch": "sha256-UPhKk5lQVa/8675JZJG/h/WTIzmQml6g/wTFJWgWnL8=", - "https://bcr.bazel.build/modules/protobuf/24.4/patches/0003-Examples-MODULE.bazel.patch": "sha256-mzBuXdk9K9RTN4PhYkoXcSXDXncPjSYjj6nVcq+dNv4=", - "https://bcr.bazel.build/modules/protobuf/24.4/patches/0004-Migrate-from-bind-to-alias.patch": "sha256-OHsXlAzbHYMAvGRlKGcxmolaoLXa86Rc5lhs84YAApg=", - "https://bcr.bazel.build/modules/protobuf/24.4/patches/0005-Make-rules_ruby-a-dev-only-dependency.patch": "sha256-k6M0C9i23kADrLUupaKQcv5sQ59LZDYp2cp3dcBPcbA=" - }, - "remote_patch_strip": 1 - } - } - }, "aspect_rules_js@1.40.0": { "name": "aspect_rules_js", "version": "1.40.0", @@ -1337,7 +1582,7 @@ ], "deps": { "aspect_bazel_lib": "aspect_bazel_lib@2.7.7", - "aspect_rules_lint": "aspect_rules_lint@1.0.0-rc9", + "aspect_rules_lint": "aspect_rules_lint@1.0.2", "bazel_features": "bazel_features@1.9.1", "bazel_skylib": "bazel_skylib@1.6.1", "rules_nodejs": "rules_nodejs@5.8.2", @@ -1630,7 +1875,7 @@ ], "deps": { "platforms": "platforms@0.0.8", - "com_google_protobuf": "protobuf@24.4", + "com_google_protobuf": "protobuf@28.2", "rules_proto": "rules_proto@6.0.2", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" @@ -1717,183 +1962,18 @@ } } }, - "rules_java@7.4.0": { - "name": "rules_java", - "version": "7.4.0", - "key": "rules_java@7.4.0", - "repoName": "rules_java", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [ - "//toolchains:all", - "@local_jdk//:runtime_toolchain_definition", - "@local_jdk//:bootstrap_runtime_toolchain_definition", - "@remotejdk11_linux_toolchain_config_repo//:all", - "@remotejdk11_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk11_linux_ppc64le_toolchain_config_repo//:all", - "@remotejdk11_linux_s390x_toolchain_config_repo//:all", - "@remotejdk11_macos_toolchain_config_repo//:all", - "@remotejdk11_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk11_win_toolchain_config_repo//:all", - "@remotejdk11_win_arm64_toolchain_config_repo//:all", - "@remotejdk17_linux_toolchain_config_repo//:all", - "@remotejdk17_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk17_linux_ppc64le_toolchain_config_repo//:all", - "@remotejdk17_linux_s390x_toolchain_config_repo//:all", - "@remotejdk17_macos_toolchain_config_repo//:all", - "@remotejdk17_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk17_win_toolchain_config_repo//:all", - "@remotejdk17_win_arm64_toolchain_config_repo//:all", - "@remotejdk21_linux_toolchain_config_repo//:all", - "@remotejdk21_linux_aarch64_toolchain_config_repo//:all", - "@remotejdk21_macos_toolchain_config_repo//:all", - "@remotejdk21_macos_aarch64_toolchain_config_repo//:all", - "@remotejdk21_win_toolchain_config_repo//:all" - ], - "extensionUsages": [ - { - "extensionBzlFile": "@rules_java//java:extensions.bzl", - "extensionName": "toolchains", - "usingModule": "rules_java@7.4.0", - "location": { - "file": "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel", - "line": 19, - "column": 27 - }, - "imports": { - "remote_java_tools": "remote_java_tools", - "remote_java_tools_linux": "remote_java_tools_linux", - "remote_java_tools_windows": "remote_java_tools_windows", - "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64", - "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64", - "local_jdk": "local_jdk", - "remotejdk11_linux_toolchain_config_repo": "remotejdk11_linux_toolchain_config_repo", - "remotejdk11_linux_aarch64_toolchain_config_repo": "remotejdk11_linux_aarch64_toolchain_config_repo", - "remotejdk11_linux_ppc64le_toolchain_config_repo": "remotejdk11_linux_ppc64le_toolchain_config_repo", - "remotejdk11_linux_s390x_toolchain_config_repo": "remotejdk11_linux_s390x_toolchain_config_repo", - "remotejdk11_macos_toolchain_config_repo": "remotejdk11_macos_toolchain_config_repo", - "remotejdk11_macos_aarch64_toolchain_config_repo": "remotejdk11_macos_aarch64_toolchain_config_repo", - "remotejdk11_win_toolchain_config_repo": "remotejdk11_win_toolchain_config_repo", - "remotejdk11_win_arm64_toolchain_config_repo": "remotejdk11_win_arm64_toolchain_config_repo", - "remotejdk17_linux_toolchain_config_repo": "remotejdk17_linux_toolchain_config_repo", - "remotejdk17_linux_aarch64_toolchain_config_repo": "remotejdk17_linux_aarch64_toolchain_config_repo", - "remotejdk17_linux_ppc64le_toolchain_config_repo": "remotejdk17_linux_ppc64le_toolchain_config_repo", - "remotejdk17_linux_s390x_toolchain_config_repo": "remotejdk17_linux_s390x_toolchain_config_repo", - "remotejdk17_macos_toolchain_config_repo": "remotejdk17_macos_toolchain_config_repo", - "remotejdk17_macos_aarch64_toolchain_config_repo": "remotejdk17_macos_aarch64_toolchain_config_repo", - "remotejdk17_win_toolchain_config_repo": "remotejdk17_win_toolchain_config_repo", - "remotejdk17_win_arm64_toolchain_config_repo": "remotejdk17_win_arm64_toolchain_config_repo", - "remotejdk21_linux_toolchain_config_repo": "remotejdk21_linux_toolchain_config_repo", - "remotejdk21_linux_aarch64_toolchain_config_repo": "remotejdk21_linux_aarch64_toolchain_config_repo", - "remotejdk21_macos_toolchain_config_repo": "remotejdk21_macos_toolchain_config_repo", - "remotejdk21_macos_aarch64_toolchain_config_repo": "remotejdk21_macos_aarch64_toolchain_config_repo", - "remotejdk21_win_toolchain_config_repo": "remotejdk21_win_toolchain_config_repo" - }, - "devImports": [], - "tags": [], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "platforms": "platforms@0.0.8", - "rules_cc": "rules_cc@0.0.9", - "bazel_skylib": "bazel_skylib@1.6.1", - "rules_proto": "rules_proto@6.0.2", - "rules_license": "rules_license@0.0.8", - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "urls": [ - "https://github.com/bazelbuild/rules_java/releases/download/7.4.0/rules_java-7.4.0.tar.gz" - ], - "integrity": "sha256-l27wi0nJKXQfIBeQ5Z44B8cq2B9CjIvJU82+/1/tFes=", - "strip_prefix": "", - "remote_patches": {}, - "remote_patch_strip": 0 - } - } - }, - "buildozer@6.4.0.2": { - "name": "buildozer", - "version": "6.4.0.2", - "key": "buildozer@6.4.0.2", - "repoName": "buildozer", - "executionPlatformsToRegister": [], - "toolchainsToRegister": [], - "extensionUsages": [ - { - "extensionBzlFile": "@buildozer//:buildozer_binary.bzl", - "extensionName": "buildozer_binary", - "usingModule": "buildozer@6.4.0.2", - "location": { - "file": "https://bcr.bazel.build/modules/buildozer/6.4.0.2/MODULE.bazel", - "line": 7, - "column": 33 - }, - "imports": { - "buildozer_binary": "buildozer_binary" - }, - "devImports": [], - "tags": [ - { - "tagName": "buildozer", - "attributeValues": { - "sha256": { - "darwin-amd64": "d29e347ecd6b5673d72cb1a8de05bf1b06178dd229ff5eb67fad5100c840cc8e", - "darwin-arm64": "9b9e71bdbec5e7223871e913b65d12f6d8fa026684daf991f00e52ed36a6978d", - "linux-amd64": "8dfd6345da4e9042daa738d7fdf34f699c5dfce4632f7207956fceedd8494119", - "linux-arm64": "6559558fded658c8fa7432a9d011f7c4dcbac6b738feae73d2d5c352e5f605fa", - "windows-amd64": "e7f05bf847f7c3689dd28926460ce6e1097ae97380ac8e6ae7147b7b706ba19b" - }, - "version": "6.4.0" - }, - "devDependency": false, - "location": { - "file": "https://bcr.bazel.build/modules/buildozer/6.4.0.2/MODULE.bazel", - "line": 8, - "column": 27 - } - } - ], - "hasDevUseExtension": false, - "hasNonDevUseExtension": true - } - ], - "deps": { - "bazel_tools": "bazel_tools@_", - "local_config_platform": "local_config_platform@_" - }, - "repoSpec": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "urls": [ - "https://github.com/fmeum/buildozer/releases/download/v6.4.0.2/buildozer-v6.4.0.2.tar.gz" - ], - "integrity": "sha256-k7tFKQMR2AygxpmZfH0yEPnQmF3efFgD9rBPkj+Yz/8=", - "strip_prefix": "buildozer-6.4.0.2", - "remote_patches": { - "https://bcr.bazel.build/modules/buildozer/6.4.0.2/patches/module_dot_bazel_version.patch": "sha256-gKANF2HMilj7bWmuXs4lbBIAAansuWC4IhWGB/CerjU=" - }, - "remote_patch_strip": 1 - } - } - }, - "zlib@1.3": { - "name": "zlib", - "version": "1.3", - "key": "zlib@1.3", - "repoName": "zlib", + "abseil-cpp@20240116.1": { + "name": "abseil-cpp", + "version": "20240116.1", + "key": "abseil-cpp@20240116.1", + "repoName": "abseil-cpp", "executionPlatformsToRegister": [], "toolchainsToRegister": [], "extensionUsages": [], "deps": { + "bazel_skylib": "bazel_skylib@1.6.1", + "com_google_googletest": "googletest@1.14.0.bcr.1", "platforms": "platforms@0.0.8", - "rules_cc": "rules_cc@0.0.9", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" }, @@ -1902,30 +1982,26 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz" + "https://github.com/abseil/abseil-cpp/releases/download/20240116.1/abseil-cpp-20240116.1.tar.gz" ], - "integrity": "sha256-/wukwpIBPbwnUws6geH5qBPNOd4Byl4Pi/NVcC76WT4=", - "strip_prefix": "zlib-1.3", + "integrity": "sha256-PHQyBN94NmrS6vI21mMdg/a8ko0XBd0AALhy5Ttz3Go=", + "strip_prefix": "abseil-cpp-20240116.1", "remote_patches": { - "https://bcr.bazel.build/modules/zlib/1.3/patches/add_build_file.patch": "sha256-Ei+FYaaOo7A3jTKunMEodTI0Uw5NXQyZEcboMC8JskY=", - "https://bcr.bazel.build/modules/zlib/1.3/patches/module_dot_bazel.patch": "sha256-fPWLM+2xaF/kuy+kZc1YTfW6hNjrkG400Ho7gckuyJk=" + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/patches/module_dot_bazel.patch": "sha256-H6J0U5xTQRVVGFkTsBioOCeWetuCfpavigN8YvpQkIQ=" }, "remote_patch_strip": 0 } } }, - "rules_pkg@0.7.0": { - "name": "rules_pkg", - "version": "0.7.0", - "key": "rules_pkg@0.7.0", - "repoName": "rules_pkg", + "jsoncpp@1.9.5": { + "name": "jsoncpp", + "version": "1.9.5", + "key": "jsoncpp@1.9.5", + "repoName": "jsoncpp", "executionPlatformsToRegister": [], "toolchainsToRegister": [], "extensionUsages": [], "deps": { - "rules_python": "rules_python@_", - "bazel_skylib": "bazel_skylib@1.6.1", - "rules_license": "rules_license@0.0.8", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" }, @@ -1934,30 +2010,259 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz" + "https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.9.5.tar.gz" ], - "integrity": "sha256-iimOgydi7aGDBZfWT+fbWBeKqEzVkm121bdE1lWJQcI=", - "strip_prefix": "", + "integrity": "sha256-9AmFblkgwY0ML7hSduJO5gfSoJtefV8KNxNokDwnXaI=", + "strip_prefix": "jsoncpp-1.9.5", "remote_patches": { - "https://bcr.bazel.build/modules/rules_pkg/0.7.0/patches/module_dot_bazel.patch": "sha256-4OaEPZwYF6iC71ZTDg6MJ7LLqX7ZA0/kK4mT+4xKqiE=" + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/patches/build_dot_bazel.patch": "sha256-Vj8diXSWps8I8h5cdEqBDYmKBA2ulvWxMZBEQlIgcpU=", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/patches/module_dot_bazel.patch": "sha256-7RC7fS8N11vcyeDEaUZ05yBqr0YY7OzuzqaWz5W2XDo=" }, - "remote_patch_strip": 0 + "remote_patch_strip": 1 } } }, - "abseil-cpp@20230802.0.bcr.1": { - "name": "abseil-cpp", - "version": "20230802.0.bcr.1", - "key": "abseil-cpp@20230802.0.bcr.1", - "repoName": "abseil-cpp", + "rules_fuzzing@0.5.2": { + "name": "rules_fuzzing", + "version": "0.5.2", + "key": "rules_fuzzing@0.5.2", + "repoName": "rules_fuzzing", "executionPlatformsToRegister": [], "toolchainsToRegister": [], - "extensionUsages": [], + "extensionUsages": [ + { + "extensionBzlFile": "@rules_fuzzing//fuzzing/private:extensions.bzl", + "extensionName": "non_module_dependencies", + "usingModule": "rules_fuzzing@0.5.2", + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 30, + "column": 40 + }, + "imports": { + "honggfuzz": "honggfuzz", + "rules_fuzzing_jazzer": "rules_fuzzing_jazzer", + "rules_fuzzing_jazzer_api": "rules_fuzzing_jazzer_api", + "rules_fuzzing_oss_fuzz": "rules_fuzzing_oss_fuzz" + }, + "devImports": [], + "tags": [], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_python//python/extensions:python.bzl", + "extensionName": "python", + "usingModule": "rules_fuzzing@0.5.2", + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 47, + "column": 23 + }, + "imports": {}, + "devImports": [], + "tags": [ + { + "tagName": "toolchain", + "attributeValues": { + "ignore_root_user_error": true, + "is_default": false, + "python_version": "3.8" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 50, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "ignore_root_user_error": true, + "is_default": false, + "python_version": "3.9" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 50, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "ignore_root_user_error": true, + "is_default": false, + "python_version": "3.10" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 50, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "ignore_root_user_error": true, + "is_default": false, + "python_version": "3.11" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 50, + "column": 21 + } + }, + { + "tagName": "toolchain", + "attributeValues": { + "ignore_root_user_error": true, + "is_default": true, + "python_version": "3.12" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 50, + "column": 21 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_python//python/extensions:pip.bzl", + "extensionName": "pip", + "usingModule": "rules_fuzzing@0.5.2", + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 59, + "column": 20 + }, + "imports": { + "fuzzing_py_deps": "rules_fuzzing_py_deps" + }, + "devImports": [], + "tags": [ + { + "tagName": "parse", + "attributeValues": { + "extra_pip_args": [ + "--require-hashes" + ], + "hub_name": "rules_fuzzing_py_deps", + "python_version": "3.8", + "requirements_lock": "//fuzzing:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 62, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "extra_pip_args": [ + "--require-hashes" + ], + "hub_name": "rules_fuzzing_py_deps", + "python_version": "3.9", + "requirements_lock": "//fuzzing:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 62, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "extra_pip_args": [ + "--require-hashes" + ], + "hub_name": "rules_fuzzing_py_deps", + "python_version": "3.10", + "requirements_lock": "//fuzzing:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 62, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "extra_pip_args": [ + "--require-hashes" + ], + "hub_name": "rules_fuzzing_py_deps", + "python_version": "3.11", + "requirements_lock": "//fuzzing:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 62, + "column": 14 + } + }, + { + "tagName": "parse", + "attributeValues": { + "extra_pip_args": [ + "--require-hashes" + ], + "hub_name": "rules_fuzzing_py_deps", + "python_version": "3.12", + "requirements_lock": "//fuzzing:requirements.txt" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 62, + "column": 14 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + }, + { + "extensionBzlFile": "@rules_java//java:extensions.bzl", + "extensionName": "toolchains", + "usingModule": "rules_fuzzing@0.5.2", + "location": { + "file": "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel", + "line": 73, + "column": 32 + }, + "imports": { + "local_jdk": "local_jdk" + }, + "devImports": [], + "tags": [], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + } + ], "deps": { - "rules_cc": "rules_cc@0.0.9", - "platforms": "platforms@0.0.8", + "com_google_absl": "abseil-cpp@20240116.1", "bazel_skylib": "bazel_skylib@1.6.1", - "com_google_googletest": "googletest@1.14.0", + "platforms": "platforms@0.0.8", + "rules_python": "rules_python@_", + "rules_java": "rules_java@7.4.0", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" }, @@ -1966,36 +2271,87 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz" + "https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.5.2/rules_fuzzing-0.5.2.zip" ], - "integrity": "sha256-WdKXavnW7PABqBo1dJpuVRozW5SdNJGM+t4Hc3udk8U=", - "strip_prefix": "abseil-cpp-20230802.0", + "integrity": "sha256-5rwhm/rJ4fg7Mn3QkPcoqflz7pm5tdjloYSicy7whiM=", + "strip_prefix": "rules_fuzzing-0.5.2", "remote_patches": { - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/patches/module_dot_bazel.patch": "sha256-Ku6wJ7uNqANq3fVmW03ySSUddevratZDsJ67NqtXIEY=" + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/patches/module_dot_bazel.patch": "sha256-+S/1nXWYEzeyvZeC9Zpgmt6bmmStrSBG99b33+dTmXc=" }, "remote_patch_strip": 0 } } }, - "upb@0.0.0-20230516-61a97ef": { - "name": "upb", - "version": "0.0.0-20230516-61a97ef", - "key": "upb@0.0.0-20230516-61a97ef", - "repoName": "upb", + "rules_java@7.4.0": { + "name": "rules_java", + "version": "7.4.0", + "key": "rules_java@7.4.0", + "repoName": "rules_java", "executionPlatformsToRegister": [], - "toolchainsToRegister": [], + "toolchainsToRegister": [ + "//toolchains:all", + "@local_jdk//:runtime_toolchain_definition", + "@local_jdk//:bootstrap_runtime_toolchain_definition", + "@remotejdk11_linux_toolchain_config_repo//:all", + "@remotejdk11_linux_aarch64_toolchain_config_repo//:all", + "@remotejdk11_linux_ppc64le_toolchain_config_repo//:all", + "@remotejdk11_linux_s390x_toolchain_config_repo//:all", + "@remotejdk11_macos_toolchain_config_repo//:all", + "@remotejdk11_macos_aarch64_toolchain_config_repo//:all", + "@remotejdk11_win_toolchain_config_repo//:all", + "@remotejdk11_win_arm64_toolchain_config_repo//:all", + "@remotejdk17_linux_toolchain_config_repo//:all", + "@remotejdk17_linux_aarch64_toolchain_config_repo//:all", + "@remotejdk17_linux_ppc64le_toolchain_config_repo//:all", + "@remotejdk17_linux_s390x_toolchain_config_repo//:all", + "@remotejdk17_macos_toolchain_config_repo//:all", + "@remotejdk17_macos_aarch64_toolchain_config_repo//:all", + "@remotejdk17_win_toolchain_config_repo//:all", + "@remotejdk17_win_arm64_toolchain_config_repo//:all", + "@remotejdk21_linux_toolchain_config_repo//:all", + "@remotejdk21_linux_aarch64_toolchain_config_repo//:all", + "@remotejdk21_macos_toolchain_config_repo//:all", + "@remotejdk21_macos_aarch64_toolchain_config_repo//:all", + "@remotejdk21_win_toolchain_config_repo//:all" + ], "extensionUsages": [ { - "extensionBzlFile": "@upb//:non_module_deps.bzl", - "extensionName": "non_module_deps", - "usingModule": "upb@0.0.0-20230516-61a97ef", + "extensionBzlFile": "@rules_java//java:extensions.bzl", + "extensionName": "toolchains", + "usingModule": "rules_java@7.4.0", "location": { - "file": "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel", - "line": 15, - "column": 32 + "file": "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel", + "line": 19, + "column": 27 }, "imports": { - "utf8_range": "utf8_range" + "remote_java_tools": "remote_java_tools", + "remote_java_tools_linux": "remote_java_tools_linux", + "remote_java_tools_windows": "remote_java_tools_windows", + "remote_java_tools_darwin_x86_64": "remote_java_tools_darwin_x86_64", + "remote_java_tools_darwin_arm64": "remote_java_tools_darwin_arm64", + "local_jdk": "local_jdk", + "remotejdk11_linux_toolchain_config_repo": "remotejdk11_linux_toolchain_config_repo", + "remotejdk11_linux_aarch64_toolchain_config_repo": "remotejdk11_linux_aarch64_toolchain_config_repo", + "remotejdk11_linux_ppc64le_toolchain_config_repo": "remotejdk11_linux_ppc64le_toolchain_config_repo", + "remotejdk11_linux_s390x_toolchain_config_repo": "remotejdk11_linux_s390x_toolchain_config_repo", + "remotejdk11_macos_toolchain_config_repo": "remotejdk11_macos_toolchain_config_repo", + "remotejdk11_macos_aarch64_toolchain_config_repo": "remotejdk11_macos_aarch64_toolchain_config_repo", + "remotejdk11_win_toolchain_config_repo": "remotejdk11_win_toolchain_config_repo", + "remotejdk11_win_arm64_toolchain_config_repo": "remotejdk11_win_arm64_toolchain_config_repo", + "remotejdk17_linux_toolchain_config_repo": "remotejdk17_linux_toolchain_config_repo", + "remotejdk17_linux_aarch64_toolchain_config_repo": "remotejdk17_linux_aarch64_toolchain_config_repo", + "remotejdk17_linux_ppc64le_toolchain_config_repo": "remotejdk17_linux_ppc64le_toolchain_config_repo", + "remotejdk17_linux_s390x_toolchain_config_repo": "remotejdk17_linux_s390x_toolchain_config_repo", + "remotejdk17_macos_toolchain_config_repo": "remotejdk17_macos_toolchain_config_repo", + "remotejdk17_macos_aarch64_toolchain_config_repo": "remotejdk17_macos_aarch64_toolchain_config_repo", + "remotejdk17_win_toolchain_config_repo": "remotejdk17_win_toolchain_config_repo", + "remotejdk17_win_arm64_toolchain_config_repo": "remotejdk17_win_arm64_toolchain_config_repo", + "remotejdk21_linux_toolchain_config_repo": "remotejdk21_linux_toolchain_config_repo", + "remotejdk21_linux_aarch64_toolchain_config_repo": "remotejdk21_linux_aarch64_toolchain_config_repo", + "remotejdk21_macos_toolchain_config_repo": "remotejdk21_macos_toolchain_config_repo", + "remotejdk21_macos_aarch64_toolchain_config_repo": "remotejdk21_macos_aarch64_toolchain_config_repo", + "remotejdk21_win_toolchain_config_repo": "remotejdk21_win_toolchain_config_repo" }, "devImports": [], "tags": [], @@ -2004,12 +2360,11 @@ } ], "deps": { + "platforms": "platforms@0.0.8", + "rules_cc": "rules_cc@0.0.9", "bazel_skylib": "bazel_skylib@1.6.1", "rules_proto": "rules_proto@6.0.2", - "com_google_protobuf": "protobuf@24.4", - "com_google_absl": "abseil-cpp@20230802.0.bcr.1", - "rules_pkg": "rules_pkg@0.7.0", - "platforms": "platforms@0.0.8", + "rules_license": "rules_license@0.0.8", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" }, @@ -2018,16 +2373,12 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/protocolbuffers/upb/archive/61a97efa24a5ce01fb8cc73c9d1e6e7060f8ea98.tar.gz" + "https://github.com/bazelbuild/rules_java/releases/download/7.4.0/rules_java-7.4.0.tar.gz" ], - "integrity": "sha256-fRnyrJweUIqGonKRPZqmfIFHgn+UkDWCiRC7BdnyzwM=", - "strip_prefix": "upb-61a97efa24a5ce01fb8cc73c9d1e6e7060f8ea98", - "remote_patches": { - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/patches/0001-Add-MODULE.bazel.patch": "sha256-YSOPeNFt006ghZRI1D056RQ1USwCodZnjXMw6pAPhKc=", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/patches/0002-Add-utf8_range-dependency.patch": "sha256-L9jPxcjZqoJh5t9mH4BR01puRI5aUY4jtYptZt5T/p8=", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/patches/0003-Backport-path-generation-instead-of-hardcoded-one.patch": "sha256-K+OqQb2b+5k43UOwHupBlfqakuNST470j/yTfvwjj04=" - }, - "remote_patch_strip": 1 + "integrity": "sha256-l27wi0nJKXQfIBeQ5Z44B8cq2B9CjIvJU82+/1/tFes=", + "strip_prefix": "", + "remote_patches": {}, + "remote_patch_strip": 0 } } }, @@ -2119,18 +2470,18 @@ } } }, - "googletest@1.14.0": { - "name": "googletest", - "version": "1.14.0", - "key": "googletest@1.14.0", - "repoName": "googletest", + "rules_pkg@0.7.0": { + "name": "rules_pkg", + "version": "0.7.0", + "key": "rules_pkg@0.7.0", + "repoName": "rules_pkg", "executionPlatformsToRegister": [], "toolchainsToRegister": [], "extensionUsages": [], "deps": { - "com_google_absl": "abseil-cpp@20230802.0.bcr.1", - "platforms": "platforms@0.0.8", - "rules_cc": "rules_cc@0.0.9", + "rules_python": "rules_python@_", + "bazel_skylib": "bazel_skylib@1.6.1", + "rules_license": "rules_license@0.0.8", "bazel_tools": "bazel_tools@_", "local_config_platform": "local_config_platform@_" }, @@ -2139,17 +2490,114 @@ "ruleClassName": "http_archive", "attributes": { "urls": [ - "https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz" + "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz" ], - "integrity": "sha256-itWYxzrXluDYKAsILOvYKmMNc+c808cAV5OKZQG7pdc=", - "strip_prefix": "googletest-1.14.0", + "integrity": "sha256-iimOgydi7aGDBZfWT+fbWBeKqEzVkm121bdE1lWJQcI=", + "strip_prefix": "", + "remote_patches": { + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/patches/module_dot_bazel.patch": "sha256-4OaEPZwYF6iC71ZTDg6MJ7LLqX7ZA0/kK4mT+4xKqiE=" + }, + "remote_patch_strip": 0 + } + } + }, + "zlib@1.3.1": { + "name": "zlib", + "version": "1.3.1", + "key": "zlib@1.3.1", + "repoName": "zlib", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [], + "extensionUsages": [], + "deps": { + "platforms": "platforms@0.0.8", + "rules_cc": "rules_cc@0.0.9", + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz" + ], + "integrity": "sha256-mpOyt9/ax3zrpaVYpYDnRmfdb+3kWFuR7vtg8Dty3yM=", + "strip_prefix": "zlib-1.3.1", "remote_patches": { - "https://bcr.bazel.build/modules/googletest/1.14.0/patches/module_dot_bazel.patch": "sha256-CSomzvti38LCuURDG5EEoa3O1tQF3cKKt/mknnP1qcc=" + "https://bcr.bazel.build/modules/zlib/1.3.1/patches/add_build_file.patch": "sha256-Ei+FYaaOo7A3jTKunMEodTI0Uw5NXQyZEcboMC8JskY=", + "https://bcr.bazel.build/modules/zlib/1.3.1/patches/module_dot_bazel.patch": "sha256-IFCFES6KY2jaryT+Kq2NemDn7hgdZYH0kZC1esA4cyE=" }, "remote_patch_strip": 0 } } }, + "buildozer@6.4.0.2": { + "name": "buildozer", + "version": "6.4.0.2", + "key": "buildozer@6.4.0.2", + "repoName": "buildozer", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [], + "extensionUsages": [ + { + "extensionBzlFile": "@buildozer//:buildozer_binary.bzl", + "extensionName": "buildozer_binary", + "usingModule": "buildozer@6.4.0.2", + "location": { + "file": "https://bcr.bazel.build/modules/buildozer/6.4.0.2/MODULE.bazel", + "line": 7, + "column": 33 + }, + "imports": { + "buildozer_binary": "buildozer_binary" + }, + "devImports": [], + "tags": [ + { + "tagName": "buildozer", + "attributeValues": { + "sha256": { + "darwin-amd64": "d29e347ecd6b5673d72cb1a8de05bf1b06178dd229ff5eb67fad5100c840cc8e", + "darwin-arm64": "9b9e71bdbec5e7223871e913b65d12f6d8fa026684daf991f00e52ed36a6978d", + "linux-amd64": "8dfd6345da4e9042daa738d7fdf34f699c5dfce4632f7207956fceedd8494119", + "linux-arm64": "6559558fded658c8fa7432a9d011f7c4dcbac6b738feae73d2d5c352e5f605fa", + "windows-amd64": "e7f05bf847f7c3689dd28926460ce6e1097ae97380ac8e6ae7147b7b706ba19b" + }, + "version": "6.4.0" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/buildozer/6.4.0.2/MODULE.bazel", + "line": 8, + "column": 27 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + } + ], + "deps": { + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/fmeum/buildozer/releases/download/v6.4.0.2/buildozer-v6.4.0.2.tar.gz" + ], + "integrity": "sha256-k7tFKQMR2AygxpmZfH0yEPnQmF3efFgD9rBPkj+Yz/8=", + "strip_prefix": "buildozer-6.4.0.2", + "remote_patches": { + "https://bcr.bazel.build/modules/buildozer/6.4.0.2/patches/module_dot_bazel_version.patch": "sha256-gKANF2HMilj7bWmuXs4lbBIAAansuWC4IhWGB/CerjU=" + }, + "remote_patch_strip": 1 + } + } + }, "rules_nodejs@5.8.2": { "name": "rules_nodejs", "version": "5.8.2", @@ -2291,6 +2739,131 @@ "remote_patch_strip": 0 } } + }, + "googletest@1.14.0.bcr.1": { + "name": "googletest", + "version": "1.14.0.bcr.1", + "key": "googletest@1.14.0.bcr.1", + "repoName": "googletest", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [], + "extensionUsages": [], + "deps": { + "com_google_absl": "abseil-cpp@20240116.1", + "platforms": "platforms@0.0.8", + "rules_cc": "rules_cc@0.0.9", + "com_googlesource_code_re2": "re2@2023-09-01", + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz" + ], + "integrity": "sha256-itWYxzrXluDYKAsILOvYKmMNc+c808cAV5OKZQG7pdc=", + "strip_prefix": "googletest-1.14.0", + "remote_patches": { + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/patches/module_dot_bazel.patch": "sha256-jijctisPYOzP4X4cl0K7neRh/kqJB+yODNHf8V8heCE=" + }, + "remote_patch_strip": 0 + } + } + }, + "re2@2023-09-01": { + "name": "re2", + "version": "2023-09-01", + "key": "re2@2023-09-01", + "repoName": "re2", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [], + "extensionUsages": [ + { + "extensionBzlFile": "@pybind11_bazel//:python_configure.bzl", + "extensionName": "extension", + "usingModule": "re2@2023-09-01", + "location": { + "file": "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel", + "line": 22, + "column": 33 + }, + "imports": { + "local_config_python": "local_config_python", + "pybind11": "pybind11" + }, + "devImports": [], + "tags": [ + { + "tagName": "toolchain", + "attributeValues": { + "python_version": "3" + }, + "devDependency": false, + "location": { + "file": "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel", + "line": 23, + "column": 27 + } + } + ], + "hasDevUseExtension": false, + "hasNonDevUseExtension": true + } + ], + "deps": { + "platforms": "platforms@0.0.8", + "rules_cc": "rules_cc@0.0.9", + "com_google_absl": "abseil-cpp@20240116.1", + "rules_python": "rules_python@_", + "pybind11_bazel": "pybind11_bazel@2.11.1", + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/google/re2/releases/download/2023-09-01/re2-2023-09-01.zip" + ], + "integrity": "sha256-IkuDUdxGM7EBLb2EdWTgYKRr5goioUY9S1uZP9S/Wcw=", + "strip_prefix": "re2-2023-09-01", + "remote_patches": { + "https://bcr.bazel.build/modules/re2/2023-09-01/patches/module_dot_bazel.patch": "sha256-MUQkRNgPJ0lbYqOXoBu2m2vLH7IuKEbK/VWTw7WWrnA=" + }, + "remote_patch_strip": 0 + } + } + }, + "pybind11_bazel@2.11.1": { + "name": "pybind11_bazel", + "version": "2.11.1", + "key": "pybind11_bazel@2.11.1", + "repoName": "pybind11_bazel", + "executionPlatformsToRegister": [], + "toolchainsToRegister": [], + "extensionUsages": [], + "deps": { + "platforms": "platforms@0.0.8", + "rules_cc": "rules_cc@0.0.9", + "bazel_tools": "bazel_tools@_", + "local_config_platform": "local_config_platform@_" + }, + "repoSpec": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/pybind/pybind11_bazel/releases/download/v2.11.1/pybind11_bazel-2.11.1.zip" + ], + "integrity": "sha256-LEZsmzzKeFK0fgeFADEomE/PDV1hoaLkxazu/ZNawiA=", + "strip_prefix": "pybind11_bazel-2.11.1", + "remote_patches": {}, + "remote_patch_strip": 0 + } + } } }, "moduleExtensions": { @@ -3295,28 +3868,35 @@ "recordedRepoMappingEntries": [] } }, - "@@protobuf~//:non_module_deps.bzl%non_module_deps": { + "@@pybind11_bazel~//:python_configure.bzl%extension": { "general": { - "bzlTransitiveDigest": "aGnO/HqVtCmRLEQWGCuKp7jwX+lCh/nc3/hI3clfwD8=", - "recordedFileInputs": {}, + "bzlTransitiveDigest": "DJPCeiYqQS2i13szWN5NSI6sC6eaWgvECEyY/oNXWms=", + "recordedFileInputs": { + "@@pybind11_bazel~//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" + }, "recordedDirentsInputs": {}, "envVariables": {}, "generatedRepoSpecs": { - "utf8_range": { + "local_config_python": { + "bzlFile": "@@pybind11_bazel~//:python_configure.bzl", + "ruleClassName": "python_configure", + "attributes": {} + }, + "pybind11": { "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", "ruleClassName": "http_archive", "attributes": { + "build_file": "@@pybind11_bazel~//:pybind11.BUILD", + "strip_prefix": "pybind11-2.11.1", "urls": [ - "https://github.com/protocolbuffers/utf8_range/archive/de0b4a8ff9b5d4c98108bdfe723291a33c52c54f.zip" - ], - "strip_prefix": "utf8_range-de0b4a8ff9b5d4c98108bdfe723291a33c52c54f", - "sha256": "5da960e5e5d92394c809629a03af3c7709d2d3d0ca731dacb3a9fb4bf28f7702" + "https://github.com/pybind/pybind11/archive/v2.11.1.zip" + ] } } }, "recordedRepoMappingEntries": [ [ - "protobuf~", + "pybind11_bazel~", "bazel_tools", "bazel_tools" ] @@ -3347,6 +3927,96 @@ ] } }, + "@@rules_fuzzing~//fuzzing/private:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "9kQ3JauWmRx45J65UZSW1lSvsLfHK49ZHkX6kws/stU=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "bazel_skylib": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz" + ] + } + }, + "rules_fuzzing_jazzer": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_jar", + "attributes": { + "sha256": "ee6feb569d88962d59cb59e8a31eb9d007c82683f3ebc64955fd5b96f277eec2", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer/0.20.1/jazzer-0.20.1.jar" + } + }, + "rules_python": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "d70cd72a7a4880f0000a6346253414825c19cdd40a28289bdf67b8e6480edff8", + "strip_prefix": "rules_python-0.28.0", + "url": "https://github.com/bazelbuild/rules_python/releases/download/0.28.0/rules_python-0.28.0.tar.gz" + } + }, + "rules_fuzzing_oss_fuzz": { + "bzlFile": "@@rules_fuzzing~//fuzzing/private/oss_fuzz:repository.bzl", + "ruleClassName": "oss_fuzz_repository", + "attributes": {} + }, + "com_google_absl": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240116.1.zip" + ], + "strip_prefix": "abseil-cpp-20240116.1", + "integrity": "sha256-7capMWOvWyoYbUaHF/b+I2U6XLMaHmky8KugWvfXYuk=" + } + }, + "honggfuzz": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "build_file": "@@rules_fuzzing~//:honggfuzz.BUILD", + "sha256": "6b18ba13bc1f36b7b950c72d80f19ea67fbadc0ac0bb297ec89ad91f2eaa423e", + "url": "https://github.com/google/honggfuzz/archive/2.5.zip", + "strip_prefix": "honggfuzz-2.5" + } + }, + "platforms": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz" + ], + "sha256": "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74" + } + }, + "rules_fuzzing_jazzer_api": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_jar", + "attributes": { + "sha256": "f5a60242bc408f7fa20fccf10d6c5c5ea1fcb3c6f44642fec5af88373ae7aa1b", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer-api/0.20.1/jazzer-api-0.20.1.jar" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_fuzzing~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, "@@rules_java~//java:extensions.bzl%toolchains": { "general": { "bzlTransitiveDigest": "tJHbmWnq7m+9eUBnUdv7jZziQ26FmcGL9C5/hU3Q9UQ=", @@ -4211,48 +4881,9 @@ "downloaded_file_path": "com/google/oauth-client/google-oauth-client/1.31.1/google-oauth-client-1.31.1.jar" } }, - "maven": { - "bzlFile": "@@rules_jvm_external~//:coursier.bzl", - "ruleClassName": "coursier_fetch", - "attributes": { - "repositories": [ - "{ \"repo_url\": \"https://repo1.maven.org/maven2\" }" - ], - "artifacts": [ - "{ \"group\": \"com.google.code.findbugs\", \"artifact\": \"jsr305\", \"version\": \"3.0.2\" }", - "{ \"group\": \"com.google.code.gson\", \"artifact\": \"gson\", \"version\": \"2.8.9\" }", - "{ \"group\": \"com.google.errorprone\", \"artifact\": \"error_prone_annotations\", \"version\": \"2.3.2\" }", - "{ \"group\": \"com.google.j2objc\", \"artifact\": \"j2objc-annotations\", \"version\": \"1.3\" }", - "{ \"group\": \"com.google.guava\", \"artifact\": \"guava\", \"version\": \"31.1-jre\" }", - "{ \"group\": \"com.google.guava\", \"artifact\": \"guava-testlib\", \"version\": \"31.1-jre\" }", - "{ \"group\": \"com.google.truth\", \"artifact\": \"truth\", \"version\": \"1.1.2\" }", - "{ \"group\": \"junit\", \"artifact\": \"junit\", \"version\": \"4.13.2\" }", - "{ \"group\": \"org.mockito\", \"artifact\": \"mockito-core\", \"version\": \"4.3.1\" }" - ], - "fail_on_missing_checksum": true, - "fetch_sources": true, - "fetch_javadoc": false, - "excluded_artifacts": [], - "generate_compat_repositories": false, - "version_conflict_policy": "default", - "override_targets": {}, - "strict_visibility": false, - "strict_visibility_value": [ - "@@//visibility:private" - ], - "resolve_timeout": 600, - "jetify": false, - "jetify_include_list": [ - "*" - ], - "use_starlark_android_rules": false, - "aar_import_bzl_label": "@build_bazel_rules_android//android:rules.bzl", - "duplicate_version_warning": "warn" - } - }, - "software_amazon_awssdk_aws_xml_protocol_2_17_183": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_file", + "software_amazon_awssdk_aws_xml_protocol_2_17_183": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", "attributes": { "sha256": "566bba05d49256fa6994efd68fa625ae05a62ea45ee74bb9130d20ea20988363", "urls": [ @@ -5102,7 +5733,7 @@ }, "@@rules_python~//python/private/pypi:pip.bzl%pip_internal": { "general": { - "bzlTransitiveDigest": "H+DH88SNvq6JY6+HlxNwz1YGNoModIYcyGwHAzpw3pI=", + "bzlTransitiveDigest": "USZadcu8aw/cnMJ66IU2YvXZ56ZQQVX12eYsmEo9d7c=", "recordedFileInputs": { "@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a", "@@rules_python~//tools/publish/requirements_windows.txt": "15472d5a28e068d31ba9e2dc389459698afaff366e9db06e15890283a3ea252e", @@ -7113,122 +7744,576 @@ "requirement": "webencodings==0.5.1", "sha256": "a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", "urls": [ - "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl" - ] + "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_sdist_ebea339a": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "charset-normalizer-3.0.1.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.0.1", + "sha256": "ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", + "urls": [ + "https://files.pythonhosted.org/packages/96/d7/1675d9089a1f4677df5eb29c3f8b064aa1e70c1251a0a8a127803158942d/charset-normalizer-3.0.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_1_aarch64_72966d1b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.0.1", + "sha256": "72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", + "urls": [ + "https://files.pythonhosted.org/packages/01/ff/9ee4a44e8c32fe96dfc12daa42f29294608a55eadc88f327939327fb20fb/charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_573f6eac": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.3.2", + "sha256": "573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "urls": [ + "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_pycparser_sdist_e644fdec": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "pycparser-2.21.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.21", + "sha256": "e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206", + "urls": [ + "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_bleach_sdist_1a1a85c1": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "bleach-6.0.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "bleach==6.0.0", + "sha256": "1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", + "urls": [ + "https://files.pythonhosted.org/packages/7e/e6/d5f220ca638f6a25557a611860482cb6e54b2d97f0332966b1b005742e1f/bleach-6.0.0.tar.gz" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features~", + "bazel_features_globals", + "bazel_features~~version_extension~bazel_features_globals" + ], + [ + "bazel_features~", + "bazel_features_version", + "bazel_features~~version_extension~bazel_features_version" + ], + [ + "rules_python~", + "bazel_features", + "bazel_features~" + ], + [ + "rules_python~", + "bazel_skylib", + "bazel_skylib~" + ], + [ + "rules_python~", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python~", + "pypi__build", + "rules_python~~internal_deps~pypi__build" + ], + [ + "rules_python~", + "pypi__click", + "rules_python~~internal_deps~pypi__click" + ], + [ + "rules_python~", + "pypi__colorama", + "rules_python~~internal_deps~pypi__colorama" + ], + [ + "rules_python~", + "pypi__importlib_metadata", + "rules_python~~internal_deps~pypi__importlib_metadata" + ], + [ + "rules_python~", + "pypi__installer", + "rules_python~~internal_deps~pypi__installer" + ], + [ + "rules_python~", + "pypi__more_itertools", + "rules_python~~internal_deps~pypi__more_itertools" + ], + [ + "rules_python~", + "pypi__packaging", + "rules_python~~internal_deps~pypi__packaging" + ], + [ + "rules_python~", + "pypi__pep517", + "rules_python~~internal_deps~pypi__pep517" + ], + [ + "rules_python~", + "pypi__pip", + "rules_python~~internal_deps~pypi__pip" + ], + [ + "rules_python~", + "pypi__pip_tools", + "rules_python~~internal_deps~pypi__pip_tools" + ], + [ + "rules_python~", + "pypi__pyproject_hooks", + "rules_python~~internal_deps~pypi__pyproject_hooks" + ], + [ + "rules_python~", + "pypi__setuptools", + "rules_python~~internal_deps~pypi__setuptools" + ], + [ + "rules_python~", + "pypi__tomli", + "rules_python~~internal_deps~pypi__tomli" + ], + [ + "rules_python~", + "pypi__wheel", + "rules_python~~internal_deps~pypi__wheel" + ], + [ + "rules_python~", + "pypi__zipp", + "rules_python~~internal_deps~pypi__zipp" + ], + [ + "rules_python~", + "pythons_hub", + "rules_python~~python~pythons_hub" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_10_host", + "rules_python~~python~python_3_10_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_11_host", + "rules_python~~python~python_3_11_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_3_host", + "rules_python~~python~python_3_12_3_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_host", + "rules_python~~python~python_3_12_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_8_12_host", + "rules_python~~python~python_3_8_12_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_8_host", + "rules_python~~python~python_3_8_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_9_host", + "rules_python~~python~python_3_9_host" + ] + ] + } + }, + "@@rules_rust~//crate_universe:extension.bzl%crate": { + "general": { + "bzlTransitiveDigest": "6mE8s7wFAWiPu3kQk6oTasDDdM99gLsQl93XBnkbkac=", + "recordedFileInputs": { + "@@rules_rust~~rust_host_tools~rust_host_tools//bin/rustc": "3f89818bb07ef2c1b4191a9289e0871c91b1e693792629d92c864bef5c2484f3", + "@@rules_rust~~rust_host_tools~rust_host_tools//bin/cargo": "7046c9b8b9cbce00ad3e757211d7fb6b893d8413accb4ae6c90e4b2ef4c32b33" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "crates__paste-1.0.15": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/paste/1.0.15/download" + ], + "strip_prefix": "paste-1.0.15", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_build_script\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_proc_macro(\n name = \"paste\",\n deps = [\n \"@crates__paste-1.0.15//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=paste\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.15\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2018\",\n pkg_name = \"paste\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=paste\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.15\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__memchr-2.7.4": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/memchr/2.7.4/download" + ], + "strip_prefix": "memchr-2.7.4", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"memchr\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=memchr\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.7.4\",\n)\n" + } + }, + "crates__autocfg-1.4.0": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/autocfg/1.4.0/download" + ], + "strip_prefix": "autocfg-1.4.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"autocfg\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2015\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=autocfg\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.4.0\",\n)\n" + } + }, + "crates__regex-automata-0.4.8": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/regex-automata/0.4.8/download" + ], + "strip_prefix": "regex-automata-0.4.8", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"regex_automata\",\n deps = [\n \"@crates__aho-corasick-1.1.3//:aho_corasick\",\n \"@crates__memchr-2.7.4//:memchr\",\n \"@crates__regex-syntax-0.8.5//:regex_syntax\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"dfa-onepass\",\n \"hybrid\",\n \"meta\",\n \"nfa-backtrack\",\n \"nfa-pikevm\",\n \"nfa-thompson\",\n \"perf-inline\",\n \"perf-literal\",\n \"perf-literal-multisubstring\",\n \"perf-literal-substring\",\n \"std\",\n \"syntax\",\n \"unicode\",\n \"unicode-age\",\n \"unicode-bool\",\n \"unicode-case\",\n \"unicode-gencat\",\n \"unicode-perl\",\n \"unicode-script\",\n \"unicode-segment\",\n \"unicode-word-boundary\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex-automata\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.4.8\",\n)\n" + } + }, + "crates__unicode-ident-1.0.13": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/unicode-ident/1.0.13/download" + ], + "strip_prefix": "unicode-ident-1.0.13", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"unicode_ident\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=unicode-ident\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.13\",\n)\n" + } + }, + "crates__googletest-0.12.0": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "22e38fa267f4db1a2fa51795ea4234eaadc3617a97486a9f158de9256672260e", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/googletest/0.12.0/download" + ], + "strip_prefix": "googletest-0.12.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"googletest\",\n deps = [\n \"@crates__num-traits-0.2.19//:num_traits\",\n \"@crates__regex-1.11.0//:regex\",\n ],\n proc_macro_deps = [\n \"@crates__googletest_macro-0.12.0//:googletest_macro\",\n \"@crates__rustversion-1.0.17//:rustversion\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=googletest\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.12.0\",\n)\n" + } + }, + "crates__googletest_macro-0.12.0": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "171deab504ad43a9ea80324a3686a0cbe9436220d9d0b48ae4d7f7bd303b48a9", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/googletest_macro/0.12.0/download" + ], + "strip_prefix": "googletest_macro-0.12.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_proc_macro(\n name = \"googletest_macro\",\n deps = [\n \"@crates__quote-1.0.37//:quote\",\n \"@crates__syn-2.0.79//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=googletest_macro\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.12.0\",\n)\n" + } + }, + "crates": { + "bzlFile": "@@rules_rust~//crate_universe:extension.bzl", + "ruleClassName": "_generate_repo", + "attributes": { + "contents": { + "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"googletest\",\n actual = \"@crates__googletest-0.12.0//:googletest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"paste\",\n actual = \"@crates__paste-1.0.15//:paste\",\n tags = [\"manual\"],\n)\n", + "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"\": {\n _COMMON_CONDITION: {\n \"googletest\": Label(\"@crates__googletest-0.12.0//:googletest\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"\": {\n _COMMON_CONDITION: {\n \"paste\": Label(\"@crates__paste-1.0.15//:paste\"),\n },\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"\": {\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-apple-darwin\": [\"@rules_rust//rust/platform:aarch64-apple-darwin\"],\n \"aarch64-apple-ios\": [\"@rules_rust//rust/platform:aarch64-apple-ios\"],\n \"aarch64-apple-ios-sim\": [\"@rules_rust//rust/platform:aarch64-apple-ios-sim\"],\n \"aarch64-fuchsia\": [\"@rules_rust//rust/platform:aarch64-fuchsia\"],\n \"aarch64-linux-android\": [\"@rules_rust//rust/platform:aarch64-linux-android\"],\n \"aarch64-pc-windows-msvc\": [\"@rules_rust//rust/platform:aarch64-pc-windows-msvc\"],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-nixos-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\"],\n \"aarch64-unknown-nto-qnx710\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\"],\n \"arm-unknown-linux-gnueabi\": [\"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\"],\n \"armv7-linux-androideabi\": [\"@rules_rust//rust/platform:armv7-linux-androideabi\"],\n \"armv7-unknown-linux-gnueabi\": [\"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\"],\n \"i686-apple-darwin\": [\"@rules_rust//rust/platform:i686-apple-darwin\"],\n \"i686-linux-android\": [\"@rules_rust//rust/platform:i686-linux-android\"],\n \"i686-pc-windows-msvc\": [\"@rules_rust//rust/platform:i686-pc-windows-msvc\"],\n \"i686-unknown-freebsd\": [\"@rules_rust//rust/platform:i686-unknown-freebsd\"],\n \"i686-unknown-linux-gnu\": [\"@rules_rust//rust/platform:i686-unknown-linux-gnu\"],\n \"powerpc-unknown-linux-gnu\": [\"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\"],\n \"riscv32imc-unknown-none-elf\": [\"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\"],\n \"riscv64gc-unknown-none-elf\": [\"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\"],\n \"s390x-unknown-linux-gnu\": [\"@rules_rust//rust/platform:s390x-unknown-linux-gnu\"],\n \"thumbv7em-none-eabi\": [\"@rules_rust//rust/platform:thumbv7em-none-eabi\"],\n \"thumbv8m.main-none-eabi\": [\"@rules_rust//rust/platform:thumbv8m.main-none-eabi\"],\n \"wasm32-unknown-unknown\": [\"@rules_rust//rust/platform:wasm32-unknown-unknown\"],\n \"wasm32-wasi\": [\"@rules_rust//rust/platform:wasm32-wasi\"],\n \"x86_64-apple-darwin\": [\"@rules_rust//rust/platform:x86_64-apple-darwin\"],\n \"x86_64-apple-ios\": [\"@rules_rust//rust/platform:x86_64-apple-ios\"],\n \"x86_64-fuchsia\": [\"@rules_rust//rust/platform:x86_64-fuchsia\"],\n \"x86_64-linux-android\": [\"@rules_rust//rust/platform:x86_64-linux-android\"],\n \"x86_64-pc-windows-msvc\": [\"@rules_rust//rust/platform:x86_64-pc-windows-msvc\"],\n \"x86_64-unknown-freebsd\": [\"@rules_rust//rust/platform:x86_64-unknown-freebsd\"],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"x86_64-unknown-nixos-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\"],\n \"x86_64-unknown-none\": [\"@rules_rust//rust/platform:x86_64-unknown-none\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.3\",\n sha256 = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.3/download\"],\n strip_prefix = \"aho-corasick-1.1.3\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.4.0\",\n sha256 = \"ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.4.0/download\"],\n strip_prefix = \"autocfg-1.4.0\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__googletest-0.12.0\",\n sha256 = \"22e38fa267f4db1a2fa51795ea4234eaadc3617a97486a9f158de9256672260e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/googletest/0.12.0/download\"],\n strip_prefix = \"googletest-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.googletest-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__googletest_macro-0.12.0\",\n sha256 = \"171deab504ad43a9ea80324a3686a0cbe9436220d9d0b48ae4d7f7bd303b48a9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/googletest_macro/0.12.0/download\"],\n strip_prefix = \"googletest_macro-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.googletest_macro-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.7.4\",\n sha256 = \"78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.7.4/download\"],\n strip_prefix = \"memchr-2.7.4\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.7.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__paste-1.0.15\",\n sha256 = \"57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/paste/1.0.15/download\"],\n strip_prefix = \"paste-1.0.15\",\n build_file = Label(\"@crates//crates:BUILD.paste-1.0.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.86\",\n sha256 = \"5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.86/download\"],\n strip_prefix = \"proc-macro2-1.0.86\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.86.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.37\",\n sha256 = \"b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.37/download\"],\n strip_prefix = \"quote-1.0.37\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.37.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.11.0\",\n sha256 = \"38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.11.0/download\"],\n strip_prefix = \"regex-1.11.0\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.8\",\n sha256 = \"368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.8/download\"],\n strip_prefix = \"regex-automata-0.4.8\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.5\",\n sha256 = \"2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.5/download\"],\n strip_prefix = \"regex-syntax-0.8.5\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustversion-1.0.17\",\n sha256 = \"955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustversion/1.0.17/download\"],\n strip_prefix = \"rustversion-1.0.17\",\n build_file = Label(\"@crates//crates:BUILD.rustversion-1.0.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.79\",\n sha256 = \"89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.79/download\"],\n strip_prefix = \"syn-2.0.79\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.79.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.13\",\n sha256 = \"e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.13/download\"],\n strip_prefix = \"unicode-ident-1.0.13\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.13.bazel\"),\n )\n\n return [\n struct(repo=\"crates__googletest-0.12.0\", is_dev_dep = False),\n struct(repo=\"crates__paste-1.0.15\", is_dev_dep = False),\n ]\n" + } + } + }, + "crates__quote-1.0.37": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/quote/1.0.37/download" + ], + "strip_prefix": "quote-1.0.37", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"quote\",\n deps = [\n \"@crates__proc-macro2-1.0.86//:proc_macro2\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=quote\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.37\",\n)\n" + } + }, + "crates__regex-1.11.0": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/regex/1.11.0/download" + ], + "strip_prefix": "regex-1.11.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"regex\",\n deps = [\n \"@crates__aho-corasick-1.1.3//:aho_corasick\",\n \"@crates__memchr-2.7.4//:memchr\",\n \"@crates__regex-automata-0.4.8//:regex_automata\",\n \"@crates__regex-syntax-0.8.5//:regex_syntax\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"perf\",\n \"perf-backtrack\",\n \"perf-cache\",\n \"perf-dfa\",\n \"perf-inline\",\n \"perf-literal\",\n \"perf-onepass\",\n \"std\",\n \"unicode\",\n \"unicode-age\",\n \"unicode-bool\",\n \"unicode-case\",\n \"unicode-gencat\",\n \"unicode-perl\",\n \"unicode-script\",\n \"unicode-segment\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.11.0\",\n)\n" + } + }, + "crates__aho-corasick-1.1.3": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "patch_args": [ + "-p0" + ], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/aho-corasick/1.1.3/download" + ], + "strip_prefix": "aho-corasick-1.1.3", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"aho_corasick\",\n deps = [\n \"@crates__memchr-2.7.4//:memchr\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"perf-literal\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=aho-corasick\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.1.3\",\n)\n" } }, - "rules_python_publish_deps_311_charset_normalizer_sdist_ebea339a": { - "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", - "ruleClassName": "whl_library", + "crates__syn-2.0.79": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", "attributes": { - "dep_template": "@rules_python_publish_deps//{name}:{target}", - "experimental_target_platforms": [ - "cp311_linux_aarch64", - "cp311_linux_arm", - "cp311_linux_ppc", - "cp311_linux_s390x", - "cp311_linux_x86_64" + "patch_args": [ + "-p0" ], - "filename": "charset-normalizer-3.0.1.tar.gz", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", - "repo": "rules_python_publish_deps_311", - "requirement": "charset-normalizer==3.0.1", - "sha256": "ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f", + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590", + "type": "tar.gz", "urls": [ - "https://files.pythonhosted.org/packages/96/d7/1675d9089a1f4677df5eb29c3f8b064aa1e70c1251a0a8a127803158942d/charset-normalizer-3.0.1.tar.gz" - ] + "https://static.crates.io/crates/syn/2.0.79/download" + ], + "strip_prefix": "syn-2.0.79", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"syn\",\n deps = [\n \"@crates__proc-macro2-1.0.86//:proc_macro2\",\n \"@crates__quote-1.0.37//:quote\",\n \"@crates__unicode-ident-1.0.13//:unicode_ident\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"clone-impls\",\n \"default\",\n \"derive\",\n \"full\",\n \"parsing\",\n \"printing\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=syn\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.0.79\",\n)\n" } }, - "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_1_aarch64_72966d1b": { - "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", - "ruleClassName": "whl_library", + "crates__num-traits-0.2.19": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", "attributes": { - "dep_template": "@rules_python_publish_deps//{name}:{target}", - "experimental_target_platforms": [ - "cp311_linux_aarch64", - "cp311_linux_arm", - "cp311_linux_ppc", - "cp311_linux_s390x", - "cp311_linux_x86_64" + "patch_args": [ + "-p0" ], - "filename": "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", - "repo": "rules_python_publish_deps_311", - "requirement": "charset-normalizer==3.0.1", - "sha256": "72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a", + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841", + "type": "tar.gz", "urls": [ - "https://files.pythonhosted.org/packages/01/ff/9ee4a44e8c32fe96dfc12daa42f29294608a55eadc88f327939327fb20fb/charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl" - ] + "https://static.crates.io/crates/num-traits/0.2.19/download" + ], + "strip_prefix": "num-traits-0.2.19", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_build_script\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"num_traits\",\n deps = [\n \"@crates__num-traits-0.2.19//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=num-traits\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.2.19\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__autocfg-1.4.0//:autocfg\",\n ],\n edition = \"2021\",\n pkg_name = \"num-traits\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=num-traits\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.2.19\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, - "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_573f6eac": { - "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", - "ruleClassName": "whl_library", + "crates__rustversion-1.0.17": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", "attributes": { - "dep_template": "@rules_python_publish_deps//{name}:{target}", - "experimental_target_platforms": [ - "cp311_osx_aarch64", - "cp311_osx_x86_64", - "cp311_windows_x86_64" + "patch_args": [ + "-p0" ], - "filename": "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", - "repo": "rules_python_publish_deps_311", - "requirement": "charset-normalizer==3.3.2", - "sha256": "573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6", + "type": "tar.gz", "urls": [ - "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl" - ] + "https://static.crates.io/crates/rustversion/1.0.17/download" + ], + "strip_prefix": "rustversion-1.0.17", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_build_script\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_proc_macro(\n name = \"rustversion\",\n deps = [\n \"@crates__rustversion-1.0.17//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=rustversion\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.17\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n crate_name = \"build_script_build\",\n crate_root = \"build/build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2018\",\n pkg_name = \"rustversion\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=rustversion\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.17\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, - "rules_python_publish_deps_311_pycparser_sdist_e644fdec": { - "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", - "ruleClassName": "whl_library", + "crates__proc-macro2-1.0.86": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", "attributes": { - "dep_template": "@rules_python_publish_deps//{name}:{target}", - "experimental_target_platforms": [ - "cp311_linux_aarch64", - "cp311_linux_arm", - "cp311_linux_ppc", - "cp311_linux_s390x", - "cp311_linux_x86_64" + "patch_args": [ + "-p0" ], - "filename": "pycparser-2.21.tar.gz", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", - "repo": "rules_python_publish_deps_311", - "requirement": "pycparser==2.21", - "sha256": "e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206", + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77", + "type": "tar.gz", "urls": [ - "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz" - ] + "https://static.crates.io/crates/proc-macro2/1.0.86/download" + ], + "strip_prefix": "proc-macro2-1.0.86", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_build_script\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"proc_macro2\",\n deps = [\n \"@crates__proc-macro2-1.0.86//:build_script_build\",\n \"@crates__unicode-ident-1.0.13//:unicode_ident\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=proc-macro2\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.86\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n crate_features = [\n \"proc-macro\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"proc-macro2\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=proc-macro2\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.86\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, - "rules_python_publish_deps_311_bleach_sdist_1a1a85c1": { - "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", - "ruleClassName": "whl_library", + "crates__regex-syntax-0.8.5": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", "attributes": { - "dep_template": "@rules_python_publish_deps//{name}:{target}", - "experimental_target_platforms": [ - "cp311_linux_aarch64", - "cp311_linux_arm", - "cp311_linux_ppc", - "cp311_linux_s390x", - "cp311_linux_x86_64", - "cp311_osx_aarch64", - "cp311_osx_x86_64", - "cp311_windows_x86_64" + "patch_args": [ + "-p0" ], - "filename": "bleach-6.0.0.tar.gz", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", - "repo": "rules_python_publish_deps_311", - "requirement": "bleach==6.0.0", - "sha256": "1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c", + "type": "tar.gz", "urls": [ - "https://files.pythonhosted.org/packages/7e/e6/d5f220ca638f6a25557a611860482cb6e54b2d97f0332966b1b005742e1f/bleach-6.0.0.tar.gz" - ] + "https://static.crates.io/crates/regex-syntax/0.8.5/download" + ], + "strip_prefix": "regex-syntax-0.8.5", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# Run 'cargo update [--workspace]'\n###############################################################################\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nrust_library(\n name = \"regex_syntax\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n \"unicode\",\n \"unicode-age\",\n \"unicode-bool\",\n \"unicode-case\",\n \"unicode-gencat\",\n \"unicode-perl\",\n \"unicode-script\",\n \"unicode-segment\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex-syntax\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n \"@rules_rust//rust/platform:aarch64-fuchsia\": [],\n \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n \"@rules_rust//rust/platform:i686-linux-android\": [],\n \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasi\": [],\n \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n \"@rules_rust//rust/platform:x86_64-fuchsia\": [],\n \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.8.5\",\n)\n" } } }, + "moduleExtensionMetadata": { + "useAllRepos": "NO", + "reproducible": false + }, "recordedRepoMappingEntries": [ [ "bazel_features~", @@ -7241,114 +8326,34 @@ "bazel_features~~version_extension~bazel_features_version" ], [ - "rules_python~", + "rules_rust~", "bazel_features", "bazel_features~" ], [ - "rules_python~", + "rules_rust~", "bazel_skylib", "bazel_skylib~" ], [ - "rules_python~", + "rules_rust~", "bazel_tools", "bazel_tools" ], [ - "rules_python~", - "pypi__build", - "rules_python~~internal_deps~pypi__build" - ], - [ - "rules_python~", - "pypi__click", - "rules_python~~internal_deps~pypi__click" - ], - [ - "rules_python~", - "pypi__colorama", - "rules_python~~internal_deps~pypi__colorama" - ], - [ - "rules_python~", - "pypi__importlib_metadata", - "rules_python~~internal_deps~pypi__importlib_metadata" - ], - [ - "rules_python~", - "pypi__installer", - "rules_python~~internal_deps~pypi__installer" - ], - [ - "rules_python~", - "pypi__more_itertools", - "rules_python~~internal_deps~pypi__more_itertools" - ], - [ - "rules_python~", - "pypi__packaging", - "rules_python~~internal_deps~pypi__packaging" - ], - [ - "rules_python~", - "pypi__pep517", - "rules_python~~internal_deps~pypi__pep517" - ], - [ - "rules_python~", - "pypi__pip", - "rules_python~~internal_deps~pypi__pip" - ], - [ - "rules_python~", - "pypi__pip_tools", - "rules_python~~internal_deps~pypi__pip_tools" - ], - [ - "rules_python~", - "pypi__pyproject_hooks", - "rules_python~~internal_deps~pypi__pyproject_hooks" - ], - [ - "rules_python~", - "pypi__setuptools", - "rules_python~~internal_deps~pypi__setuptools" - ], - [ - "rules_python~", - "pypi__tomli", - "rules_python~~internal_deps~pypi__tomli" - ], - [ - "rules_python~", - "pypi__wheel", - "rules_python~~internal_deps~pypi__wheel" - ], - [ - "rules_python~", - "pypi__zipp", - "rules_python~~internal_deps~pypi__zipp" - ], - [ - "rules_python~", - "pythons_hub", - "rules_python~~python~pythons_hub" - ], - [ - "rules_python~~python~pythons_hub", - "python_3_11_host", - "rules_python~~python~python_3_11_host" + "rules_rust~", + "rules_cc", + "rules_cc~" ], [ - "rules_python~~python~pythons_hub", - "python_3_12_3_host", - "rules_python~~python~python_3_12_3_host" + "rules_rust~", + "rules_rust", + "rules_rust~" ], [ - "rules_python~~python~pythons_hub", - "python_3_8_12_host", - "rules_python~~python~python_3_8_12_host" + "rules_rust~", + "rust_host_tools", + "rules_rust~~rust_host_tools~rust_host_tools" ] ] } @@ -21088,34 +22093,6 @@ }, "recordedRepoMappingEntries": [] } - }, - "@@upb~//:non_module_deps.bzl%non_module_deps": { - "general": { - "bzlTransitiveDigest": "aGnO/HqVtCmRLEQWGCuKp7jwX+lCh/nc3/hI3clfwD8=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "utf8_range": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "urls": [ - "https://github.com/protocolbuffers/utf8_range/archive/de0b4a8ff9b5d4c98108bdfe723291a33c52c54f.zip" - ], - "strip_prefix": "utf8_range-de0b4a8ff9b5d4c98108bdfe723291a33c52c54f", - "sha256": "5da960e5e5d92394c809629a03af3c7709d2d3d0ca731dacb3a9fb4bf28f7702" - } - } - }, - "recordedRepoMappingEntries": [ - [ - "upb~", - "bazel_tools", - "bazel_tools" - ] - ] - } } } } diff --git a/Makefile b/Makefile index 7763b298ac3..d90d192945b 100644 --- a/Makefile +++ b/Makefile @@ -276,9 +276,11 @@ Pipfile.lock: echo "pipenv lock"; \ exit 1; \ fi; \ - ( SKIP_MAKEFILE_CALL=1 $(PIPENV) lock --python $(PYTHON_MAJOR_DOT_MINOR) ) || ( $(RM) -r .venv ; exit 1 ) \ + ( SKIP_MAKEFILE_CALL=1 $(PIPENV) lock --python $(PYTHON_MAJOR_DOT_MINOR) ) \ + || ( $(RM) -r .venv ; exit 1 ) \ + && ( bazel run //cmk:requirements.update ) \ fi \ - ) $(LOCK_FD)>$(LOCK_PATH); \ + ) $(LOCK_FD)>$(LOCK_PATH) # .venv is PHONY because the dependencies are resolved now in the make_venv script diff --git a/Pipfile b/Pipfile index 8e5f251b7a8..aa3c137e541 100644 --- a/Pipfile +++ b/Pipfile @@ -40,15 +40,12 @@ py-import-cycles = "*" # used in tests/Makefile pylint = "*" # used by test/Makefile's test-pylint target pylint-pydantic = "*" pylsp-mypy = "*" # mypy plugin for python-lsp-server -python-lsp-ruff = "*" # ruff plugin for python-lsp-server pymongo = "<4.9" # used by mk_mongodb agent plugin # 4.9 has no pymongo.database.Database anymore pytest = "*" pytest-cov = "*" # used (indirectly) by test/Makefile's test-unit-coverage-html target, see comment there pytest-html = "*" # used to generate HTML reports for test suites pytest-mock = "*" # used by quite a few unit/integration tests via the mocker fixture pytest-random-order = "*" # used to test resiliency -pytest-repeat = "*" # used to test resiliency -pytest-testmon = "*" # used for pre-commit checking via .pre-commit-config.yaml pytest-xdist = "*" # used to limit number of procs in e2e tests pytest-check = "*" # used to queue failed assertions and continue test execution python-lsp-server = "*" # Note: There are extras, but the default seems sensible. @@ -93,6 +90,7 @@ uvicorn = "*" webtest = "*" # used by WSGI based tests [packages] +setuptools = "<=70.3.0" # See https://github.com/pypa/setuptools/issues/4487#issuecomment-2237487845 for context setuptools-scm = "==4.1.2" # needed by various setup.py six = "==1.16.0" # direct dependency + needed by python-dateutil, vcrpy, python-active-directory python-dateutil = "~=2.9.0" # direct dependency diff --git a/Pipfile.lock b/Pipfile.lock index 87de0effe2a..f08ed15ca68 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "debae46975a3750c8d0e8f4a0217207e551d6058774558f52a7927c66b1d3cb8" + "sha256": "1688656db561a5b89c816db0c7a998f86b87e7ea7936c6dc8ae0e111fc3c7a11" }, "pipfile-spec": 6, "requires": { @@ -18,108 +18,108 @@ "default": { "aiohappyeyeballs": { "hashes": [ - "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2", - "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd" + "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", + "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572" ], "markers": "python_version >= '3.8'", - "version": "==2.4.0" + "version": "==2.4.3" }, "aiohttp": { "hashes": [ - "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277", - "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1", - "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe", - "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb", - "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca", - "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91", - "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972", - "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a", - "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3", - "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa", - "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77", - "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b", - "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8", - "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599", - "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc", - "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf", - "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511", - "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699", - "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487", - "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987", - "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff", - "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db", - "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022", - "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce", - "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a", - "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5", - "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7", - "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820", - "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf", - "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e", - "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf", - "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5", - "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6", - "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6", - "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91", - "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3", - "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a", - "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d", - "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088", - "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc", - "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f", - "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75", - "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471", - "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e", - "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697", - "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092", - "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69", - "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3", - "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32", - "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589", - "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178", - "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92", - "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2", - "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e", - "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058", - "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857", - "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1", - "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6", - "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22", - "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0", - "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b", - "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57", - "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f", - "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e", - "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16", - "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1", - "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f", - "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6", - "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04", - "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae", - "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d", - "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b", - "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f", - "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862", - "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689", - "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c", - "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683", - "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef", - "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f", - "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12", - "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73", - "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061", - "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072", - "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11", - "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691", - "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77", - "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385", - "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172", - "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569", - "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f", - "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5" - ], - "markers": "python_version >= '3.8'", - "version": "==3.10.5" + "sha256:02d1d6610588bcd743fae827bd6f2e47e0d09b346f230824b4c6fb85c6065f9c", + "sha256:03690541e4cc866eef79626cfa1ef4dd729c5c1408600c8cb9e12e1137eed6ab", + "sha256:0bc059ecbce835630e635879f5f480a742e130d9821fbe3d2f76610a6698ee25", + "sha256:0c21c82df33b264216abffff9f8370f303dab65d8eee3767efbbd2734363f677", + "sha256:1298b854fd31d0567cbb916091be9d3278168064fca88e70b8468875ef9ff7e7", + "sha256:1321658f12b6caffafdc35cfba6c882cb014af86bef4e78c125e7e794dfb927b", + "sha256:143b0026a9dab07a05ad2dd9e46aa859bffdd6348ddc5967b42161168c24f857", + "sha256:16e6a51d8bc96b77f04a6764b4ad03eeef43baa32014fce71e882bd71302c7e4", + "sha256:172ad884bb61ad31ed7beed8be776eb17e7fb423f1c1be836d5cb357a096bf12", + "sha256:17c272cfe7b07a5bb0c6ad3f234e0c336fb53f3bf17840f66bd77b5815ab3d16", + "sha256:1a0ee6c0d590c917f1b9629371fce5f3d3f22c317aa96fbdcce3260754d7ea21", + "sha256:2746d8994ebca1bdc55a1e998feff4e94222da709623bb18f6e5cfec8ec01baf", + "sha256:2914caa46054f3b5ff910468d686742ff8cff54b8a67319d75f5d5945fd0a13d", + "sha256:2bbf94d4a0447705b7775417ca8bb8086cc5482023a6e17cdc8f96d0b1b5aba6", + "sha256:2bd9f3eac515c16c4360a6a00c38119333901b8590fe93c3257a9b536026594d", + "sha256:2c33fa6e10bb7ed262e3ff03cc69d52869514f16558db0626a7c5c61dde3c29f", + "sha256:2d37f4718002863b82c6f391c8efd4d3a817da37030a29e2682a94d2716209de", + "sha256:3668d0c2a4d23fb136a753eba42caa2c0abbd3d9c5c87ee150a716a16c6deec1", + "sha256:36d4fba838be5f083f5490ddd281813b44d69685db910907636bc5dca6322316", + "sha256:40ff5b7660f903dc587ed36ef08a88d46840182d9d4b5694e7607877ced698a1", + "sha256:42775de0ca04f90c10c5c46291535ec08e9bcc4756f1b48f02a0657febe89b10", + "sha256:482c85cf3d429844396d939b22bc2a03849cb9ad33344689ad1c85697bcba33a", + "sha256:4e6cb75f8ddd9c2132d00bc03c9716add57f4beff1263463724f6398b813e7eb", + "sha256:4edc3fd701e2b9a0d605a7b23d3de4ad23137d23fc0dbab726aa71d92f11aaaf", + "sha256:4fd16b30567c5b8e167923be6e027eeae0f20cf2b8a26b98a25115f28ad48ee0", + "sha256:5002a02c17fcfd796d20bac719981d2fca9c006aac0797eb8f430a58e9d12431", + "sha256:51d0a4901b27272ae54e42067bc4b9a90e619a690b4dc43ea5950eb3070afc32", + "sha256:558b3d223fd631ad134d89adea876e7fdb4c93c849ef195049c063ada82b7d08", + "sha256:5c070430fda1a550a1c3a4c2d7281d3b8cfc0c6715f616e40e3332201a253067", + "sha256:5f392ef50e22c31fa49b5a46af7f983fa3f118f3eccb8522063bee8bfa6755f8", + "sha256:60555211a006d26e1a389222e3fab8cd379f28e0fbf7472ee55b16c6c529e3a6", + "sha256:608cecd8d58d285bfd52dbca5b6251ca8d6ea567022c8a0eaae03c2589cd9af9", + "sha256:60ad5b8a7452c0f5645c73d4dad7490afd6119d453d302cd5b72b678a85d6044", + "sha256:63649309da83277f06a15bbdc2a54fbe75efb92caa2c25bb57ca37762789c746", + "sha256:6ebdc3b3714afe1b134b3bbeb5f745eed3ecbcff92ab25d80e4ef299e83a5465", + "sha256:6f3c6648aa123bcd73d6f26607d59967b607b0da8ffcc27d418a4b59f4c98c7c", + "sha256:7003f33f5f7da1eb02f0446b0f8d2ccf57d253ca6c2e7a5732d25889da82b517", + "sha256:776e9f3c9b377fcf097c4a04b241b15691e6662d850168642ff976780609303c", + "sha256:85711eec2d875cd88c7eb40e734c4ca6d9ae477d6f26bd2b5bb4f7f60e41b156", + "sha256:87d1e4185c5d7187684d41ebb50c9aeaaaa06ca1875f4c57593071b0409d2444", + "sha256:8a3f063b41cc06e8d0b3fcbbfc9c05b7420f41287e0cd4f75ce0a1f3d80729e6", + "sha256:8b3fb28a9ac8f2558760d8e637dbf27aef1e8b7f1d221e8669a1074d1a266bb2", + "sha256:8bd9125dd0cc8ebd84bff2be64b10fdba7dc6fd7be431b5eaf67723557de3a31", + "sha256:8be1a65487bdfc285bd5e9baf3208c2132ca92a9b4020e9f27df1b16fab998a9", + "sha256:8cc0d13b4e3b1362d424ce3f4e8c79e1f7247a00d792823ffd640878abf28e56", + "sha256:8d9d10d10ec27c0d46ddaecc3c5598c4db9ce4e6398ca872cdde0525765caa2f", + "sha256:8debb45545ad95b58cc16c3c1cc19ad82cffcb106db12b437885dbee265f0ab5", + "sha256:91aa966858593f64c8a65cdefa3d6dc8fe3c2768b159da84c1ddbbb2c01ab4ef", + "sha256:9331dd34145ff105177855017920dde140b447049cd62bb589de320fd6ddd582", + "sha256:99f9678bf0e2b1b695e8028fedac24ab6770937932eda695815d5a6618c37e04", + "sha256:9fdf5c839bf95fc67be5794c780419edb0dbef776edcfc6c2e5e2ffd5ee755fa", + "sha256:a14e4b672c257a6b94fe934ee62666bacbc8e45b7876f9dd9502d0f0fe69db16", + "sha256:a19caae0d670771ea7854ca30df76f676eb47e0fd9b2ee4392d44708f272122d", + "sha256:a35ed3d03910785f7d9d6f5381f0c24002b2b888b298e6f941b2fc94c5055fcd", + "sha256:a61df62966ce6507aafab24e124e0c3a1cfbe23c59732987fc0fd0d71daa0b88", + "sha256:a6e00c8a92e7663ed2be6fcc08a2997ff06ce73c8080cd0df10cc0321a3168d7", + "sha256:ac3196952c673822ebed8871cf8802e17254fff2a2ed4835d9c045d9b88c5ec7", + "sha256:ac74e794e3aee92ae8f571bfeaa103a141e409863a100ab63a253b1c53b707eb", + "sha256:ad3675c126f2a95bde637d162f8231cff6bc0bc9fbe31bd78075f9ff7921e322", + "sha256:aeebd3061f6f1747c011e1d0b0b5f04f9f54ad1a2ca183e687e7277bef2e0da2", + "sha256:ba1a599255ad6a41022e261e31bc2f6f9355a419575b391f9655c4d9e5df5ff5", + "sha256:bbdb8def5268f3f9cd753a265756f49228a20ed14a480d151df727808b4531dd", + "sha256:c2555e4949c8d8782f18ef20e9d39730d2656e218a6f1a21a4c4c0b56546a02e", + "sha256:c2695c61cf53a5d4345a43d689f37fc0f6d3a2dc520660aec27ec0f06288d1f9", + "sha256:c2b627d3c8982691b06d89d31093cee158c30629fdfebe705a91814d49b554f8", + "sha256:c46131c6112b534b178d4e002abe450a0a29840b61413ac25243f1291613806a", + "sha256:c54dc329cd44f7f7883a9f4baaefe686e8b9662e2c6c184ea15cceee587d8d69", + "sha256:c7d7cafc11d70fdd8801abfc2ff276744ae4cb39d8060b6b542c7e44e5f2cfc2", + "sha256:cb0b2d5d51f96b6cc19e6ab46a7b684be23240426ae951dcdac9639ab111b45e", + "sha256:d15a29424e96fad56dc2f3abed10a89c50c099f97d2416520c7a543e8fddf066", + "sha256:d1f5c9169e26db6a61276008582d945405b8316aae2bb198220466e68114a0f5", + "sha256:d271f770b52e32236d945911b2082f9318e90ff835d45224fa9e28374303f729", + "sha256:d646fdd74c25bbdd4a055414f0fe32896c400f38ffbdfc78c68e62812a9e0257", + "sha256:d6e395c3d1f773cf0651cd3559e25182eb0c03a2777b53b4575d8adc1149c6e9", + "sha256:d7c071235a47d407b0e93aa6262b49422dbe48d7d8566e1158fecc91043dd948", + "sha256:d97273a52d7f89a75b11ec386f786d3da7723d7efae3034b4dda79f6f093edc1", + "sha256:dcf354661f54e6a49193d0b5653a1b011ba856e0b7a76bda2c33e4c6892f34ea", + "sha256:e3e7fabedb3fe06933f47f1538df7b3a8d78e13d7167195f51ca47ee12690373", + "sha256:e525b69ee8a92c146ae5b4da9ecd15e518df4d40003b01b454ad694a27f498b5", + "sha256:e709d6ac598c5416f879bb1bae3fd751366120ac3fa235a01de763537385d036", + "sha256:e83dfefb4f7d285c2d6a07a22268344a97d61579b3e0dce482a5be0251d672ab", + "sha256:e86260b76786c28acf0b5fe31c8dca4c2add95098c709b11e8c35b424ebd4f5b", + "sha256:e883b61b75ca6efc2541fcd52a5c8ccfe288b24d97e20ac08fdf343b8ac672ea", + "sha256:f0a44bb40b6aaa4fb9a5c1ee07880570ecda2065433a96ccff409c9c20c1624a", + "sha256:f82ace0ec57c94aaf5b0e118d4366cff5889097412c75aa14b4fd5fc0c44ee3e", + "sha256:f9ca09414003c0e96a735daa1f071f7d7ed06962ef4fa29ceb6c80d06696d900", + "sha256:fa430b871220dc62572cef9c69b41e0d70fcb9d486a4a207a5de4c1f25d82593", + "sha256:fc262c3df78c8ff6020c782d9ce02e4bcffe4900ad71c0ecdad59943cba54442", + "sha256:fcd546782d03181b0b1d20b43d612429a90a68779659ba8045114b867971ab71", + "sha256:fd4ceeae2fb8cabdd1b71c82bfdd39662473d3433ec95b962200e9e752fb70d0", + "sha256:fec5fac7aea6c060f317f07494961236434928e6f4374e170ef50b3001e14581" + ], + "markers": "python_version >= '3.8'", + "version": "==3.10.9" }, "aiosignal": { "hashes": [ @@ -240,21 +240,21 @@ }, "boto3": { "hashes": [ - "sha256:97fcc1a14cbc759e4ba9535ced703a99fcf652c9c4b8dfcd06f292c80551684b", - "sha256:be7807f30f26d6c0057e45cfd09dad5968e664488bf4f9138d0bb7a0f6d8ed40" + "sha256:385ca77bf8ea4ab2d97f6e2435bdb29f77d9301e2f7ac796c2f465753c2adf3c", + "sha256:470d981583885859fed2fd1c185eeb01cc03e60272d499bafe41b12625b158c8" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.24" + "version": "==1.35.37" }, "botocore": { "hashes": [ - "sha256:1e59b0f14f4890c4f70bd6a58a634b9464bed1c4c6171f87c8795d974ade614b", - "sha256:eb9ccc068255cc3d24c36693fda6aec7786db05ae6c2b13bcba66dce6a13e2e3" + "sha256:64f965d4ba7adb8d79ce044c3aef7356e05dd74753cf7e9115b80f477845d920", + "sha256:b2b4d29bafd95b698344f2f0577bb67064adbf1735d8a0e3c7473daa59c23ba6" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.24" + "version": "==1.35.37" }, "cached-property": { "hashes": [ @@ -362,99 +362,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "click": { "hashes": [ @@ -564,11 +579,11 @@ }, "dnspython": { "hashes": [ - "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", - "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc" + "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", + "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1" ], - "markers": "python_version >= '3.8'", - "version": "==2.6.1" + "markers": "python_version >= '3.9'", + "version": "==2.7.0" }, "docstring-parser": { "hashes": [ @@ -736,20 +751,20 @@ "grpc" ], "hashes": [ - "sha256:ef0591ef03c30bb83f79b3d0575c3f31219001fc9c5cf37024d08310aeffed8a", - "sha256:f74dff1889ba291a4b76c5079df0711810e2d9da81abfdc99957bc961c1eb28f" + "sha256:4a152fd11a9f774ea606388d423b68aa7e6d6a0ffe4c8266f74979613ec09f81", + "sha256:6869eacb2a37720380ba5898312af79a4d30b8bca1548fb4093e0697dc4bdf5d" ], "markers": "python_version >= '3.7'", - "version": "==2.20.0" + "version": "==2.21.0" }, "google-api-python-client": { "hashes": [ - "sha256:41f671be10fa077ee5143ee9f0903c14006d39dc644564f4e044ae96b380bf68", - "sha256:b1e62c9889c5ef6022f11d30d7ef23dc55100300f0e8aaf8aa09e8e92540acad" + "sha256:1a5232e9cfed8c201799d9327e4d44dc7ea7daa3c6e1627fca41aa201539c0da", + "sha256:b9d68c6b14ec72580d66001bd33c5816b78e2134b93ccc5cf8f624516b561750" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.146.0" + "version": "==2.149.0" }, "google-auth": { "hashes": [ @@ -830,55 +845,64 @@ }, "grpcio": { "hashes": [ - "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e", - "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce", - "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8", - "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d", - "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858", - "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0", - "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a", - "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45", - "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef", - "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2", - "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac", - "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd", - "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1", - "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce", - "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492", - "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e", - "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb", - "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44", - "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb", - "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759", - "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e", - "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761", - "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26", - "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791", - "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c", - "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60", - "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df", - "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a", - "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3", - "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734", - "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f", - "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083", - "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524", - "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d", - "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a", - "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0", - "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb", - "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503", - "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815", - "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22", - "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2", - "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c", - "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d", - "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b", - "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c", - "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9" - ], - "markers": "python_version >= '3.8'", - "version": "==1.66.1" + "sha256:02697eb4a5cbe5a9639f57323b4c37bcb3ab2d48cec5da3dc2f13334d72790dd", + "sha256:03b0b307ba26fae695e067b94cbb014e27390f8bc5ac7a3a39b7723fed085604", + "sha256:05bc2ceadc2529ab0b227b1310d249d95d9001cd106aa4d31e8871ad3c428d73", + "sha256:06de8ec0bd71be123eec15b0e0d457474931c2c407869b6c349bd9bed4adbac3", + "sha256:0be4e0490c28da5377283861bed2941d1d20ec017ca397a5df4394d1c31a9b50", + "sha256:12fda97ffae55e6526825daf25ad0fa37483685952b5d0f910d6405c87e3adb6", + "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34", + "sha256:2018b053aa15782db2541ca01a7edb56a0bf18c77efed975392583725974b249", + "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75", + "sha256:2335c58560a9e92ac58ff2bc5649952f9b37d0735608242973c7a8b94a6437d8", + "sha256:31fd163105464797a72d901a06472860845ac157389e10f12631025b3e4d0453", + "sha256:38b68498ff579a3b1ee8f93a05eb48dc2595795f2f62716e797dc24774c1aaa8", + "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d", + "sha256:3ed71e81782966ffead60268bbda31ea3f725ebf8aa73634d5dda44f2cf3fb9c", + "sha256:45a3d462826f4868b442a6b8fdbe8b87b45eb4f5b5308168c156b21eca43f61c", + "sha256:49f0ca7ae850f59f828a723a9064cadbed90f1ece179d375966546499b8a2c9c", + "sha256:4e504572433f4e72b12394977679161d495c4c9581ba34a88d843eaf0f2fbd39", + "sha256:4ea1d062c9230278793820146c95d038dc0f468cbdd172eec3363e42ff1c7d01", + "sha256:563588c587b75c34b928bc428548e5b00ea38c46972181a4d8b75ba7e3f24231", + "sha256:6001e575b8bbd89eee11960bb640b6da6ae110cf08113a075f1e2051cc596cae", + "sha256:66a0cd8ba6512b401d7ed46bb03f4ee455839957f28b8d61e7708056a806ba6a", + "sha256:6851de821249340bdb100df5eacfecfc4e6075fa85c6df7ee0eb213170ec8e5d", + "sha256:728bdf36a186e7f51da73be7f8d09457a03061be848718d0edf000e709418987", + "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a", + "sha256:73fc8f8b9b5c4a03e802b3cd0c18b2b06b410d3c1dcbef989fdeb943bd44aff7", + "sha256:78fa51ebc2d9242c0fc5db0feecc57a9943303b46664ad89921f5079e2e4ada7", + "sha256:7b2c86457145ce14c38e5bf6bdc19ef88e66c5fee2c3d83285c5aef026ba93b3", + "sha256:7d69ce1f324dc2d71e40c9261d3fdbe7d4c9d60f332069ff9b2a4d8a257c7b2b", + "sha256:802d84fd3d50614170649853d121baaaa305de7b65b3e01759247e768d691ddf", + "sha256:80fd702ba7e432994df208f27514280b4b5c6843e12a48759c9255679ad38db8", + "sha256:8ac475e8da31484efa25abb774674d837b343afb78bb3bcdef10f81a93e3d6bf", + "sha256:950da58d7d80abd0ea68757769c9db0a95b31163e53e5bb60438d263f4bed7b7", + "sha256:99a641995a6bc4287a6315989ee591ff58507aa1cbe4c2e70d88411c4dcc0839", + "sha256:9c3a99c519f4638e700e9e3f83952e27e2ea10873eecd7935823dab0c1c9250e", + "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b", + "sha256:a18e20d8321c6400185b4263e27982488cb5cdd62da69147087a76a24ef4e7e3", + "sha256:a917d26e0fe980b0ac7bfcc1a3c4ad6a9a4612c911d33efb55ed7833c749b0ee", + "sha256:a9539f01cb04950fd4b5ab458e64a15f84c2acc273670072abe49a3f29bbad54", + "sha256:ad2efdbe90c73b0434cbe64ed372e12414ad03c06262279b104a029d1889d13e", + "sha256:b672abf90a964bfde2d0ecbce30f2329a47498ba75ce6f4da35a2f4532b7acbc", + "sha256:bbd27c24a4cc5e195a7f56cfd9312e366d5d61b86e36d46bbe538457ea6eb8dd", + "sha256:c400ba5675b67025c8a9f48aa846f12a39cf0c44df5cd060e23fda5b30e9359d", + "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed", + "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7", + "sha256:ce89f5876662f146d4c1f695dda29d4433a5d01c8681fbd2539afff535da14d4", + "sha256:d25a14af966438cddf498b2e338f88d1c9706f3493b1d73b93f695c99c5f0e2a", + "sha256:d8d4732cc5052e92cea2f78b233c2e2a52998ac40cd651f40e398893ad0d06ec", + "sha256:d9a9724a156c8ec6a379869b23ba3323b7ea3600851c91489b871e375f710bc8", + "sha256:e636ce23273683b00410f1971d209bf3689238cf5538d960adc3cdfe80dd0dbd", + "sha256:e88264caad6d8d00e7913996030bac8ad5f26b7411495848cc218bd3a9040b6c", + "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46", + "sha256:fb57870449dfcfac428afbb5a877829fcb0d6db9d9baa1148705739e9083880e", + "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf", + "sha256:fe96281713168a3270878255983d2cb1a97e034325c8c2c25169a69289d3ecfa", + "sha256:ff1f7882e56c40b0d33c4922c15dfa30612f05fb785074a012f7cda74d1c3679" + ], + "markers": "python_version >= '3.8'", + "version": "==1.66.2" }, "grpcio-status": { "hashes": [ @@ -889,32 +913,33 @@ }, "gssapi": { "hashes": [ - "sha256:19c373b3ba63ce19cd3163aa1495635e3d01b0de6cc4ff1126095eded1df6e01", - "sha256:338db18612e3e6ed64e92b6d849242a535fdc98b365f21122992fb8cae737617", - "sha256:37f1a8046d695f2c9b8d640a6e385780d3945c0741571ed6fee6f94c31e431dc", - "sha256:3a3f63105f39c4af29ffc8f7b6542053d87fe9d63010c689dd9a9f5571facb8e", - "sha256:465c6788f2ac6ef7c738394ba8fde1ede6004e5721766f386add63891d8c90af", - "sha256:4d9ed83f2064cda60aad90e6840ae282096801b2c814b8cbd390bf0df4635aab", - "sha256:4e4a83e9b275fe69b5d40be6d5479889866b80333a12c51a9243f2712d4f0554", - "sha256:5731c5b40ecc3116cfe7fb7e1d1e128583ec8b3df1e68bf8cd12073160793acd", - "sha256:5b4bf84d0a6d7779a4bf11dacfd3db57ae02dd53562e2aeadac4219a68eaee07", - "sha256:791e44f7bea602b8e3da1ec56fbdb383b8ee3326fdeb736f904c2aa9af13a67d", - "sha256:7d91fe6e2a5c89b32102ea8e374b8ae13b9031d43d7b55f3abc1f194ddce820d", - "sha256:8d57d67547e18f4e44a688bfb20abbf176d1b8df547da2b31c3f2df03cfdc269", - "sha256:8fb8ee70458f47b51ed881a6881f30b187c987c02af16cc0fff0079255d4d465", - "sha256:8fdb1ff130cee49bc865ec1624dee8cf445cd6c6e93b04bffef2c6f363a60cb9", - "sha256:aa3c8d0b1526f52559552bb2c9d2d6be013d76a8e5db00b39a1db5727e93b0b0", - "sha256:b031c0f186ab4275186da385b2c7470dd47c9b27522cb3b753757c9ac4bebf11", - "sha256:b03d6b30f1fcd66d9a688b45a97e302e4dd3f1386d5c333442731aec73cdb409", - "sha256:ca6ceb17fc15eda2a69f2e8c6cf10d11e2edb32832255e5d4c65b21b6db4680a", - "sha256:d5b28237afc0668046934792756dd4b6b7e957b0d95a608d02f296734a2819ad", - "sha256:e2bb081f2db2111377effe7d40ba23f9a87359b9d2f4881552b731e9da88b36b", - "sha256:e40efc88ccefefd6142f8c47b8af498731938958b808bad49990442a91f45160", - "sha256:e556878da197ad115a566d36e46a8082d0079731d9c24d1ace795132d725ff2a", - "sha256:edc8ef3a9e397dbe18bb6016f8e2209969677b534316d20bb139da2865a38efe", - "sha256:ee74b9211c977b9181ff4652d886d7712c9a221560752a35393b58e5ea07887a" - ], - "version": "==1.8.3" + "sha256:060b58b455d29ab8aca74770e667dca746264bee660ac5b6a7a17476edc2c0b8", + "sha256:10134db0cf01bd7d162acb445762dbcc58b5c772a613e17c46cf8ad956c4dfec", + "sha256:11c9fe066edb0fa0785697eb0cecf2719c7ad1d9f2bf27be57b647a617bcfaa5", + "sha256:11e9b92cef11da547fc8c210fa720528fd854038504103c1b15ae2a89dce5fcd", + "sha256:14a1ae12fdf1e4c8889206195ba1843de09fe82587fa113112887cd5894587c6", + "sha256:1a5786bd9fcf435bd0c87dc95ae99ad68cefcc2bcc80c71fef4cb0ccdfb40f1e", + "sha256:261e00ac426d840055ddb2199f4989db7e3ce70fa18b1538f53e392b4823e8f1", + "sha256:2a9c745255e3a810c3e8072e267b7b302de0705f8e9a0f2c5abc92fe12b9475e", + "sha256:2bddd1cc0c9859c5e0fd96d4d88eb67bd498fdbba45b14cdccfe10bfd329479f", + "sha256:59e1a1a9a6c5dc430dc6edfcf497f5ca00cf417015f781c9fac2e85652cd738f", + "sha256:5b2a3c0a9beb895942d4b8e31f515e52c17026e55aeaa81ee0df9bbfdac76098", + "sha256:67d9be5e34403e47fb5749d5a1ad4e5a85b568e6a9add1695edb4a5b879f7560", + "sha256:6c5f8a549abd187687440ec0b72e5b679d043d620442b3637d31aa2766b27cbe", + "sha256:a2e43f50450e81fe855888c53df70cdd385ada979db79463b38031710a12acd9", + "sha256:a81f30cde21031e7b1f8194a3eea7285e39e551265e7744edafd06eadc1c95bc", + "sha256:b66a98827fbd2864bf8993677a039d7ba4a127ca0d2d9ed73e0ef4f1baa7fd7f", + "sha256:b74031c70864d04864b7406c818f41be0c1637906fb9654b06823bcc79f151dc", + "sha256:c0e378d62b2fc352ca0046030cda5911d808a965200f612fdd1d74501b83e98f", + "sha256:c99959a9dd62358e370482f1691e936cb09adf9a69e3e10d4f6a097240e9fd28", + "sha256:cbc93fdadd5aab9bae594538b2128044b8c5cdd1424fe015a465d8a8a587411a", + "sha256:cea344246935b5337e6f8a69bb6cc45619ab3a8d74a29fcb0a39fd1e5843c89c", + "sha256:dfc1b4c0bfe9f539537601c9f187edc320daf488f694e50d02d0c1eb37416962", + "sha256:e28c7d45da68b7e36ed3fb3326744bfe39649f16e8eecd7b003b082206039c76", + "sha256:f2f3a46784d8127cc7ef10d3367dedcbe82899ea296710378ccc9b7cefe96f4c", + "sha256:f468fac8f3f5fca8f4d1ca19e3cd4d2e10bd91074e7285464b22715d13548afe" + ], + "version": "==1.9.0" }, "gunicorn": { "hashes": [ @@ -975,10 +1000,11 @@ }, "isodate": { "hashes": [ - "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", - "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" + "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", + "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6" ], - "version": "==0.6.1" + "markers": "python_version >= '3.7'", + "version": "==0.7.2" }, "itsdangerous": { "hashes": [ @@ -1062,20 +1088,21 @@ }, "krb5": { "hashes": [ - "sha256:0c89220495a1134dfe2d3566e31d7a44276ffdb20cda6f21257b311d41dae003", - "sha256:174595bfd053df9fa2f9721cf41865756b0f6a6bc992e995e92ac604471e4542", - "sha256:324e21ebde6e7e08bcacc9f4ec1d3494c692002a15ba097ea042272f475b7a18", - "sha256:3529bd2c0cb343fa3a0912445da5d307a1033c0a2686613449ba781f2e0b6a50", - "sha256:61f4c0bf6a14c865f7a96b6647ae36c115d708e0f0e949e591fb8da17eb4b3f5", - "sha256:62d803f989ea725479374447946f060fabcf74e956c4241b5e5316b2692e023a", - "sha256:712ba092fbe3a28ec18820bb1b1ed2cc1037b75c5c7033f970c6a8c97bbd1209", - "sha256:8f1419ad4c4052f687aafd8ed0497de3e10905d7c4bfd0645d02fd63e24ab4b8", - "sha256:c9cca6b40b98de2cfa715fa306578c63a9b7cb6f5b70881c47aaef4f93817991", - "sha256:ce9d85d485cdaea78299fb2944871b92d1deb84f9e0d964411dce8e3e4039db7", - "sha256:e34fd5976d6826e2f07bb23f7cd69a39b0efea13592ed42a9d4f3e07e40085c0", - "sha256:e5af9eb068eb947e7ea90d8029feb340aa7ccd1795645f109100a9ffa4a9bb69" + "sha256:4a32a35e425ce967f5577f9247a4e0a7d7e9a7e4527a778f7e0719aeb99e295f", + "sha256:66b286d9b4af42b4f5d2d561354cd44d891bee275768f1a2ac795ad4e8042dce", + "sha256:691e2eafd0b16cb1b209b2bd36888526ea7df24ce69ba39e72ccad281ffdadb2", + "sha256:69dc98084de5d693a97725f746d5af46299590bb9658c9fc32e4769a4a0f3079", + "sha256:6a308f2e17d151c395b24e6aec7bdff6a56fe3627a32042fc86d412398a92ddd", + "sha256:717e5b8b4d78268eefdba72a39cb0f93e5821a23e626ada3a45a583a2454d084", + "sha256:72d551ce659502f3a7c46c65cdd75af682c077d3d1a081d4d1bb478e14a55ffd", + "sha256:87a6d11bb182a289dd86086c19cba3f03a8108175e8e23292d3d2786ff3ecaeb", + "sha256:a33896483f6d415c4289e5cc108b0450a919bae0546a997f3352d982bd4e7c99", + "sha256:aead8037a4ef3f8a12db09fec32ff7f561399a35970c40bf62d748b834ac0eb5", + "sha256:dd954a76973ddc295756a5741e7fcfda70cfd31d965d45ed47422bffe5792b6f", + "sha256:f2cef1a7f78d331cc07b69cb8dc4cfb4a80f7b11dc2949f4e81f8cf86fd1836a", + "sha256:fa4ea45629e585787c0bcc455c7fbed7e09176031a7f9e7c87b9deaad401da36" ], - "version": "==0.6.0" + "version": "==0.7.0" }, "kubernetes": { "hashes": [ @@ -1148,69 +1175,70 @@ }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", + "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", + "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", + "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", + "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", + "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", + "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", + "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", + "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", + "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", + "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", + "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", + "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", + "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", + "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", + "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", + "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", + "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", + "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", + "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", + "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", + "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", + "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", + "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", + "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", + "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", + "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", + "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", + "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", + "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", + "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", + "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", + "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", + "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", + "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", + "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", + "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", + "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", + "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", + "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", + "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", + "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", + "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", + "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", + "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", + "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", + "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", + "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", + "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", + "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", + "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", + "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", + "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", + "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", + "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", + "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", + "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", + "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", + "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", + "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", + "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "markers": "python_version >= '3.9'", + "version": "==3.0.1" }, "marshmallow": { "hashes": [ @@ -1591,6 +1619,110 @@ "markers": "platform_system != 'Windows'", "version": "==2.10.1" }, + "propcache": { + "hashes": [ + "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", + "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", + "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", + "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb", + "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", + "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", + "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957", + "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68", + "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f", + "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798", + "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418", + "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6", + "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162", + "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", + "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", + "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", + "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", + "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", + "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", + "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8", + "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638", + "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", + "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", + "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", + "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", + "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", + "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", + "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", + "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", + "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89", + "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", + "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", + "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", + "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861", + "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", + "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", + "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", + "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", + "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", + "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", + "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", + "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563", + "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5", + "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", + "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9", + "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12", + "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", + "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", + "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", + "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9", + "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed", + "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", + "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90", + "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063", + "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", + "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6", + "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8", + "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", + "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", + "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", + "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", + "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", + "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df", + "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", + "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", + "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", + "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", + "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", + "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", + "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", + "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", + "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", + "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6", + "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562", + "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", + "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", + "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", + "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", + "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", + "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", + "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", + "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d", + "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04", + "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", + "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", + "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", + "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea", + "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", + "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1", + "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", + "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", + "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7", + "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", + "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d", + "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", + "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d", + "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", + "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504" + ], + "markers": "python_version >= '3.8'", + "version": "==0.2.0" + }, "proto-plus": { "hashes": [ "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445", @@ -1837,12 +1969,12 @@ }, "pypdf": { "hashes": [ - "sha256:5c536ec0f7af8e2f80eb32806964652a562b9abc5477b3c195e2b842725ce55b", - "sha256:67603e2e96cdf70e676564520933c017d450f16075b9966be5fee128812ace8c" + "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea", + "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db" ], "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.1" }, "pyprof2calltree": { "hashes": [ @@ -1948,11 +2080,11 @@ }, "python-multipart": { "hashes": [ - "sha256:2b06ad9e8d50c7a8db80e3b56dab590137b323410605af2be20d62a5f1ba1dc8", - "sha256:46eb3c6ce6fdda5fb1a03c7e11d490e407c6930a2703fe7aef4da71c374688fa" + "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb", + "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf" ], "markers": "python_version >= '3.8'", - "version": "==0.0.10" + "version": "==0.0.12" }, "python-snap7": { "hashes": [ @@ -2224,11 +2356,11 @@ }, "s3transfer": { "hashes": [ - "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6", - "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69" + "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", + "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" ], "markers": "python_version >= '3.8'", - "version": "==0.10.2" + "version": "==0.10.3" }, "setproctitle": { "hashes": [ @@ -2241,11 +2373,12 @@ }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5", + "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc" ], + "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "version": "==70.3.0" }, "setuptools-scm": { "hashes": [ @@ -2314,76 +2447,65 @@ }, "time-machine": { "hashes": [ - "sha256:008bd668d933b1a029c81805bcdc0132390c2545b103cf8e6709e3adbc37989d", - "sha256:014589d0edd4aa14f8d63985745565e8cbbe48461d6c004a96000b47f6b44e78", - "sha256:0302568338c8bd333ed0698231dbb781b70ead1a5579b4ac734b9bf88313229f", - "sha256:0630a32e9ebcf2fac3704365b31e271fef6eabd6fedfa404cd8dbd244f7fc84d", - "sha256:09fd839a321a92aa8183206c383b9725eaf4e0a28a70e4cb87db292b352eeefb", - "sha256:0b2d28daf4cabc698aafb12135525d87dc1f2f893cbd29a8a6fe0d8d36d1342c", - "sha256:1168eebd7af7e6e3e2fd378c16ca917b97dd81c89a1f1f9e1daa985c81699d90", - "sha256:18fc4740073e67071472c48355775ec6d1b93af5c675524b7de2474e0dcd8741", - "sha256:1dee3a0dd1866988c49a5d00564404db9bcdf49ca92f9c4e8b6c99609d64e698", - "sha256:245ef73f9927b7d4909d554a6a0284dbc5dee9730adea599e430b37c9e9fa203", - "sha256:29b988b1f09f2a083b12b6b054787b799ae91ee15bb0e9de3e48f880e4d68674", - "sha256:31af56399bf7c9ef76a3f7b6d9471dffa8f06ee373c194a374b69523f9061de9", - "sha256:3862dda89bdb05f9d521b08fdcb24b19a7dd9f559ae324f4301ba7a07b6eea64", - "sha256:3b177d334a35bf2ce103bfe4e0e416e4ee824dd33386ea73fa7491c17cc61897", - "sha256:3f7eadd820e792de33a9ec91f8178a2b9088e4e8b9a166953419ddc4ec5f7cfe", - "sha256:4428bdae507996aa3fdeb4727bca09e26306fa64a502e7335207252684516cbf", - "sha256:4601fe7a6b74c6fd9207e614d9db2a20dd4befd4d314677a0feac13a67189707", - "sha256:4cd9f057457d12604be18b623bcd5ae7d0b917ad66cb510ee1135d5f123666e2", - "sha256:4e83fd6112808d1d14d1a57397c6fa3bd71bb2f3b8800036e12366e3680819b9", - "sha256:52468a0784544eba708c0ae6bc5e8c5dcfd685495a60f7f74028662c984bd9cd", - "sha256:5d4073b754f90b19f28d036ec5143d3fca3a75e4d4241d78790a6178b00bb373", - "sha256:5f7add997684bc6141e1c80f6ba0c38ffe316ba277a4074e61b1b7b4f5a172bf", - "sha256:5ff655716cd13a242eef8cf5d368074e8b396ff86508a5933e7cff4f2b3eb3c2", - "sha256:617c9a92d8d8f60d5ef39e76596620503752a09f834a218e5b83be352fdd6c91", - "sha256:6425001e50a0c82108caed438233066cea04d42a8fc9c49bfcf081a5b96e5b4e", - "sha256:658ea8477fa020f08435fb7277635eb0b50cd5206b9d4cbe10e9a5466b01f855", - "sha256:65d395211736d9844537a530287a7c64b9fda1d353e899a0e1723986a0859154", - "sha256:660810cd27a8a94cb5e845e8f28a95e70b01ff0c45466d394c4a0cba5a0ae279", - "sha256:671e88a6209a1cf415dc0f8c67d2b2d3b55b436cc63801a518f9800ebd752959", - "sha256:674097dd54a0bbd555e7927092c74428c4c07268ad52bca38cfccc3214707e50", - "sha256:6f021aa2dbd8fbfe54d3fa2258518129108b7496922b3bcff2cf5991078eec67", - "sha256:704abc7f3403584cca9c01c5809812e0bd70632ea4251389fae4f45e11aad94f", - "sha256:73a8c8160d2a170dadcad5b82fb5ee53236a19cec0996651cf4d21da0a2574d5", - "sha256:768d33b484a35da93731cc99bdc926b539240a78673216cdc6306833d9072350", - "sha256:79bf1ef6850182e09d86e61fa31717da56014a3b2234afb025fca1f2a43ac07b", - "sha256:838a6d117739f1ae6ecc45ec630fa694f41a85c0d07b1f3b1db2a6cc52c1808b", - "sha256:8817b0f7d7830215261b18db83c9c3ef1da6bb64da5c292d7c70b9a46e5a6745", - "sha256:892d016789b59950989b2db188dcd46cf16d34e8daf2343e33b679b0c5fd1001", - "sha256:899f1a856b3bebb82b6cbc3c0014834b583b83f246b28e462a031ec1b766130b", - "sha256:8c2b1c91b437133c672e374857eccb1dd2c2d9f8477ae3b35138382d5ef19846", - "sha256:9479530e3fce65f6149058071fa4df8150025f15b43b103445f619842981a87c", - "sha256:95c8e7036cf442480d0bf6f5fde371e1eb6dbbf5391d7bdb8db73bd8a732b538", - "sha256:97dc6793e512a62ba9eab250134a2e67372c16ae9948e73d27c2ef355356e2e1", - "sha256:9a6a9342fae113b12aab42c790880c549d9ba695b8deff27ee08096eedd67569", - "sha256:a22f47c34ee1fcf7d93a8c5c93135499aac879d9d5d8f820bd28571a30fdabcd", - "sha256:a731c03bc00552ee6cc685a59616d36003124e7e04c6ddf65c2c47f1c3d85480", - "sha256:b095a1de40ca1afaeae8df3f45e26b645094a1912e6e6871e725fcf06ecdb74a", - "sha256:b48abd7745caec1a78a16a048966cde14ff6ccb04d471a7201532648d3f77d14", - "sha256:b5f3ab4185c1f72010846ca9fccb08349e23a2b52982a18d9870e848ce9f1c86", - "sha256:b684f8ecdeacd6baabc17b15ac1b054ca62029193e6c5367ef00b3516671de80", - "sha256:b7b647684eb2e1fd1e5e6b101249d5fe9d6117c117b5e336ad8dd75af48d2d1f", - "sha256:bcbb25029ee8756f10c6473cea5ef21707a1d9a8752cdf29fad3a5f34aa4a313", - "sha256:c0473dfa8f17c6a9a250b2bd6a5b62af3aa7d22518f701649115f1085d5e35ab", - "sha256:c08800c28160f4d32ca510128b4e201a43c813e7a2dd53178fa79ebe050eba13", - "sha256:c344eb09fcfbf71e5b5847d4f188fec98e1c3a976125ef571eac5f1c39e7a5e5", - "sha256:c596920d6017702a36e3a43fd8110a84e87d6229f30b84bd5640cbae9b5145da", - "sha256:c947135750d20f35acac290c34f1acf5771fc166a3fbc0e3816a97c756aaa5f5", - "sha256:d24d2ec74923b49bce7618e3e7762baa6be74e624d9829d5632321de102bf386", - "sha256:d828721dcbcb94b904a6b25df67c2513ecd24cd9e36694f38b9f0fa71c7c6103", - "sha256:ddad27a62df2ea47b7b483009fbfcf167a71d702cbd8e2eefd9ddc1c93146658", - "sha256:df6f618b98f0848fd8d07039541e10f23db679d8283f8719e870a98e1ef8e639", - "sha256:e1790481a6b9ce38888f22ce30710244067898c3ac4805a0e061e381f3db3506", - "sha256:e6776840aea3ff5ab6924b50117957da62db51b109b3b491c0d5817a804b1a8e", - "sha256:e99689f6c6b9ca6e2fc7a75d140e38c5a7985dab61fe1f4e506268f7e9844e05", - "sha256:ebd2e63baa117ded04b978813fcd1279d3fc6be2149c9cac75c716b6f1db774c", - "sha256:f50f10058b884d45cd8a50423bf561b1f9f9df7058abeb8b318700c8bcf4bb54", - "sha256:f5b94cba3edfc54bcb3ab5be616a2f50fa48be438e5af970824efdf882d1bc31" - ], - "markers": "python_version >= '3.8'", - "version": "==2.15.0" + "sha256:01bc257e9418980a4922de94775be42a966e1a082fb01a1635917f9afc7b84ca", + "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52", + "sha256:0c766bea27a0600e36806d628ebc4b47178b12fcdfb6c24dc0a566a9c06bfe7f", + "sha256:12474fcdbc475aa6fe5275fe7224e685c5b9777f5939647f35980e9614ae7558", + "sha256:15ec236b6571730236a193d9d6c11d472432fc6ab54e85eac1c16d98ddcd71bf", + "sha256:1784edf173ca840ba154de6eed000b5727f65ab92972c2f88cec5c4d6349c5f2", + "sha256:1e0dcc97cfec12ae306e3036746e7631cc7ef65c31889f7264c25217d4938367", + "sha256:23c5283c01b4f80b7dfbc88f3d8088c06c301b94b7c35366be498c2d7b308549", + "sha256:2552f0767bc10c9d668f108fef9b487809cdeb772439ce932e74136365c69baf", + "sha256:265462c77dc9576267c3c7f20707780a171a9fdbac93ac22e608c309efd68c33", + "sha256:298aa423e07c8b21b991782f01d7749c871c792319c2af3e9755f9ab49033212", + "sha256:2e08a4015d5d1aab2cb46c780e85b33efcd5cbe880bb363b282a6972e617b8bb", + "sha256:2f5876a5682ce1f517e55d7ace2383432627889f6f7e338b961f99d684fd9e8d", + "sha256:317b68b56a9c3731e0cf8886e0f94230727159e375988b36c60edce0ddbcb44a", + "sha256:32d445ce20d25c60ab92153c073942b0bac9815bfbfd152ce3dcc225d15ce988", + "sha256:4149e17018af07a5756a1df84aea71e6e178598c358c860c6bfec42170fa7970", + "sha256:43e1e18279759897be3293a255d53e6b1cb0364b69d9591d0b80c51e461c94b0", + "sha256:4a99acc273d2f98add23a89b94d4dd9e14969c01214c8514bfa78e4e9364c7e2", + "sha256:4d3843143c46dddca6491a954bbd0abfd435681512ac343169560e9bab504129", + "sha256:503e7ff507c2089699d91885fc5b9c8ff16774a7b6aff48b4dcee0c0a0685b61", + "sha256:520a814ea1b2706c89ab260a54023033d3015abef25c77873b83e3d7c1fafbb2", + "sha256:5886e23ede3478ca2a3e0a641f5d09dd784dfa9e48c96e8e5e31fc4fe77b6dc0", + "sha256:64c205ea37b8c4ba232645335fc3b75bc2d03ce30f0a34649e36cae85652ee96", + "sha256:667b150fedb54acdca2a4bea5bf6da837b43e6dd12857301b48191f8803ba93f", + "sha256:6895e3e84119594ab12847c928f619d40ae9cedd0755515dc154a5b5dc6edd9f", + "sha256:6dae82ab647d107817e013db82223e20a9853fa88543fec853ae326382d03c2e", + "sha256:7751bf745d54e9e8b358c0afa332815da9b8a6194b26d0fd62876ab6c4d5c9c0", + "sha256:7c29616e18e2349a8766d5b6817920fc74e39c00fa375d202231e9d525a1b882", + "sha256:806672529a2e255cd901f244c9033767dc1fa53466d0d3e3e49565a1572a64fe", + "sha256:8243664438bb468408b29c6865958662d75e51f79c91842d2794fa22629eb697", + "sha256:84788f4d62a8b1bf5e499bb9b0e23ceceea21c415ad6030be6267ce3d639842f", + "sha256:8f936566ef9f09136a3d5db305961ef6d897b76b240c9ff4199144aed6dd4fe5", + "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad", + "sha256:9d26d79de1c63a8c6586c75967e09b0ff306aa7e944a1eaddb74595c9b1839ca", + "sha256:9db5e5b3ccdadaafa5730c2f9db44c38b013234c9ad01f87738907e19bdba268", + "sha256:ac2df0fa564356384515ed62cb6679f33f1f529435b16b0ec0f88414635dbe39", + "sha256:ac95ae4529d7d85b251f9cf0f961a8a408ba285875811268f469d824a3b0b15a", + "sha256:c0fca3025266d88d1b48be162a43b7c2d91c81cc5b3bee9f01194678ffb9969a", + "sha256:c1906ec6e26e6b803cd6aab28d420c87285b9c209ff2a69f82d12f82278f78bb", + "sha256:c1ceb6035a64cb00650e3ab203cf3faffac18576a3f3125c24df468b784077c7", + "sha256:c761d32d0c5d1fe5b71ac502e1bd5edec4598a7fc6f607b9b906b98e911148ce", + "sha256:c76caf539fa4941e1817b7c482c87c65c52a1903fea761e84525955c6106fafb", + "sha256:cac3e2b4101db296b150cb665e5461c03621e6ede6117fc9d5048c0ec96d6e7c", + "sha256:cedc989717c8b44a3881ac3d68ab5a95820448796c550de6a2149ed1525157f0", + "sha256:d0b6ff3ccde9b16bbc694a2b5facf2d8890554f3135ff626ed1429e270e3cc4f", + "sha256:d5fe7a6284e3dce87ae13a25029c53542dd27a28d151f3ef362ec4dd9c3e45fd", + "sha256:da3ae1028af240c0c46c79adf9c1acffecc6ed1701f2863b8132f5ceae6ae4b5", + "sha256:ddfab1c622342f2945942c5c2d6be327656980e8f2d2b2ce0c022d0aa3711361", + "sha256:dfb76674db946a74f0ca6e3b81caa8265e35dafe9b7005c7d2b8dd5bbd3825cf", + "sha256:dfe92412bd11104c4f0fb2da68653e6c45b41f7217319a83a8b66ed4f20148b3", + "sha256:e3391ae9c484736850bb44ef125cbad52fe2d1b69e42c95dc88c43af8ead2cc7", + "sha256:e43adb22def972a29d2b147999b56897116085777a0fea182fd93ee45730611e", + "sha256:e46bd09c944ec7a20868abd2b83d7d7abdaf427775e9df3089b9226a122b340f", + "sha256:eee7b0fc4fbab2c6585ea17606c6548be83919c70deea0865409fe9fc2d8cdce", + "sha256:ef768e14768eebe3bb1196c0dece8e14c1c6991605721214a0c3c68cf77eb216", + "sha256:f6927dda86425f97ffda36131f297b1a601c64a6ee6838bfa0e6d3149c2f0d9f" + ], + "markers": "python_version >= '3.9'", + "version": "==2.16.0" }, "tqdm": { "hashes": [ @@ -2403,11 +2525,11 @@ }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", + "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446" ], "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" + "version": "==2.9.0.20241003" }, "typing-extensions": { "hashes": [ @@ -2420,11 +2542,11 @@ }, "tzdata": { "hashes": [ - "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd", - "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252" + "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", + "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd" ], "markers": "python_version >= '2'", - "version": "==2024.1" + "version": "==2024.2" }, "tzlocal": { "hashes": [ @@ -2453,11 +2575,11 @@ }, "uvicorn": { "hashes": [ - "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", - "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5" + "sha256:adc42d9cac80cf3e51af97c1851648066841e7cfb6993a4ca8de29ac1548ed41", + "sha256:f5167919867b161b7bcaf32646c6a94cdbd4c3aa2eb5c17d36bb9aa5cfd8c493" ], "markers": "python_version >= '3.8'", - "version": "==0.30.6" + "version": "==0.31.1" }, "vcrpy": { "hashes": [ @@ -2578,101 +2700,101 @@ }, "yarl": { "hashes": [ - "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49", - "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867", - "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520", - "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a", - "sha256:077da604852be488c9a05a524068cdae1e972b7dc02438161c32420fb4ec5e14", - "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a", - "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93", - "sha256:0ea9682124fc062e3d931c6911934a678cb28453f957ddccf51f568c2f2b5e05", - "sha256:0f351fa31234699d6084ff98283cb1e852270fe9e250a3b3bf7804eb493bd937", - "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74", - "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b", - "sha256:15439f3c5c72686b6c3ff235279630d08936ace67d0fe5c8d5bbc3ef06f5a420", - "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639", - "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089", - "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53", - "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e", - "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c", - "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e", - "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe", - "sha256:238a21849dd7554cb4d25a14ffbfa0ef380bb7ba201f45b144a14454a72ffa5a", - "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366", - "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63", - "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9", - "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145", - "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf", - "sha256:3257978c870728a52dcce8c2902bf01f6c53b65094b457bf87b2644ee6238ddc", - "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5", - "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff", - "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d", - "sha256:3ff6b1617aa39279fe18a76c8d165469c48b159931d9b48239065767ee455b2b", - "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00", - "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad", - "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92", - "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998", - "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91", - "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b", - "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a", - "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5", - "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff", - "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367", - "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa", - "sha256:61a5f2c14d0a1adfdd82258f756b23a550c13ba4c86c84106be4c111a3a4e413", - "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4", - "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45", - "sha256:67459cf8cf31da0e2cbdb4b040507e535d25cfbb1604ca76396a3a66b8ba37a6", - "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5", - "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df", - "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c", - "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318", - "sha256:7175a87ab8f7fbde37160a15e58e138ba3b2b0e05492d7351314a250d61b1591", - "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38", - "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8", - "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e", - "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804", - "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec", - "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6", - "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870", - "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83", - "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d", - "sha256:8418c053aeb236b20b0ab8fa6bacfc2feaaf7d4683dd96528610989c99723d5f", - "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909", - "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269", - "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26", - "sha256:8aef1b64da41d18026632d99a06b3fefe1d08e85dd81d849fa7c96301ed22f1b", - "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2", - "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7", - "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd", - "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68", - "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0", - "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786", - "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da", - "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc", - "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447", - "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239", - "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0", - "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84", - "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e", - "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef", - "sha256:ba444bdd4caa2a94456ef67a2f383710928820dd0117aae6650a4d17029fa25e", - "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82", - "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675", - "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26", - "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979", - "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46", - "sha256:dae7bd0daeb33aa3e79e72877d3d51052e8b19c9025ecf0374f542ea8ec120e4", - "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff", - "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27", - "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c", - "sha256:f3a6d90cab0bdf07df8f176eae3a07127daafcf7457b997b2bf46776da2c7eb7", - "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265", - "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79", - "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd" - ], - "markers": "python_version >= '3.8'", - "version": "==1.11.1" + "sha256:047b258e00b99091b6f90355521f026238c63bd76dcf996d93527bb13320eefd", + "sha256:06ff23462398333c78b6f4f8d3d70410d657a471c2c5bbe6086133be43fc8f1a", + "sha256:07f9eaf57719d6721ab15805d85f4b01a5b509a0868d7320134371bcb652152d", + "sha256:0aa92e3e30a04f9462a25077db689c4ac5ea9ab6cc68a2e563881b987d42f16d", + "sha256:0cf21f46a15d445417de8fc89f2568852cf57fe8ca1ab3d19ddb24d45c0383ae", + "sha256:0fd7b941dd1b00b5f0acb97455fea2c4b7aac2dd31ea43fb9d155e9bc7b78664", + "sha256:147e36331f6f63e08a14640acf12369e041e0751bb70d9362df68c2d9dcf0c87", + "sha256:16a682a127930f3fc4e42583becca6049e1d7214bcad23520c590edd741d2114", + "sha256:176110bff341b6730f64a1eb3a7070e12b373cf1c910a9337e7c3240497db76f", + "sha256:19268b4fec1d7760134f2de46ef2608c2920134fb1fa61e451f679e41356dc55", + "sha256:1b16f6c75cffc2dc0616ea295abb0e1967601bd1fb1e0af6a1de1c6c887f3439", + "sha256:1bfc25aa6a7c99cf86564210f79a0b7d4484159c67e01232b116e445b3036547", + "sha256:1ca3894e9e9f72da93544f64988d9c052254a338a9f855165f37f51edb6591de", + "sha256:1dda53508df0de87b6e6b0a52d6718ff6c62a5aca8f5552748404963df639269", + "sha256:217a782020b875538eebf3948fac3a7f9bbbd0fd9bf8538f7c2ad7489e80f4e8", + "sha256:2192f718db4a8509f63dd6d950f143279211fa7e6a2c612edc17d85bf043d36e", + "sha256:29a84a46ec3ebae7a1c024c055612b11e9363a8a23238b3e905552d77a2bc51b", + "sha256:3007a5b75cb50140708420fe688c393e71139324df599434633019314ceb8b59", + "sha256:30600ba5db60f7c0820ef38a2568bb7379e1418ecc947a0f76fd8b2ff4257a97", + "sha256:337912bcdcf193ade64b9aae5a4017a0a1950caf8ca140362e361543c6773f21", + "sha256:37001e5d4621cef710c8dc1429ca04e189e572f128ab12312eab4e04cf007132", + "sha256:3d569f877ed9a708e4c71a2d13d2940cb0791da309f70bd970ac1a5c088a0a92", + "sha256:4009def9be3a7e5175db20aa2d7307ecd00bbf50f7f0f989300710eee1d0b0b9", + "sha256:46a9772a1efa93f9cd170ad33101c1817c77e0e9914d4fe33e2da299d7cf0f9b", + "sha256:47eede5d11d669ab3759b63afb70d28d5328c14744b8edba3323e27dc52d298d", + "sha256:498b3c55087b9d762636bca9b45f60d37e51d24341786dc01b81253f9552a607", + "sha256:4e0d45ebf975634468682c8bec021618b3ad52c37619e5c938f8f831fa1ac5c0", + "sha256:4f24f08b6c9b9818fd80612c97857d28f9779f0d1211653ece9844fc7b414df2", + "sha256:55c144d363ad4626ca744556c049c94e2b95096041ac87098bb363dcc8635e8d", + "sha256:582cedde49603f139be572252a318b30dc41039bc0b8165f070f279e5d12187f", + "sha256:587c3cc59bc148a9b1c07a019346eda2549bc9f468acd2f9824d185749acf0a6", + "sha256:5cd5dad8366e0168e0fd23d10705a603790484a6dbb9eb272b33673b8f2cce72", + "sha256:5d02d700705d67e09e1f57681f758f0b9d4412eeb70b2eb8d96ca6200b486db3", + "sha256:625f207b1799e95e7c823f42f473c1e9dbfb6192bd56bba8695656d92be4535f", + "sha256:659603d26d40dd4463200df9bfbc339fbfaed3fe32e5c432fe1dc2b5d4aa94b4", + "sha256:689a99a42ee4583fcb0d3a67a0204664aa1539684aed72bdafcbd505197a91c4", + "sha256:68ac1a09392ed6e3fd14be880d39b951d7b981fd135416db7d18a6208c536561", + "sha256:6a615cad11ec3428020fb3c5a88d85ce1b5c69fd66e9fcb91a7daa5e855325dd", + "sha256:73bedd2be05f48af19f0f2e9e1353921ce0c83f4a1c9e8556ecdcf1f1eae4892", + "sha256:742aef0a99844faaac200564ea6f5e08facb285d37ea18bd1a5acf2771f3255a", + "sha256:75ff4c819757f9bdb35de049a509814d6ce851fe26f06eb95a392a5640052482", + "sha256:781e2495e408a81e4eaeedeb41ba32b63b1980dddf8b60dbbeff6036bcd35049", + "sha256:7a9f917966d27f7ce30039fe8d900f913c5304134096554fd9bea0774bcda6d1", + "sha256:7e2637d75e92763d1322cb5041573279ec43a80c0f7fbbd2d64f5aee98447b17", + "sha256:8089d4634d8fa2b1806ce44fefa4979b1ab2c12c0bc7ef3dfa45c8a374811348", + "sha256:816d24f584edefcc5ca63428f0b38fee00b39fe64e3c5e558f895a18983efe96", + "sha256:8385ab36bf812e9d37cf7613999a87715f27ef67a53f0687d28c44b819df7cb0", + "sha256:85cb3e40eaa98489f1e2e8b29f5ad02ee1ee40d6ce6b88d50cf0f205de1d9d2c", + "sha256:8648180b34faaea4aa5b5ca7e871d9eb1277033fa439693855cf0ea9195f85f1", + "sha256:8892fa575ac9b1b25fae7b221bc4792a273877b9b56a99ee2d8d03eeb3dbb1d2", + "sha256:88c7d9d58aab0724b979ab5617330acb1c7030b79379c8138c1c8c94e121d1b3", + "sha256:8a2f8fb7f944bcdfecd4e8d855f84c703804a594da5123dd206f75036e536d4d", + "sha256:8f4e475f29a9122f908d0f1f706e1f2fc3656536ffd21014ff8a6f2e1b14d1d8", + "sha256:8f50eb3837012a937a2b649ec872b66ba9541ad9d6f103ddcafb8231cfcafd22", + "sha256:91d875f75fabf76b3018c5f196bf3d308ed2b49ddcb46c1576d6b075754a1393", + "sha256:94b2bb9bcfd5be9d27004ea4398fb640373dd0c1a9e219084f42c08f77a720ab", + "sha256:9557c9322aaa33174d285b0c1961fb32499d65ad1866155b7845edc876c3c835", + "sha256:95e16e9eaa2d7f5d87421b8fe694dd71606aa61d74b824c8d17fc85cc51983d1", + "sha256:96952f642ac69075e44c7d0284528938fdff39422a1d90d3e45ce40b72e5e2d9", + "sha256:985623575e5c4ea763056ffe0e2d63836f771a8c294b3de06d09480538316b13", + "sha256:99ff3744f5fe48288be6bc402533b38e89749623a43208e1d57091fc96b783b9", + "sha256:9abe80ae2c9d37c17599557b712e6515f4100a80efb2cda15f5f070306477cd2", + "sha256:a152751af7ef7b5d5fa6d215756e508dd05eb07d0cf2ba51f3e740076aa74373", + "sha256:a2e4725a08cb2b4794db09e350c86dee18202bb8286527210e13a1514dc9a59a", + "sha256:a56fbe3d7f3bce1d060ea18d2413a2ca9ca814eea7cedc4d247b5f338d54844e", + "sha256:ab3abc0b78a5dfaa4795a6afbe7b282b6aa88d81cf8c1bb5e394993d7cae3457", + "sha256:b03384eed107dbeb5f625a99dc3a7de8be04fc8480c9ad42fccbc73434170b20", + "sha256:b0547ab1e9345dc468cac8368d88ea4c5bd473ebc1d8d755347d7401982b5dd8", + "sha256:b4c1ecba93e7826dc71ddba75fb7740cdb52e7bd0be9f03136b83f54e6a1f511", + "sha256:b693c63e7e64b524f54aa4888403c680342d1ad0d97be1707c531584d6aeeb4f", + "sha256:b6d0147574ce2e7b812c989e50fa72bbc5338045411a836bd066ce5fc8ac0bce", + "sha256:b9cfef3f14f75bf6aba73a76caf61f9d00865912a04a4393c468a7ce0981b519", + "sha256:b9f805e37ed16cc212fdc538a608422d7517e7faf539bedea4fe69425bc55d76", + "sha256:bab03192091681d54e8225c53f270b0517637915d9297028409a2a5114ff4634", + "sha256:bc24f968b82455f336b79bf37dbb243b7d76cd40897489888d663d4e028f5069", + "sha256:c14b504a74e58e2deb0378b3eca10f3d076635c100f45b113c18c770b4a47a50", + "sha256:c2089a9afef887664115f7fa6d3c0edd6454adaca5488dba836ca91f60401075", + "sha256:c8ed4034f0765f8861620c1f2f2364d2e58520ea288497084dae880424fc0d9f", + "sha256:cd2660c01367eb3ef081b8fa0a5da7fe767f9427aa82023a961a5f28f0d4af6c", + "sha256:d8361c7d04e6a264481f0b802e395f647cd3f8bbe27acfa7c12049efea675bd1", + "sha256:d9baec588f015d0ee564057aa7574313c53a530662ffad930b7886becc85abdf", + "sha256:dbd9ff43a04f8ffe8a959a944c2dca10d22f5f99fc6a459f49c3ebfb409309d9", + "sha256:e3f8bfc1db82589ef965ed234b87de30d140db8b6dc50ada9e33951ccd8ec07a", + "sha256:e6a2c5c5bb2556dfbfffffc2bcfb9c235fd2b566d5006dfb2a37afc7e3278a07", + "sha256:e749af6c912a7bb441d105c50c1a3da720474e8acb91c89350080dd600228f0e", + "sha256:e85d86527baebb41a214cc3b45c17177177d900a2ad5783dbe6f291642d4906f", + "sha256:ee2c68e4f2dd1b1c15b849ba1c96fac105fca6ffdb7c1e8be51da6fabbdeafb9", + "sha256:f3ab950f8814f3b7b5e3eebc117986f817ec933676f68f0a6c5b2137dd7c9c69", + "sha256:f4f4547944d4f5cfcdc03f3f097d6f05bbbc915eaaf80a2ee120d0e756de377d", + "sha256:f72a0d746d38cb299b79ce3d4d60ba0892c84bbc905d0d49c13df5bace1b65f8", + "sha256:fc2c80bc87fba076e6cbb926216c27fba274dae7100a7b9a0983b53132dd99f2", + "sha256:fe4d2536c827f508348d7b40c08767e8c7071614250927233bf0c92170451c0a" + ], + "markers": "python_version >= '3.8'", + "version": "==1.14.0" }, "zipp": { "hashes": [ @@ -2726,12 +2848,12 @@ }, "astroid": { "hashes": [ - "sha256:2d79acfd3c594b6a2d4141fea98a1d62ab4a52e54332b1f1ddcf07b652cc5c0f", - "sha256:63f8c5370d9bad8294163c87b2d440a7fdf546be6c72bbeac0549c93244dbd72" + "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d", + "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8" ], "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.3" + "version": "==3.3.5" }, "attrs": { "hashes": [ @@ -2809,12 +2931,12 @@ }, "bandit": { "hashes": [ - "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec", - "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61" + "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b", + "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.7.9" + "version": "==1.7.10" }, "beautifulsoup4": { "hashes": [ @@ -2830,20 +2952,20 @@ "logs" ], "hashes": [ - "sha256:329a9944a75bedd9b343230b03d37c94158e60e7b7a9553e03be9a8f327cd41c", - "sha256:f96c814f26f2ab8fcd42811b7208105f43657fe15ffa82be2cdc7734160e28c4" + "sha256:32b70602af1c34ddd244bbdafcc7f32b9824135c2f14dcf41d8e5a33b914b19a", + "sha256:dc12838481a10d65802f75b4ca1e4eb334e06dbb2f0d5c565f43e0363c2037d6" ], "markers": "python_version >= '3.8'", - "version": "==1.35.24" + "version": "==1.35.37" }, "botocore-stubs": { "hashes": [ - "sha256:052eead5808ef138988089b6de6786f6271fc7f395ee0d4395e96e06ab04573c", - "sha256:20ca0d0c77215b599ab79e365f2bf5f909a49f4c5440bbbbb08175971a3de442" + "sha256:0fd4ce53636196fcb72b8dad1c67cb774f2f1941891a9c5293f91401ff6d8589", + "sha256:834f1d55c8e8a815bbb446fe9a7d3da09c4402312ff1a8fcf13fb6b4b894ab92" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.24" + "version": "==1.35.37" }, "bson": { "hashes": [ @@ -2854,19 +2976,11 @@ }, "build": { "hashes": [ - "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c", - "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613" + "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", + "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" ], "markers": "python_version >= '3.8'", - "version": "==1.2.2" - }, - "cattrs": { - "hashes": [ - "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0", - "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85" - ], - "markers": "python_version >= '3.8'", - "version": "==24.1.2" + "version": "==1.2.2.post1" }, "certifi": { "hashes": [ @@ -2959,107 +3073,122 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "check-manifest": { "hashes": [ - "sha256:058cd30057714c39b96ce4d83f254fc770e3145c7b1932b5940b4e3efb5521ef", - "sha256:64a640445542cf226919657c7b78d02d9c1ca5b1c25d7e66e0e1ff325060f416" + "sha256:6ab3e3aa72a008da3314b432f4c768c9647b4d6d8032f9e1a4672a572118e48c", + "sha256:d300f9f292986aa1a30424af44eb45c5644e0a810e392e62d553b24bb3393494" ], "markers": "python_version >= '3.7'", - "version": "==0.49" + "version": "==0.50" }, "checkmk-dev-tools": { "hashes": [ @@ -3091,81 +3220,71 @@ "toml" ], "hashes": [ - "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", - "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", - "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", - "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", - "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", - "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", - "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", - "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", - "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", - "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", - "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", - "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", - "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", - "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", - "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", - "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", - "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", - "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", - "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", - "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", - "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", - "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", - "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", - "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", - "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", - "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", - "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", - "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", - "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", - "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", - "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", - "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", - "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", - "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", - "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", - "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", - "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", - "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", - "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", - "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", - "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", - "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", - "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", - "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", - "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", - "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", - "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", - "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", - "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", - "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", - "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", - "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", - "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", - "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", - "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", - "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", - "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", - "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", - "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", - "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", - "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", - "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", - "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", - "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", - "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", - "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", - "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", - "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", - "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", - "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", - "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", - "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc" - ], - "markers": "python_version >= '3.8'", - "version": "==7.6.1" + "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0", + "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f", + "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b", + "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4", + "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f", + "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760", + "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c", + "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304", + "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52", + "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171", + "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14", + "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77", + "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5", + "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba", + "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b", + "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40", + "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658", + "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0", + "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345", + "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e", + "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e", + "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0", + "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2", + "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef", + "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438", + "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7", + "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676", + "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e", + "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f", + "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e", + "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea", + "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90", + "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b", + "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89", + "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3", + "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170", + "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84", + "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e", + "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1", + "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf", + "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e", + "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191", + "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b", + "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869", + "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909", + "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5", + "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36", + "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f", + "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667", + "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b", + "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a", + "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02", + "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530", + "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627", + "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6", + "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c", + "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925", + "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0", + "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72", + "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276", + "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a", + "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db" + ], + "markers": "python_version >= '3.9'", + "version": "==7.6.2" }, "cryptography": { "hashes": [ @@ -3206,27 +3325,27 @@ }, "dill": { "hashes": [ - "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", - "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" + "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", + "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.3.8" + "version": "==0.3.9" }, "distlib": { "hashes": [ - "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", - "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64" + "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", + "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403" ], - "version": "==0.3.8" + "version": "==0.3.9" }, "dnspython": { "hashes": [ - "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", - "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc" + "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", + "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1" ], - "markers": "python_version >= '3.8'", - "version": "==2.6.1" + "markers": "python_version >= '3.9'", + "version": "==2.7.0" }, "docker": { "hashes": [ @@ -3270,22 +3389,22 @@ }, "faker": { "hashes": [ - "sha256:32d0ee7d42925ff06e4a7d906ee7efbf34f5052a41a2a1eb8bb174a422a5498f", - "sha256:34e89aec594cad9773431ca479ee95c7ce03dd9f22fda2524e2373b880a2fa77" + "sha256:8760fbb34564fbb2f394345eef24aec5b8f6506b6cfcefe8195ed66dd1032bdb", + "sha256:e8a15fd1b0f72992b008f5ea94c70d3baa0cb51b0d5a0e899c17b1d1b23d2771" ], "markers": "python_version >= '3.8'", - "version": "==29.0.0" + "version": "==30.3.0" }, "fakeredis": { "extras": [ "lua" ], "hashes": [ - "sha256:09d3049a29910f80c0ef5789c31bef3dbb9727bd43a67ee8598217f4efd12f35", - "sha256:4a52ab0edad53543ac5e3a41d761f91012613ed583344da54ae6473e05b0f6d0" + "sha256:d08dcbaceae0804db4644fa634106e3c42d76fe4d11aea2949eda768df0c6450", + "sha256:e9e73bacf412d1d942ee7f80525dc188182158e82d41be57eb9c4e71f7474ac8" ], "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==2.24.1" + "version": "==2.25.1" }, "fastapi": { "hashes": [ @@ -3426,11 +3545,11 @@ }, "httpcore": { "hashes": [ - "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", - "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", + "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f" ], "markers": "python_version >= '3.8'", - "version": "==1.0.5" + "version": "==1.0.6" }, "httpx": { "hashes": [ @@ -3442,12 +3561,12 @@ }, "hypothesis": { "hashes": [ - "sha256:93631b1498b20d2c205ed304cbd41d50e9c069d78a9c773c1324ca094c5e30ce", - "sha256:b070d7a1bb9bd84706c31885c9aeddc138e2b36a9c112a91984f49501c567856" + "sha256:117f2d065d3f2ec5b2b37c89150c2350be7feb43dfb9ccc30f30d5293b34e607", + "sha256:15ea6e4bb297276351ada18f172c60049c117a91040154ea620c632cc4c53e88" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==6.112.1" + "markers": "python_version >= '3.9'", + "version": "==6.114.1" }, "hypothesis-graphql": { "hashes": [ @@ -3508,10 +3627,11 @@ }, "isodate": { "hashes": [ - "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", - "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" + "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", + "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6" ], - "version": "==0.6.1" + "markers": "python_version >= '3.7'", + "version": "==0.7.2" }, "isoduration": { "hashes": [ @@ -3546,11 +3666,11 @@ }, "jaraco.functools": { "hashes": [ - "sha256:3460c74cd0d32bf82b9576bbb3527c4364d5b27a21f5158a62aed6c4b42e23f5", - "sha256:c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3" + "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649" ], "markers": "python_version >= '3.8'", - "version": "==4.0.2" + "version": "==4.1.0" }, "jedi": { "hashes": [ @@ -3633,14 +3753,6 @@ "markers": "python_version >= '3.9'", "version": "==1.4.0" }, - "lsprotocol": { - "hashes": [ - "sha256:c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2", - "sha256:cc5c15130d2403c18b734304339e51242d3018a05c4f7d0f198ad6e0cd21861d" - ], - "markers": "python_version >= '3.7'", - "version": "==2023.0.1" - }, "lupa": { "hashes": [ "sha256:00bcae88a2123f0cfd34f7206cc2d88008d905ebc065d41797827d046404b09e", @@ -3742,69 +3854,70 @@ }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", + "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", + "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", + "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", + "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", + "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", + "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", + "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", + "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", + "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", + "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", + "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", + "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", + "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", + "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", + "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", + "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", + "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", + "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", + "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", + "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", + "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", + "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", + "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", + "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", + "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", + "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", + "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", + "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", + "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", + "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", + "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", + "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", + "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", + "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", + "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", + "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", + "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", + "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", + "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", + "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", + "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", + "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", + "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", + "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", + "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", + "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", + "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", + "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", + "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", + "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", + "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", + "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", + "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", + "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", + "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", + "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", + "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", + "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", + "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", + "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "markers": "python_version >= '3.9'", + "version": "==3.0.1" }, "mccabe": { "hashes": [ @@ -4116,12 +4229,116 @@ }, "pre-commit": { "hashes": [ - "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", - "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f" + "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", + "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==3.8.0" + "version": "==4.0.1" + }, + "propcache": { + "hashes": [ + "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", + "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", + "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", + "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb", + "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", + "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", + "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957", + "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68", + "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f", + "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798", + "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418", + "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6", + "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162", + "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", + "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", + "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", + "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", + "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", + "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", + "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8", + "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638", + "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", + "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", + "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", + "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", + "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", + "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", + "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", + "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", + "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89", + "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", + "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", + "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", + "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861", + "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", + "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", + "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", + "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", + "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", + "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", + "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", + "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563", + "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5", + "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", + "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9", + "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12", + "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", + "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", + "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", + "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9", + "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed", + "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", + "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90", + "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063", + "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", + "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6", + "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8", + "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", + "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", + "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", + "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", + "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", + "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df", + "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", + "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", + "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", + "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", + "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", + "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", + "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", + "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", + "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", + "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6", + "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562", + "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", + "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", + "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", + "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", + "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", + "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", + "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", + "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d", + "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04", + "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", + "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", + "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", + "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea", + "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", + "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1", + "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", + "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", + "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7", + "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", + "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d", + "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", + "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d", + "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", + "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504" + ], + "markers": "python_version >= '3.8'", + "version": "==0.2.0" }, "protobuf": { "hashes": [ @@ -4304,12 +4521,12 @@ }, "pylint": { "hashes": [ - "sha256:02dce1845f68974b9b03045894eb3bf05a8b3c7da9fd10af4de3c91e69eb92f1", - "sha256:c685fe3c061ee5fb0ce7c29436174ab84a2f525fce2a268b1986e921e083fe22" + "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9", + "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e" ], "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.0" + "version": "==3.3.1" }, "pylint-plugin-utils": { "hashes": [ @@ -4347,11 +4564,11 @@ }, "pyproject-hooks": { "hashes": [ - "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965", - "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2" + "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", + "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913" ], "markers": "python_version >= '3.7'", - "version": "==1.1.0" + "version": "==1.2.0" }, "pyrate-limiter": { "hashes": [ @@ -4422,31 +4639,13 @@ "markers": "python_full_version >= '3.5.0'", "version": "==1.1.1" }, - "pytest-repeat": { - "hashes": [ - "sha256:26ab2df18226af9d5ce441c858f273121e92ff55f5bb311d25755b8d7abdd8ed", - "sha256:ffd3836dfcd67bb270bec648b330e20be37d2966448c4148c4092d1e8aba8185" - ], - "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==0.9.3" - }, "pytest-subtests": { "hashes": [ - "sha256:2e3691caedea0c464fe96ffffd14bf872df1406b88d1930971dafe1966095bad", - "sha256:95c44c77e3fbede9848bb88ca90b384815fcba8090ef9a9f55659ab163b1681c" + "sha256:989e38f0f1c01bc7c6b2e04db7d9fd859db35d77c2c1a430c831a70cbf3fde2d", + "sha256:ab616a22f64cd17c1aee65f18af94dbc30c444f8683de2b30895c3778265e3bd" ], - "markers": "python_version >= '3.6'", - "version": "==0.7.0" - }, - "pytest-testmon": { - "hashes": [ - "sha256:8271ca47bc8c80760c4fc7fd7895ea786b111bbb31f13eeea879a6fd11fe2226", - "sha256:8ebe2c3de42d99306ee54cd4536fed0fc48346a954420da904b18e8d59b5da98" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==2.1.1" + "markers": "python_version >= '3.7'", + "version": "==0.13.1" }, "pytest-xdist": { "hashes": [ @@ -4481,15 +4680,6 @@ "markers": "python_version >= '3.8'", "version": "==1.1.2" }, - "python-lsp-ruff": { - "hashes": [ - "sha256:3f80bdb0b4a8ee24624596a1cff60b28cc37771773730f9bf7d946ddff9f0cac", - "sha256:7034d16c5cfdf07e932195649ebef569a7ddfcc5853fb2fee05fa7fc739afe3a" - ], - "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==2.2.2" - }, "python-lsp-server": { "hashes": [ "sha256:2e912c661881d85f67f2076e4e66268b695b62bf127e07e81f58b187d4bb6eda", @@ -4593,11 +4783,11 @@ }, "rich": { "hashes": [ - "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", - "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "rpds-py": { "hashes": [ @@ -4710,21 +4900,21 @@ }, "ruff": { "hashes": [ - "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", - "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b" + "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", + "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.6.7" + "version": "==0.6.9" }, "schemathesis": { "hashes": [ - "sha256:67043bb96aa72f29c00e0ee4008f98117e0964024a7c8fe953db3d476dcab16c", - "sha256:88ed12a33a94546285fb8ca6cb19f58040253d264b31c13b04b6509fd11f18bf" + "sha256:0333141cba48f8a9fc15894d57078b1baaac36e2582199113899840685005dfa", + "sha256:9a7c4f8c2a855c6fa8fa36eba80977d7cbc21157b18d2c6297e264b74e2daeba" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==3.36.1" + "version": "==3.37.0" }, "secretstorage": { "hashes": [ @@ -4745,11 +4935,12 @@ }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5", + "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc" ], + "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "version": "==70.3.0" }, "six": { "hashes": [ @@ -4801,12 +4992,12 @@ }, "sphinx-autoapi": { "hashes": [ - "sha256:c31a5f41eabc9705d277b75f98e983d653e9af24e294dd576b2afa1719f72c1f", - "sha256:e44a225827d0ef7178748225a66f30c95454dfd00ee3c22afbdfb8056f7dffb5" + "sha256:08afa656f7fcd45fe7dd64bf9f44698ddb8ca7c2d5cd0614c7455912ed580324", + "sha256:ebf8b44b2ebab5c28f0263ec6c2f8acdd156e9b2d539a58eca39d2f368445173" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==3.3.1" + "version": "==3.3.2" }, "sphinx-autodoc-typehints": { "hashes": [ @@ -4941,76 +5132,65 @@ }, "time-machine": { "hashes": [ - "sha256:008bd668d933b1a029c81805bcdc0132390c2545b103cf8e6709e3adbc37989d", - "sha256:014589d0edd4aa14f8d63985745565e8cbbe48461d6c004a96000b47f6b44e78", - "sha256:0302568338c8bd333ed0698231dbb781b70ead1a5579b4ac734b9bf88313229f", - "sha256:0630a32e9ebcf2fac3704365b31e271fef6eabd6fedfa404cd8dbd244f7fc84d", - "sha256:09fd839a321a92aa8183206c383b9725eaf4e0a28a70e4cb87db292b352eeefb", - "sha256:0b2d28daf4cabc698aafb12135525d87dc1f2f893cbd29a8a6fe0d8d36d1342c", - "sha256:1168eebd7af7e6e3e2fd378c16ca917b97dd81c89a1f1f9e1daa985c81699d90", - "sha256:18fc4740073e67071472c48355775ec6d1b93af5c675524b7de2474e0dcd8741", - "sha256:1dee3a0dd1866988c49a5d00564404db9bcdf49ca92f9c4e8b6c99609d64e698", - "sha256:245ef73f9927b7d4909d554a6a0284dbc5dee9730adea599e430b37c9e9fa203", - "sha256:29b988b1f09f2a083b12b6b054787b799ae91ee15bb0e9de3e48f880e4d68674", - "sha256:31af56399bf7c9ef76a3f7b6d9471dffa8f06ee373c194a374b69523f9061de9", - "sha256:3862dda89bdb05f9d521b08fdcb24b19a7dd9f559ae324f4301ba7a07b6eea64", - "sha256:3b177d334a35bf2ce103bfe4e0e416e4ee824dd33386ea73fa7491c17cc61897", - "sha256:3f7eadd820e792de33a9ec91f8178a2b9088e4e8b9a166953419ddc4ec5f7cfe", - "sha256:4428bdae507996aa3fdeb4727bca09e26306fa64a502e7335207252684516cbf", - "sha256:4601fe7a6b74c6fd9207e614d9db2a20dd4befd4d314677a0feac13a67189707", - "sha256:4cd9f057457d12604be18b623bcd5ae7d0b917ad66cb510ee1135d5f123666e2", - "sha256:4e83fd6112808d1d14d1a57397c6fa3bd71bb2f3b8800036e12366e3680819b9", - "sha256:52468a0784544eba708c0ae6bc5e8c5dcfd685495a60f7f74028662c984bd9cd", - "sha256:5d4073b754f90b19f28d036ec5143d3fca3a75e4d4241d78790a6178b00bb373", - "sha256:5f7add997684bc6141e1c80f6ba0c38ffe316ba277a4074e61b1b7b4f5a172bf", - "sha256:5ff655716cd13a242eef8cf5d368074e8b396ff86508a5933e7cff4f2b3eb3c2", - "sha256:617c9a92d8d8f60d5ef39e76596620503752a09f834a218e5b83be352fdd6c91", - "sha256:6425001e50a0c82108caed438233066cea04d42a8fc9c49bfcf081a5b96e5b4e", - "sha256:658ea8477fa020f08435fb7277635eb0b50cd5206b9d4cbe10e9a5466b01f855", - "sha256:65d395211736d9844537a530287a7c64b9fda1d353e899a0e1723986a0859154", - "sha256:660810cd27a8a94cb5e845e8f28a95e70b01ff0c45466d394c4a0cba5a0ae279", - "sha256:671e88a6209a1cf415dc0f8c67d2b2d3b55b436cc63801a518f9800ebd752959", - "sha256:674097dd54a0bbd555e7927092c74428c4c07268ad52bca38cfccc3214707e50", - "sha256:6f021aa2dbd8fbfe54d3fa2258518129108b7496922b3bcff2cf5991078eec67", - "sha256:704abc7f3403584cca9c01c5809812e0bd70632ea4251389fae4f45e11aad94f", - "sha256:73a8c8160d2a170dadcad5b82fb5ee53236a19cec0996651cf4d21da0a2574d5", - "sha256:768d33b484a35da93731cc99bdc926b539240a78673216cdc6306833d9072350", - "sha256:79bf1ef6850182e09d86e61fa31717da56014a3b2234afb025fca1f2a43ac07b", - "sha256:838a6d117739f1ae6ecc45ec630fa694f41a85c0d07b1f3b1db2a6cc52c1808b", - "sha256:8817b0f7d7830215261b18db83c9c3ef1da6bb64da5c292d7c70b9a46e5a6745", - "sha256:892d016789b59950989b2db188dcd46cf16d34e8daf2343e33b679b0c5fd1001", - "sha256:899f1a856b3bebb82b6cbc3c0014834b583b83f246b28e462a031ec1b766130b", - "sha256:8c2b1c91b437133c672e374857eccb1dd2c2d9f8477ae3b35138382d5ef19846", - "sha256:9479530e3fce65f6149058071fa4df8150025f15b43b103445f619842981a87c", - "sha256:95c8e7036cf442480d0bf6f5fde371e1eb6dbbf5391d7bdb8db73bd8a732b538", - "sha256:97dc6793e512a62ba9eab250134a2e67372c16ae9948e73d27c2ef355356e2e1", - "sha256:9a6a9342fae113b12aab42c790880c549d9ba695b8deff27ee08096eedd67569", - "sha256:a22f47c34ee1fcf7d93a8c5c93135499aac879d9d5d8f820bd28571a30fdabcd", - "sha256:a731c03bc00552ee6cc685a59616d36003124e7e04c6ddf65c2c47f1c3d85480", - "sha256:b095a1de40ca1afaeae8df3f45e26b645094a1912e6e6871e725fcf06ecdb74a", - "sha256:b48abd7745caec1a78a16a048966cde14ff6ccb04d471a7201532648d3f77d14", - "sha256:b5f3ab4185c1f72010846ca9fccb08349e23a2b52982a18d9870e848ce9f1c86", - "sha256:b684f8ecdeacd6baabc17b15ac1b054ca62029193e6c5367ef00b3516671de80", - "sha256:b7b647684eb2e1fd1e5e6b101249d5fe9d6117c117b5e336ad8dd75af48d2d1f", - "sha256:bcbb25029ee8756f10c6473cea5ef21707a1d9a8752cdf29fad3a5f34aa4a313", - "sha256:c0473dfa8f17c6a9a250b2bd6a5b62af3aa7d22518f701649115f1085d5e35ab", - "sha256:c08800c28160f4d32ca510128b4e201a43c813e7a2dd53178fa79ebe050eba13", - "sha256:c344eb09fcfbf71e5b5847d4f188fec98e1c3a976125ef571eac5f1c39e7a5e5", - "sha256:c596920d6017702a36e3a43fd8110a84e87d6229f30b84bd5640cbae9b5145da", - "sha256:c947135750d20f35acac290c34f1acf5771fc166a3fbc0e3816a97c756aaa5f5", - "sha256:d24d2ec74923b49bce7618e3e7762baa6be74e624d9829d5632321de102bf386", - "sha256:d828721dcbcb94b904a6b25df67c2513ecd24cd9e36694f38b9f0fa71c7c6103", - "sha256:ddad27a62df2ea47b7b483009fbfcf167a71d702cbd8e2eefd9ddc1c93146658", - "sha256:df6f618b98f0848fd8d07039541e10f23db679d8283f8719e870a98e1ef8e639", - "sha256:e1790481a6b9ce38888f22ce30710244067898c3ac4805a0e061e381f3db3506", - "sha256:e6776840aea3ff5ab6924b50117957da62db51b109b3b491c0d5817a804b1a8e", - "sha256:e99689f6c6b9ca6e2fc7a75d140e38c5a7985dab61fe1f4e506268f7e9844e05", - "sha256:ebd2e63baa117ded04b978813fcd1279d3fc6be2149c9cac75c716b6f1db774c", - "sha256:f50f10058b884d45cd8a50423bf561b1f9f9df7058abeb8b318700c8bcf4bb54", - "sha256:f5b94cba3edfc54bcb3ab5be616a2f50fa48be438e5af970824efdf882d1bc31" - ], - "markers": "python_version >= '3.8'", - "version": "==2.15.0" + "sha256:01bc257e9418980a4922de94775be42a966e1a082fb01a1635917f9afc7b84ca", + "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52", + "sha256:0c766bea27a0600e36806d628ebc4b47178b12fcdfb6c24dc0a566a9c06bfe7f", + "sha256:12474fcdbc475aa6fe5275fe7224e685c5b9777f5939647f35980e9614ae7558", + "sha256:15ec236b6571730236a193d9d6c11d472432fc6ab54e85eac1c16d98ddcd71bf", + "sha256:1784edf173ca840ba154de6eed000b5727f65ab92972c2f88cec5c4d6349c5f2", + "sha256:1e0dcc97cfec12ae306e3036746e7631cc7ef65c31889f7264c25217d4938367", + "sha256:23c5283c01b4f80b7dfbc88f3d8088c06c301b94b7c35366be498c2d7b308549", + "sha256:2552f0767bc10c9d668f108fef9b487809cdeb772439ce932e74136365c69baf", + "sha256:265462c77dc9576267c3c7f20707780a171a9fdbac93ac22e608c309efd68c33", + "sha256:298aa423e07c8b21b991782f01d7749c871c792319c2af3e9755f9ab49033212", + "sha256:2e08a4015d5d1aab2cb46c780e85b33efcd5cbe880bb363b282a6972e617b8bb", + "sha256:2f5876a5682ce1f517e55d7ace2383432627889f6f7e338b961f99d684fd9e8d", + "sha256:317b68b56a9c3731e0cf8886e0f94230727159e375988b36c60edce0ddbcb44a", + "sha256:32d445ce20d25c60ab92153c073942b0bac9815bfbfd152ce3dcc225d15ce988", + "sha256:4149e17018af07a5756a1df84aea71e6e178598c358c860c6bfec42170fa7970", + "sha256:43e1e18279759897be3293a255d53e6b1cb0364b69d9591d0b80c51e461c94b0", + "sha256:4a99acc273d2f98add23a89b94d4dd9e14969c01214c8514bfa78e4e9364c7e2", + "sha256:4d3843143c46dddca6491a954bbd0abfd435681512ac343169560e9bab504129", + "sha256:503e7ff507c2089699d91885fc5b9c8ff16774a7b6aff48b4dcee0c0a0685b61", + "sha256:520a814ea1b2706c89ab260a54023033d3015abef25c77873b83e3d7c1fafbb2", + "sha256:5886e23ede3478ca2a3e0a641f5d09dd784dfa9e48c96e8e5e31fc4fe77b6dc0", + "sha256:64c205ea37b8c4ba232645335fc3b75bc2d03ce30f0a34649e36cae85652ee96", + "sha256:667b150fedb54acdca2a4bea5bf6da837b43e6dd12857301b48191f8803ba93f", + "sha256:6895e3e84119594ab12847c928f619d40ae9cedd0755515dc154a5b5dc6edd9f", + "sha256:6dae82ab647d107817e013db82223e20a9853fa88543fec853ae326382d03c2e", + "sha256:7751bf745d54e9e8b358c0afa332815da9b8a6194b26d0fd62876ab6c4d5c9c0", + "sha256:7c29616e18e2349a8766d5b6817920fc74e39c00fa375d202231e9d525a1b882", + "sha256:806672529a2e255cd901f244c9033767dc1fa53466d0d3e3e49565a1572a64fe", + "sha256:8243664438bb468408b29c6865958662d75e51f79c91842d2794fa22629eb697", + "sha256:84788f4d62a8b1bf5e499bb9b0e23ceceea21c415ad6030be6267ce3d639842f", + "sha256:8f936566ef9f09136a3d5db305961ef6d897b76b240c9ff4199144aed6dd4fe5", + "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad", + "sha256:9d26d79de1c63a8c6586c75967e09b0ff306aa7e944a1eaddb74595c9b1839ca", + "sha256:9db5e5b3ccdadaafa5730c2f9db44c38b013234c9ad01f87738907e19bdba268", + "sha256:ac2df0fa564356384515ed62cb6679f33f1f529435b16b0ec0f88414635dbe39", + "sha256:ac95ae4529d7d85b251f9cf0f961a8a408ba285875811268f469d824a3b0b15a", + "sha256:c0fca3025266d88d1b48be162a43b7c2d91c81cc5b3bee9f01194678ffb9969a", + "sha256:c1906ec6e26e6b803cd6aab28d420c87285b9c209ff2a69f82d12f82278f78bb", + "sha256:c1ceb6035a64cb00650e3ab203cf3faffac18576a3f3125c24df468b784077c7", + "sha256:c761d32d0c5d1fe5b71ac502e1bd5edec4598a7fc6f607b9b906b98e911148ce", + "sha256:c76caf539fa4941e1817b7c482c87c65c52a1903fea761e84525955c6106fafb", + "sha256:cac3e2b4101db296b150cb665e5461c03621e6ede6117fc9d5048c0ec96d6e7c", + "sha256:cedc989717c8b44a3881ac3d68ab5a95820448796c550de6a2149ed1525157f0", + "sha256:d0b6ff3ccde9b16bbc694a2b5facf2d8890554f3135ff626ed1429e270e3cc4f", + "sha256:d5fe7a6284e3dce87ae13a25029c53542dd27a28d151f3ef362ec4dd9c3e45fd", + "sha256:da3ae1028af240c0c46c79adf9c1acffecc6ed1701f2863b8132f5ceae6ae4b5", + "sha256:ddfab1c622342f2945942c5c2d6be327656980e8f2d2b2ce0c022d0aa3711361", + "sha256:dfb76674db946a74f0ca6e3b81caa8265e35dafe9b7005c7d2b8dd5bbd3825cf", + "sha256:dfe92412bd11104c4f0fb2da68653e6c45b41f7217319a83a8b66ed4f20148b3", + "sha256:e3391ae9c484736850bb44ef125cbad52fe2d1b69e42c95dc88c43af8ead2cc7", + "sha256:e43adb22def972a29d2b147999b56897116085777a0fea182fd93ee45730611e", + "sha256:e46bd09c944ec7a20868abd2b83d7d7abdaf427775e9df3089b9226a122b340f", + "sha256:eee7b0fc4fbab2c6585ea17606c6548be83919c70deea0865409fe9fc2d8cdce", + "sha256:ef768e14768eebe3bb1196c0dece8e14c1c6991605721214a0c3c68cf77eb216", + "sha256:f6927dda86425f97ffda36131f297b1a601c64a6ee6838bfa0e6d3149c2f0d9f" + ], + "markers": "python_version >= '3.9'", + "version": "==2.16.0" }, "toml": { "hashes": [ @@ -5022,19 +5202,19 @@ }, "tomli": { "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", + "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed" ], - "markers": "python_version >= '3.7'", - "version": "==2.0.1" + "markers": "python_version >= '3.8'", + "version": "==2.0.2" }, "tomli-w": { "hashes": [ - "sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463", - "sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9" + "sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7", + "sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33" ], - "markers": "python_version >= '3.7'", - "version": "==1.0.0" + "markers": "python_version >= '3.9'", + "version": "==1.1.0" }, "tomlkit": { "hashes": [ @@ -5063,11 +5243,11 @@ }, "types-awscrt": { "hashes": [ - "sha256:117ff2b1bb657f09d01b7e0ce3fe3fa6e039be12d30b826896182725c9ce85b1", - "sha256:9f7f47de68799cb2bcb9e486f48d77b9f58962b92fba43cb8860da70b3c57d1b" + "sha256:67a660c90bad360c339f6a79310cc17094d12472042c7ca5a41450aaf5fc9a54", + "sha256:b2c196bbd3226bab42d80fae13c34548de9ddc195f5a366d79c15d18e5897aa9" ], "markers": "python_version >= '3.8'", - "version": "==0.21.5" + "version": "==0.22.0" }, "types-beautifulsoup4": { "hashes": [ @@ -5088,12 +5268,12 @@ }, "types-docutils": { "hashes": [ - "sha256:5dd2aa5e2e06fcfa090020bc4115479b4dd28da3329ab708563ee29894bd3c0d", - "sha256:9c8ed6d90583944af00f6b5fa3aecc2101e20672f6b1a4a299c6bf7d1e47084d" + "sha256:48f804a2b50da3a1b1681c4ca1b6184416a6e4129e302d15c44e9d97c59b3365", + "sha256:4d9021422f2f3fca8b0726fb8949395f66a06c0d951479eb3b1387d75b134430" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.21.0.20240907" + "version": "==0.21.0.20241005" }, "types-html5lib": { "hashes": [ @@ -5150,12 +5330,12 @@ }, "types-paramiko": { "hashes": [ - "sha256:6f9b311c63c16c74b923529315e6c75585b323f910b121568d4b3e47cedaf321", - "sha256:e0e6c6c72abe922b035edd62741b4a1cd056ec50c548b2b9e17539bb27b2ba94" + "sha256:79dd9b2ee510b76a3b60d8ac1f3f348c45fcecf01347ca79e14db726bbfc442d", + "sha256:cda0aff4905fe8efe4b5448331a80e943d42a796bd4beb77a3eed3485bc96a85" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==3.5.0.20240918" + "version": "==3.5.0.20240928" }, "types-pillow": { "hashes": [ @@ -5168,12 +5348,12 @@ }, "types-protobuf": { "hashes": [ - "sha256:992d695315d11eb2d25e806122c9e1fd9fec282e96104f0a0cb9226cd5d90293", - "sha256:c04140bd3c761a55f4e661372b24a6f508169e0815f2b73da33f34b447ed7a8d" + "sha256:5cecf612ccdefb7dc95f7a51fb502902f20fc2e6681cd500184aaa1b3931d6a7", + "sha256:d181af8a256e5a91ce8d5adb53496e880efd9144c7d54483e3653332b60296f0" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.27.0.20240920" + "version": "==5.28.0.20240924" }, "types-psutil": { "hashes": [ @@ -5230,11 +5410,11 @@ }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", + "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446" ], "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" + "version": "==2.9.0.20241003" }, "types-pyyaml": { "hashes": [ @@ -5247,12 +5427,12 @@ }, "types-redis": { "hashes": [ - "sha256:0e7537e5c085fe96b7d468d5edae0cf667b4ba4b62c6e4a5dfc340bd3b868c23", - "sha256:4bab1a378dbf23c2c95c370dfdb89a8f033957c4fd1a53fee71b529c182fe008" + "sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e", + "sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.6.0.20240903" + "version": "==4.6.0.20241004" }, "types-requests": { "hashes": [ @@ -5265,11 +5445,11 @@ }, "types-s3transfer": { "hashes": [ - "sha256:60167a3bfb5c536ec6cdb5818f7f9a28edca9dc3e0b5ff85ae374526fc5e576e", - "sha256:7a3fec8cd632e2b5efb665a355ef93c2a87fdd5a45b74a949f95a9e628a86356" + "sha256:d34c5a82f531af95bb550927136ff5b737a1ed3087f90a59d545591dfde5b4cc", + "sha256:f761b2876ac4c208e6c6b75cdf5f6939009768be9950c545b11b0225e7703ee7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.2" + "version": "==0.10.3" }, "types-setuptools": { "hashes": [ @@ -5291,12 +5471,12 @@ }, "types-six": { "hashes": [ - "sha256:af2a105be6d504339bfed81319cc8e8697865f0ee5c6baa63658f127b33b9e63", - "sha256:cdf445b5161bf17753500713a475ab79a45bd0d87728b8bfcecd86e2fbf66402" + "sha256:16d9e3ab37abb7339d98ea2ba857b7098ff2a1f8e9d89795876075cab34c6e67", + "sha256:8de8698195ec96370be175864555df5313e6d47f6342bd44e7d31e8d0c60fa01" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.16.21.20240513" + "version": "==1.16.21.20241009" }, "types-urllib3": { "hashes": [ @@ -5417,19 +5597,19 @@ }, "uvicorn": { "hashes": [ - "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", - "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5" + "sha256:adc42d9cac80cf3e51af97c1851648066841e7cfb6993a4ca8de29ac1548ed41", + "sha256:f5167919867b161b7bcaf32646c6a94cdbd4c3aa2eb5c17d36bb9aa5cfd8c493" ], "markers": "python_version >= '3.8'", - "version": "==0.30.6" + "version": "==0.31.1" }, "virtualenv": { "hashes": [ - "sha256:4f3ac17b81fba3ce3bd6f4ead2749a72da5929c01774948e243db9ba41df4ff6", - "sha256:ce489cac131aa58f4b25e321d6d186171f78e6cb13fafbf32a840cee67733ff4" + "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48", + "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2" ], "markers": "python_version >= '3.7'", - "version": "==20.26.5" + "version": "==20.26.6" }, "waitress": { "hashes": [ @@ -5474,101 +5654,101 @@ }, "yarl": { "hashes": [ - "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49", - "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867", - "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520", - "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a", - "sha256:077da604852be488c9a05a524068cdae1e972b7dc02438161c32420fb4ec5e14", - "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a", - "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93", - "sha256:0ea9682124fc062e3d931c6911934a678cb28453f957ddccf51f568c2f2b5e05", - "sha256:0f351fa31234699d6084ff98283cb1e852270fe9e250a3b3bf7804eb493bd937", - "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74", - "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b", - "sha256:15439f3c5c72686b6c3ff235279630d08936ace67d0fe5c8d5bbc3ef06f5a420", - "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639", - "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089", - "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53", - "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e", - "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c", - "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e", - "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe", - "sha256:238a21849dd7554cb4d25a14ffbfa0ef380bb7ba201f45b144a14454a72ffa5a", - "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366", - "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63", - "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9", - "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145", - "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf", - "sha256:3257978c870728a52dcce8c2902bf01f6c53b65094b457bf87b2644ee6238ddc", - "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5", - "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff", - "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d", - "sha256:3ff6b1617aa39279fe18a76c8d165469c48b159931d9b48239065767ee455b2b", - "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00", - "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad", - "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92", - "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998", - "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91", - "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b", - "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a", - "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5", - "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff", - "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367", - "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa", - "sha256:61a5f2c14d0a1adfdd82258f756b23a550c13ba4c86c84106be4c111a3a4e413", - "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4", - "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45", - "sha256:67459cf8cf31da0e2cbdb4b040507e535d25cfbb1604ca76396a3a66b8ba37a6", - "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5", - "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df", - "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c", - "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318", - "sha256:7175a87ab8f7fbde37160a15e58e138ba3b2b0e05492d7351314a250d61b1591", - "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38", - "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8", - "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e", - "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804", - "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec", - "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6", - "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870", - "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83", - "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d", - "sha256:8418c053aeb236b20b0ab8fa6bacfc2feaaf7d4683dd96528610989c99723d5f", - "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909", - "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269", - "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26", - "sha256:8aef1b64da41d18026632d99a06b3fefe1d08e85dd81d849fa7c96301ed22f1b", - "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2", - "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7", - "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd", - "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68", - "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0", - "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786", - "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da", - "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc", - "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447", - "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239", - "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0", - "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84", - "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e", - "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef", - "sha256:ba444bdd4caa2a94456ef67a2f383710928820dd0117aae6650a4d17029fa25e", - "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82", - "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675", - "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26", - "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979", - "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46", - "sha256:dae7bd0daeb33aa3e79e72877d3d51052e8b19c9025ecf0374f542ea8ec120e4", - "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff", - "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27", - "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c", - "sha256:f3a6d90cab0bdf07df8f176eae3a07127daafcf7457b997b2bf46776da2c7eb7", - "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265", - "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79", - "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd" - ], - "markers": "python_version >= '3.8'", - "version": "==1.11.1" + "sha256:047b258e00b99091b6f90355521f026238c63bd76dcf996d93527bb13320eefd", + "sha256:06ff23462398333c78b6f4f8d3d70410d657a471c2c5bbe6086133be43fc8f1a", + "sha256:07f9eaf57719d6721ab15805d85f4b01a5b509a0868d7320134371bcb652152d", + "sha256:0aa92e3e30a04f9462a25077db689c4ac5ea9ab6cc68a2e563881b987d42f16d", + "sha256:0cf21f46a15d445417de8fc89f2568852cf57fe8ca1ab3d19ddb24d45c0383ae", + "sha256:0fd7b941dd1b00b5f0acb97455fea2c4b7aac2dd31ea43fb9d155e9bc7b78664", + "sha256:147e36331f6f63e08a14640acf12369e041e0751bb70d9362df68c2d9dcf0c87", + "sha256:16a682a127930f3fc4e42583becca6049e1d7214bcad23520c590edd741d2114", + "sha256:176110bff341b6730f64a1eb3a7070e12b373cf1c910a9337e7c3240497db76f", + "sha256:19268b4fec1d7760134f2de46ef2608c2920134fb1fa61e451f679e41356dc55", + "sha256:1b16f6c75cffc2dc0616ea295abb0e1967601bd1fb1e0af6a1de1c6c887f3439", + "sha256:1bfc25aa6a7c99cf86564210f79a0b7d4484159c67e01232b116e445b3036547", + "sha256:1ca3894e9e9f72da93544f64988d9c052254a338a9f855165f37f51edb6591de", + "sha256:1dda53508df0de87b6e6b0a52d6718ff6c62a5aca8f5552748404963df639269", + "sha256:217a782020b875538eebf3948fac3a7f9bbbd0fd9bf8538f7c2ad7489e80f4e8", + "sha256:2192f718db4a8509f63dd6d950f143279211fa7e6a2c612edc17d85bf043d36e", + "sha256:29a84a46ec3ebae7a1c024c055612b11e9363a8a23238b3e905552d77a2bc51b", + "sha256:3007a5b75cb50140708420fe688c393e71139324df599434633019314ceb8b59", + "sha256:30600ba5db60f7c0820ef38a2568bb7379e1418ecc947a0f76fd8b2ff4257a97", + "sha256:337912bcdcf193ade64b9aae5a4017a0a1950caf8ca140362e361543c6773f21", + "sha256:37001e5d4621cef710c8dc1429ca04e189e572f128ab12312eab4e04cf007132", + "sha256:3d569f877ed9a708e4c71a2d13d2940cb0791da309f70bd970ac1a5c088a0a92", + "sha256:4009def9be3a7e5175db20aa2d7307ecd00bbf50f7f0f989300710eee1d0b0b9", + "sha256:46a9772a1efa93f9cd170ad33101c1817c77e0e9914d4fe33e2da299d7cf0f9b", + "sha256:47eede5d11d669ab3759b63afb70d28d5328c14744b8edba3323e27dc52d298d", + "sha256:498b3c55087b9d762636bca9b45f60d37e51d24341786dc01b81253f9552a607", + "sha256:4e0d45ebf975634468682c8bec021618b3ad52c37619e5c938f8f831fa1ac5c0", + "sha256:4f24f08b6c9b9818fd80612c97857d28f9779f0d1211653ece9844fc7b414df2", + "sha256:55c144d363ad4626ca744556c049c94e2b95096041ac87098bb363dcc8635e8d", + "sha256:582cedde49603f139be572252a318b30dc41039bc0b8165f070f279e5d12187f", + "sha256:587c3cc59bc148a9b1c07a019346eda2549bc9f468acd2f9824d185749acf0a6", + "sha256:5cd5dad8366e0168e0fd23d10705a603790484a6dbb9eb272b33673b8f2cce72", + "sha256:5d02d700705d67e09e1f57681f758f0b9d4412eeb70b2eb8d96ca6200b486db3", + "sha256:625f207b1799e95e7c823f42f473c1e9dbfb6192bd56bba8695656d92be4535f", + "sha256:659603d26d40dd4463200df9bfbc339fbfaed3fe32e5c432fe1dc2b5d4aa94b4", + "sha256:689a99a42ee4583fcb0d3a67a0204664aa1539684aed72bdafcbd505197a91c4", + "sha256:68ac1a09392ed6e3fd14be880d39b951d7b981fd135416db7d18a6208c536561", + "sha256:6a615cad11ec3428020fb3c5a88d85ce1b5c69fd66e9fcb91a7daa5e855325dd", + "sha256:73bedd2be05f48af19f0f2e9e1353921ce0c83f4a1c9e8556ecdcf1f1eae4892", + "sha256:742aef0a99844faaac200564ea6f5e08facb285d37ea18bd1a5acf2771f3255a", + "sha256:75ff4c819757f9bdb35de049a509814d6ce851fe26f06eb95a392a5640052482", + "sha256:781e2495e408a81e4eaeedeb41ba32b63b1980dddf8b60dbbeff6036bcd35049", + "sha256:7a9f917966d27f7ce30039fe8d900f913c5304134096554fd9bea0774bcda6d1", + "sha256:7e2637d75e92763d1322cb5041573279ec43a80c0f7fbbd2d64f5aee98447b17", + "sha256:8089d4634d8fa2b1806ce44fefa4979b1ab2c12c0bc7ef3dfa45c8a374811348", + "sha256:816d24f584edefcc5ca63428f0b38fee00b39fe64e3c5e558f895a18983efe96", + "sha256:8385ab36bf812e9d37cf7613999a87715f27ef67a53f0687d28c44b819df7cb0", + "sha256:85cb3e40eaa98489f1e2e8b29f5ad02ee1ee40d6ce6b88d50cf0f205de1d9d2c", + "sha256:8648180b34faaea4aa5b5ca7e871d9eb1277033fa439693855cf0ea9195f85f1", + "sha256:8892fa575ac9b1b25fae7b221bc4792a273877b9b56a99ee2d8d03eeb3dbb1d2", + "sha256:88c7d9d58aab0724b979ab5617330acb1c7030b79379c8138c1c8c94e121d1b3", + "sha256:8a2f8fb7f944bcdfecd4e8d855f84c703804a594da5123dd206f75036e536d4d", + "sha256:8f4e475f29a9122f908d0f1f706e1f2fc3656536ffd21014ff8a6f2e1b14d1d8", + "sha256:8f50eb3837012a937a2b649ec872b66ba9541ad9d6f103ddcafb8231cfcafd22", + "sha256:91d875f75fabf76b3018c5f196bf3d308ed2b49ddcb46c1576d6b075754a1393", + "sha256:94b2bb9bcfd5be9d27004ea4398fb640373dd0c1a9e219084f42c08f77a720ab", + "sha256:9557c9322aaa33174d285b0c1961fb32499d65ad1866155b7845edc876c3c835", + "sha256:95e16e9eaa2d7f5d87421b8fe694dd71606aa61d74b824c8d17fc85cc51983d1", + "sha256:96952f642ac69075e44c7d0284528938fdff39422a1d90d3e45ce40b72e5e2d9", + "sha256:985623575e5c4ea763056ffe0e2d63836f771a8c294b3de06d09480538316b13", + "sha256:99ff3744f5fe48288be6bc402533b38e89749623a43208e1d57091fc96b783b9", + "sha256:9abe80ae2c9d37c17599557b712e6515f4100a80efb2cda15f5f070306477cd2", + "sha256:a152751af7ef7b5d5fa6d215756e508dd05eb07d0cf2ba51f3e740076aa74373", + "sha256:a2e4725a08cb2b4794db09e350c86dee18202bb8286527210e13a1514dc9a59a", + "sha256:a56fbe3d7f3bce1d060ea18d2413a2ca9ca814eea7cedc4d247b5f338d54844e", + "sha256:ab3abc0b78a5dfaa4795a6afbe7b282b6aa88d81cf8c1bb5e394993d7cae3457", + "sha256:b03384eed107dbeb5f625a99dc3a7de8be04fc8480c9ad42fccbc73434170b20", + "sha256:b0547ab1e9345dc468cac8368d88ea4c5bd473ebc1d8d755347d7401982b5dd8", + "sha256:b4c1ecba93e7826dc71ddba75fb7740cdb52e7bd0be9f03136b83f54e6a1f511", + "sha256:b693c63e7e64b524f54aa4888403c680342d1ad0d97be1707c531584d6aeeb4f", + "sha256:b6d0147574ce2e7b812c989e50fa72bbc5338045411a836bd066ce5fc8ac0bce", + "sha256:b9cfef3f14f75bf6aba73a76caf61f9d00865912a04a4393c468a7ce0981b519", + "sha256:b9f805e37ed16cc212fdc538a608422d7517e7faf539bedea4fe69425bc55d76", + "sha256:bab03192091681d54e8225c53f270b0517637915d9297028409a2a5114ff4634", + "sha256:bc24f968b82455f336b79bf37dbb243b7d76cd40897489888d663d4e028f5069", + "sha256:c14b504a74e58e2deb0378b3eca10f3d076635c100f45b113c18c770b4a47a50", + "sha256:c2089a9afef887664115f7fa6d3c0edd6454adaca5488dba836ca91f60401075", + "sha256:c8ed4034f0765f8861620c1f2f2364d2e58520ea288497084dae880424fc0d9f", + "sha256:cd2660c01367eb3ef081b8fa0a5da7fe767f9427aa82023a961a5f28f0d4af6c", + "sha256:d8361c7d04e6a264481f0b802e395f647cd3f8bbe27acfa7c12049efea675bd1", + "sha256:d9baec588f015d0ee564057aa7574313c53a530662ffad930b7886becc85abdf", + "sha256:dbd9ff43a04f8ffe8a959a944c2dca10d22f5f99fc6a459f49c3ebfb409309d9", + "sha256:e3f8bfc1db82589ef965ed234b87de30d140db8b6dc50ada9e33951ccd8ec07a", + "sha256:e6a2c5c5bb2556dfbfffffc2bcfb9c235fd2b566d5006dfb2a37afc7e3278a07", + "sha256:e749af6c912a7bb441d105c50c1a3da720474e8acb91c89350080dd600228f0e", + "sha256:e85d86527baebb41a214cc3b45c17177177d900a2ad5783dbe6f291642d4906f", + "sha256:ee2c68e4f2dd1b1c15b849ba1c96fac105fca6ffdb7c1e8be51da6fabbdeafb9", + "sha256:f3ab950f8814f3b7b5e3eebc117986f817ec933676f68f0a6c5b2137dd7c9c69", + "sha256:f4f4547944d4f5cfcdc03f3f097d6f05bbbc915eaaf80a2ee120d0e756de377d", + "sha256:f72a0d746d38cb299b79ce3d4d60ba0892c84bbc905d0d49c13df5bace1b65f8", + "sha256:fc2c80bc87fba076e6cbb926216c27fba274dae7100a7b9a0983b53132dd99f2", + "sha256:fe4d2536c827f508348d7b40c08767e8c7071614250927233bf0c92170451c0a" + ], + "markers": "python_version >= '3.8'", + "version": "==1.14.0" }, "zipp": { "hashes": [ diff --git a/WORKSPACE b/WORKSPACE index 0bc810af28c..30e2ca2bc59 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -280,36 +280,6 @@ http_archive( url = "https://github.com/google/googletest/archive/57e107a10ea4ff5d8d31df9e4833f80b414b0dd2.tar.gz", ) -http_archive( - name = "rules_proto", - sha256 = "6fb6767d1bef535310547e03247f7518b03487740c11b6c6adb7952033fe1295", - strip_prefix = "rules_proto-6.0.2", - url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.2/rules_proto-6.0.2.tar.gz", -) - -load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies") - -rules_proto_dependencies() - -load("@rules_proto//proto:setup.bzl", "rules_proto_setup") - -rules_proto_setup() - -load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains") - -rules_proto_toolchains() - -http_archive( - name = "com_google_protobuf", - sha256 = "76637ddb08533dc6bffbd382e2614b119b8f84d16a025f7516cf2f833d103c12", - strip_prefix = "protobuf-3d9f7c430a5ae1385512908801492d4421c3cdb7", - url = "https://github.com/protocolbuffers/protobuf/archive/3d9f7c430a5ae1385512908801492d4421c3cdb7.tar.gz", -) - -load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") - -protobuf_deps() - load("//omd/packages/redfish_mkp:redfish_mkp_http.bzl", "redfish_mkp_workspace") redfish_mkp_workspace() diff --git a/agents/check_mk_agent.linux b/agents/check_mk_agent.linux index 27a1dc61403..531253dcb8e 100755 --- a/agents/check_mk_agent.linux +++ b/agents/check_mk_agent.linux @@ -1043,15 +1043,9 @@ section_drbd() { } section_heartbeat() { - if command -v crm_mon >/dev/null 2>&1 || [ -S /var/run/heartbeat/crm/cib_ro ] || [ -S /var/run/crm/cib_ro ] || pgrep "^(crmd|pacemaker-contr)$" >/dev/null 2>&1; then - crm_output=$(TZ=UTC crm_mon -1 -r | grep -v ^$ | sed 's/^ //; /^\sResource Group:/,$ s/^\s//; s/^\s/_/g') - if [ -n "$crm_output" ]; then - echo '<<>>' - echo "$crm_output" - else - echo '<<>>' - crm_mon -1 -r 2>&1 - fi + if [ -S /var/run/heartbeat/crm/cib_ro ] || [ -S /var/run/crm/cib_ro ] || pgrep "^(crmd|pacemaker-contr)$" >/dev/null 2>&1; then + echo '<<>>' + TZ=UTC crm_mon -1 -r | grep -v ^$ | sed 's/^ //; /^\sResource Group:/,$ s/^\s//; s/^\s/_/g' fi if inpath cl_status; then diff --git a/agents/modules/windows/clean_environment.cmd b/agents/modules/windows/clean_environment.cmd index a8f1e156c31..5657d88c9d3 100644 --- a/agents/modules/windows/clean_environment.cmd +++ b/agents/modules/windows/clean_environment.cmd @@ -21,7 +21,8 @@ powershell Write-Host "cabs" -foreground white del /Q python-3.cab del /Q python-3.8.cab powershell Write-Host "root files" -foreground white -del /Q *.* +del /Q *.txt +del /Q Pipfile.* powershell Write-Host "root folders" -foreground white rd /q /s libs rd /q /s tools diff --git a/agents/modules/windows/save_python.cmd b/agents/modules/windows/save_python.cmd index 3c75c7fc276..8e080254d1a 100644 --- a/agents/modules/windows/save_python.cmd +++ b/agents/modules/windows/save_python.cmd @@ -18,6 +18,7 @@ powershell Write-Host "save_dir should point on valid path with tmp inside" -for exit /b 4 :processing +rd /q /s "%save_dir%" mkdir %save_dir% 2> nul set last_dir=%cd% cd %save_dir% || Powershell Write-Host "`'%save_dir%`' absent" -Foreground red && exit /b 5 diff --git a/agents/modules/windows/tests/pyproject.toml b/agents/modules/windows/tests/pyproject.toml index 7dfc18717d8..a14d993b957 100644 --- a/agents/modules/windows/tests/pyproject.toml +++ b/agents/modules/windows/tests/pyproject.toml @@ -9,7 +9,7 @@ addopts = [ # successful, etc. etc. We might reconsinder lowering the live log level when we # have cleaned up things... "--log-cli-level=CRITICAL", - "--log-cli-format=\"%(asctime)s %(levelname)s %(message)s\"", + "--log-cli-format=%(asctime)s %(levelname)s %(message)s", # Show summary of skipped tests "-rs", # Show N slowest setup/test durations diff --git a/agents/plugins/mk_logwatch.py b/agents/plugins/mk_logwatch.py index d1d297eebfe..6994151cb63 100755 --- a/agents/plugins/mk_logwatch.py +++ b/agents/plugins/mk_logwatch.py @@ -8,7 +8,7 @@ agent without arguments. Options: - -d Debug mode: Colored output, no saving of status. + -d Debug mode: No saving of status. -c CONFIG_FILE Use this config file -h Show help. --no_state No state @@ -82,15 +82,6 @@ (b"\xfe\xff", "utf_16_be"), ) -TTY_COLORS = { - "C": "\033[1;31m", # red - "W": "\033[1;33m", # yellow - "O": "\033[1;32m", # green - "I": "\033[1;34m", # blue - ".": "", # remain same - "normal": "\033[0m", -} - CONFIG_ERROR_PREFIX = "CANNOT READ CONFIG FILE: " # detected by check plug-in PY2 = sys.version_info[0] == 2 @@ -621,11 +612,7 @@ def get_formatted_line(line, level): # type: (text_type, str) -> text_type formatted_line = "%s %s" % (level, line) if sys.stdout.isatty(): - formatted_line = "%s%s%s" % ( - TTY_COLORS[level], - formatted_line.replace("\1", "\nCONT:"), - TTY_COLORS["normal"], - ) + formatted_line = formatted_line.replace("\1", "\nCONT:") return formatted_line @@ -797,13 +784,8 @@ def process_logfile(section, filestate, debug): # pylint: disable=too-many-bran offset_wrap = new_offset // section.options.maxfilesize if ((offset or 0) // section.options.maxfilesize) < offset_wrap: warnings_and_errors.append( - "%sW Maximum allowed logfile size (%d bytes) exceeded for the %dth time.%s\n" - % ( - TTY_COLORS["W"] if sys.stdout.isatty() else "", - section.options.maxfilesize, - offset_wrap, - TTY_COLORS["normal"] if sys.stdout.isatty() else "", - ) + "W Maximum allowed logfile size (%d bytes) exceeded for the %dth time.\n" + % (section.options.maxfilesize, offset_wrap) ) # output all lines if at least one warning, error or ok has been found @@ -1168,7 +1150,7 @@ def _filter_maxcontextlines(lines_list, before, after): if new_in_context_idx < n_lines and context_end < n_lines: new_in_context = lines_list[new_in_context_idx] # if the line ahead is relevant, extend the context - if new_in_context.startswith(("C", "W")): + if new_in_context.startswith(("C", "W", "O")): context_end = new_in_context_idx + after if 0 <= idx <= context_end: yield lines_list[idx] diff --git a/agents/plugins/mk_postgres.py b/agents/plugins/mk_postgres.py index e3a2b630b3a..95a9da5b342 100755 --- a/agents/plugins/mk_postgres.py +++ b/agents/plugins/mk_postgres.py @@ -63,8 +63,10 @@ import os import platform import re +import stat import subprocess import sys +import tempfile try: from collections.abc import Callable, Iterable, Sequence # pylint: disable=unused-import @@ -776,11 +778,17 @@ def get_bloat(self, databases, numeric_version): class PostgresLinux(PostgresBase): - def run_sql_as_db_user( - self, sql_cmd, extra_args="", field_sep=";", quiet=True, rows_only=True, mixed_cmd=False + def _run_sql_as_db_user( + self, sql_file_path, extra_args="", field_sep=";", quiet=True, rows_only=True ): - # type: (str, str, str, bool, bool, bool) -> str - base_cmd_list = ["su", "-", self.db_user, "-c", r"""PGPASSFILE=%s %s -X %s -A0 -F'%s'%s"""] + # type: (str, str, str, bool, bool) -> str + base_cmd_list = [ + "su", + "-", + self.db_user, + "-c", + r"""PGPASSFILE=%s %s -X %s -A0 -F'%s' -f %s""", + ] extra_args += " -U %s" % self.pg_user extra_args += " -d %s" % self.pg_database extra_args += " -p %s" % self.pg_port @@ -790,40 +798,36 @@ def run_sql_as_db_user( if rows_only: extra_args += " -t" - # In case we want to use postgres meta commands AND SQL queries in one call, we need to pipe - # the full cmd string into psql executable - # see https://www.postgresql.org/docs/9.2/app-psql.html - if mixed_cmd: - cmd_to_pipe = subprocess.Popen( # pylint: disable=consider-using-with - ["echo", sql_cmd], stdout=subprocess.PIPE - ) - base_cmd_list[-1] = base_cmd_list[-1] % ( - self.pg_passfile, - self.psql_binary_path, - extra_args, - field_sep, - "", - ) - - receiving_pipe = subprocess.Popen( # pylint: disable=consider-using-with - base_cmd_list, stdin=cmd_to_pipe.stdout, stdout=subprocess.PIPE, env=self.my_env - ) - out = receiving_pipe.communicate()[0] + base_cmd_list[-1] = base_cmd_list[-1] % ( + self.pg_passfile, + self.psql_binary_path, + extra_args, + field_sep, + sql_file_path, + ) + proc = subprocess.Popen( # pylint: disable=consider-using-with + base_cmd_list, env=self.my_env, stdout=subprocess.PIPE + ) + return _sanitize_sql_query(proc.communicate()[0]) - else: - base_cmd_list[-1] = base_cmd_list[-1] % ( - self.pg_passfile, - self.psql_binary_path, - extra_args, - field_sep, - ' -c "%s" ' % sql_cmd, - ) - proc = subprocess.Popen( # pylint: disable=consider-using-with - base_cmd_list, env=self.my_env, stdout=subprocess.PIPE + def run_sql_as_db_user( + self, sql_cmd, extra_args="", field_sep=";", quiet=True, rows_only=True, mixed_cmd=False + ): + # type: (str, str, str, bool, bool, bool) -> str + with tempfile.NamedTemporaryFile(delete=True) as tmp: + tmp.write(sql_cmd.encode("utf-8")) + # set cursor to the beginning of the file + tmp.seek(0) + # We use 'psql ... -f ', the tmp file has to be readable to all users, + # ie. stat.S_IROTH + os.chmod(tmp.name, stat.S_IROTH) + return self._run_sql_as_db_user( + tmp.name, + extra_args=extra_args, + field_sep=field_sep, + quiet=quiet, + rows_only=rows_only, ) - out = proc.communicate()[0] - - return _sanitize_sql_query(out) def get_psql_binary_path(self): # type: () -> str diff --git a/agents/plugins/smart b/agents/plugins/smart index b8a70899ccd..2629394f35f 100755 --- a/agents/plugins/smart +++ b/agents/plugins/smart @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # 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. @@ -64,27 +64,39 @@ megaraid_info() { done } +_tw_cli_drivestatus_to_port() { + tw_cli_driver_status="${1}" + device_name="${2}" + # - add a trailing zero to handle case of unused slot + # trailing zeros are part of the device links in /dev/disk/by-id/... anyway + echo "$tw_cli_driver_status" | grep -E '^p[0-9]' | awk '{print $1 " " $7 "0"}' | while read -r twaminor serial; do + # - only the last 9 chars seem to be relevant + # (hopefully all this doesn't change with new kernels...) + serial=$(echo "$serial" | sed -n -e 's/.*\(.\{9\}\)$/\1/p') + serial=AMCC_${serial}00000000000 + if [ "$serial" = "$device_name" ]; then + echo "${twaminor#p}" + break + fi + done +} + +_format_model_name() { + MODEL=$(echo "$1" | head -n 1 | awk -F= '{ print $2 }') + MODEL=${MODEL## } + echo "$MODEL" | sed -e "s/ /-/g" +} + main() { # Only handle always updated values, add device path and vendor/model if inpath smartctl >/dev/null 2>&1; then # - # if the 3ware-utility is found - # get the serials for all disks on the controller # if inpath tw_cli >/dev/null 2>&1; then # support for only one controller at the moment TWAC=$(tw_cli show | awk 'NR < 4 { next } { print $1 }' | head -n 1) - - # - add a trailing zero to handle case of unused slot - # trailing zeros are part of the device links in /dev/disk/by-id/... anyway - # - only the last 9 chars seem to be relevant - # (hopefully all this doesn't change with new kernels...) - eval "$(tw_cli /"$TWAC" show drivestatus | grep -E '^p[0-9]' | awk '{print $1 " " $7 "0"}' | while read -r twaminor serial; do - twaminor=${twaminor#p} - serial=${serial:(-9)} - serial=AMCC_${serial}00000000000 - echo "$serial=$twaminor" - done)" + # if the 3ware-utility is found, then we get ports via the drivestatus + TW_CLI_DRIVER_STATUS=$(tw_cli /"$TWAC" show drivestatus) else echo "tw_cli not found" >&2 fi @@ -120,12 +132,12 @@ main() { fi # Exclude everything which can read a CD - if [ "$INPATH_UDEVADM" == "udevadm_present" ] && (udevadm info /dev/"$N" | grep -Fxq 'E: ID_CDROM_CD=1'); then + if [ "$INPATH_UDEVADM" = "udevadm_present" ] && (udevadm info /dev/"$N" | grep -Fxq 'E: ID_CDROM_CD=1'); then continue fi # Avoid duplicate entries for same device - if [ "${SEEN//.$N./}" != "$SEEN" ]; then + if echo "$SEEN" | grep -q ".$N."; then continue fi SEEN="$SEEN.$N." @@ -135,18 +147,17 @@ main() { DNAME=${DNAME#"$BY_ID_PATH"/ata-} # 2012-01-25 Stefan Kaerst CDJ - special option in case vendor is AMCC CMD= - if [ "$VEND" == "AMCC" ] && [ -n "$TWAC" ]; then + if [ "$VEND" = "AMCC" ] && [ -n "$TWAC" ]; then DNAME=${DNAME#1} - [ -z "${!DNAME}" ] && continue - CMD="smartctl -d 3ware,${!DNAME} -v 9,raw48 -A /dev/twa0" + PORT=$(_tw_cli_drivestatus_to_port "$TW_CLI_DRIVER_STATUS" "$DNAME") + [ -z "$PORT" ] && continue + CMD="smartctl -d 3ware,$PORT, -v 9,raw48 -A /dev/twa0" # create nice device name including model - MODEL=$(tw_cli /"$TWAC"/p"${!DNAME}" show model | head -n 1 | awk -F= '{ print $2 }') - MODEL=${MODEL## } - MODEL=${MODEL// /-} + MODEL=_format_model_name "$(tw_cli /"$TWAC"/p"$PORT" show model)" DNAME=${DNAME#AMCC_} DNAME="AMCC_${MODEL}_${DNAME%000000000000}" elif [ "$VEND" != "ATA" ]; then - if [ "$VEND" == "NVME" ]; then + if [ "$VEND" = "NVME" ]; then DNAME="/dev/$N" CMD="smartctl -d nvme -A $DNAME" else @@ -154,17 +165,17 @@ main() { # create temperature output as expected by checks/smart # this is a hack, TODO: change checks/smart to support SCSI-disks eval "$(smartctl -d scsi -i -A "$D" | while read -r a b c d _; do - [ "$a" == Serial ] && echo SN="$c" - [ "$a" == Current ] && [ "$b" == Drive ] && [ "$c" == Temperature: ] && echo TEMP="$d" + [ "$a" = Serial ] && echo SN="$c" + [ "$a" = Current ] && [ "$b" = Drive ] && [ "$c" = Temperature: ] && echo TEMP="$d" done)" - [ -n "$TEMP" ] && CMD="echo 194 Temperature_Celsius 0x0000 000 000 000 Old_age Always - $TEMP (0 0 0 0)" + [ -n "$TEMP" ] && CMD="echo 194 Temperature_Celsius 0x0000 000 000 000 Old_age Always - $TEMP \(0 0 0 0\)" DNAME="${VEND}_${MODEL}_${SN}" fi else CMD="smartctl -d ata -v 9,raw48 -A $D; smartctl -d sat -v 9,raw48 -A $D" fi - if [ "$VEND" == "NVME" ]; then + if [ "$VEND" = "NVME" ]; then echo "$DNAME $VEND $MODEL" [ -n "$CMD" ] && eval "$CMD" | sed -e '1,5d; /^$/d' else diff --git a/agents/windows/plugins/mk_inventory.vbs b/agents/windows/plugins/mk_inventory.vbs index 0a9fbfb7351..f4c8eb16227 100644 --- a/agents/windows/plugins/mk_inventory.vbs +++ b/agents/windows/plugins/mk_inventory.vbs @@ -87,6 +87,17 @@ Sub startSection(name,sep,timeUntil) End Sub +Function poorMansJson(valuesDict) + Dim serialized + + serialized = "" + For Each key in valuesDict.Keys + serialized = serialized & ", """ & Replace(key, """", "\\""") & """:""" & Replace(valuesDict.Item(key), """", "\\""") & """" + Next + poorMansJson = "{" & Mid(serialized, 2) & "}" +End Function + + Sub getWMIObject(strClass,arrVars) Set objClass = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set Entries = objClass.ExecQuery("Select * from " & strClass) @@ -236,34 +247,26 @@ Sub SoftwareFromInstaller(fields) Dim IteratedItem, productCode For Each IteratedItem In oProducts On Error Resume Next + Dim values : Set values = CreateObject("Scripting.Dictionary") if productsEx then ' ProductEx function Err.clear() Dim oProduct : Set oProduct = IteratedItem productCode = oProduct.ProductCode - values = fields ' copy - idx = 0 For Each field In fields - values(idx) = oProduct.InstallProperty(field) - idx = idx + 1 + values.Add field, oProduct.InstallProperty(field) Next - - outPut(Join(values, "|")) else 'Products function Err.clear() productCode = IteratedItem - values = fields ' copy - idx = 0 For Each field In fields - values(idx) = oInstaller.ProductInfo(productCode, field) - idx = idx + 1 + values.Add field, oInstaller.ProductInfo(productCode, field) Next - - outPut(Join(values, "|")) end if + outPut(poorMansJson(values)) Next End Sub @@ -321,7 +324,7 @@ Call startSection("win_ip_r",124,timeUntil) Call getRouteTable() ' Installed Software -Call startSection("win_wmi_software",124,timeUntil) +Call startSection("win_wmi_software_json",0,timeUntil) swVars = Array( "ProductName", "Publisher", "VersionString", "InstallDate", "Language") Call SoftwareFromInstaller(swVars) @@ -335,7 +338,7 @@ Do While Not objExecObject.StdOut.AtEndOfStream Loop ' Search Registry -Call startSection("win_reg_uninstall",124,timeUntil) +Call startSection("win_reg_uninstall_json",0,timeUntil) Set rego = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv") regVars = Array("DisplayName", "Publisher", "InstallLocation", "PSChildName", "DisplayVersion", "EstimatedSize", "InstallDate", "Language") @@ -345,6 +348,7 @@ For Each path in regPaths For Each strIdentityCode in arrIdentityCode strOut = "" boleanContent = False + Dim values : Set values = CreateObject("Scripting.Dictionary") For Each var in regVars ' PSChildName is the name in powershell ' We use strIdentityCode in vbs @@ -359,17 +363,17 @@ For Each path in regPaths End If ' Only allow vartypes which can be represented as a string If VarType(value) <= 8 and VarType(value) > 1 Then - strOut = strOut & "|" & CStr(value) + values.Add var, CStr(value) ' Only print a line when more than only PSChildName is present If var <> "PSChildName" Then boleanContent = True End If Else - strOut = strOut & "|" + values.Add var, "" End If Next If boleanContent Then - outPut(Mid(strOut,2)) + outPut(poorMansJson(values)) End If Next End If diff --git a/agents/wnx/src/engine/extensions.cpp b/agents/wnx/src/engine/extensions.cpp index cff8810b91d..9bd7e3112ff 100644 --- a/agents/wnx/src/engine/extensions.cpp +++ b/agents/wnx/src/engine/extensions.cpp @@ -68,10 +68,7 @@ std::vector GatherExtensions(const YAML::Node &group) { const auto command_line = GetVal(entry, vars::kExecutionCmdLine, ""); auto mode = GetVal(entry, vars::kExecutionRun, ""); - exts.emplace_back(Extension{.name = name, - .binary = FindBinary(binary), - .command_line = command_line, - .mode = ToMode(mode)}); + exts.emplace_back(name, FindBinary(binary), command_line, ToMode(mode)); } return exts; } diff --git a/bin/check_mk b/bin/check_mk index 3331afc2ad8..a78100405cf 100755 --- a/bin/check_mk +++ b/bin/check_mk @@ -30,18 +30,20 @@ import cmk.ccc.debug import cmk.ccc.version as cmk_version from cmk.ccc.crash_reporting import ABCCrashReport, crash_report_registry, CrashReportStore from cmk.ccc.exceptions import MKBailOut, MKGeneralException, MKTerminate +from cmk.ccc.site import get_omd_config, omd_site import cmk.utils.caching import cmk.utils.log import cmk.utils.paths from cmk.utils.log import console -import cmk.base.check_api as check_api -import cmk.base.config as config -import cmk.base.profiling as profiling import cmk.base.utils +from cmk.base import check_api, config, profiling from cmk.base.modes import modes +from cmk import trace +from cmk.trace.export import exporter_from_config, init_span_processor + cmk.utils.log.setup_console_logging() logger = logging.getLogger("cmk.base") @@ -49,6 +51,19 @@ cmk.base.utils.register_sigint_handler() help_function = modes.get("help").handler_function +# Would be nice if we could enable tracing in all cases. But the current timeout and retry +# logic of the Opentelemetry SDK does not work as intended, which can lead to longer hanging +# executions in case the configured collector (e.g. Jaeger) is not reachable. +# For now only enable tracing in case the caller provides a tracing context. This way we produce +# traces only when the caller is interested in them. +# This condition can be removed once the timeout and retry logic was fixed +# (https://github.com/open-telemetry/opentelemetry-python/issues/4043). +if trace_context := trace.extract_context_from_environment(dict(os.environ)): + init_span_processor( + trace.init_tracing(omd_site(), "cmk"), + exporter_from_config(trace.trace_send_config(get_omd_config(cmk.utils.paths.omd_root))), + ) + # We probably don't really need to register that here, do we? @crash_report_registry.register @@ -121,13 +136,13 @@ try: done, exit_status = False, 0 if mode_name is not None and mode_args is not None: - exit_status = modes.call(mode_name, mode_args, opts, args) + exit_status = modes.call(mode_name, mode_args, opts, args, trace_context) done = True # When no mode was found, Checkmk is running the "check" mode if not done: if (args and len(args) <= 2) or "--keepalive" in [o[0] for o in opts]: - exit_status = modes.call("--check", None, opts, args) + exit_status = modes.call("--check", None, opts, args, trace_context) else: help_function = modes.get("help").handler_function if help_function is None: diff --git a/bin/message-broker-certs b/bin/message-broker-certs index 6786287b616..f2929da8516 100755 --- a/bin/message-broker-certs +++ b/bin/message-broker-certs @@ -2,6 +2,7 @@ # 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. +"""Ensure the message broker certificates are created""" import argparse import logging @@ -11,13 +12,14 @@ from pathlib import Path from dateutil.relativedelta import relativedelta -from cmk.utils.certs import CN_TEMPLATE - from cmk import messaging from cmk.crypto.certificate import CertificateWithPrivateKey, PersistedCertificateWithPrivateKey +_CN_TEMPLATE = "Site '{}' broker CA" +_ORG_TEMPLATE = "Checkmk Site {}" + -@dataclass +@dataclass(frozen=True) class Arguments: omd_root: Path site_name: str @@ -29,8 +31,8 @@ def initialize_message_broker_certs(omd_root: Path, site_name: str) -> None: """ ca = CertificateWithPrivateKey.generate_self_signed( - common_name=CN_TEMPLATE.format(site_name), - organization=f"Checkmk Site {site_name}", + common_name=_CN_TEMPLATE.format(site_name), + organization=_ORG_TEMPLATE.format(site_name), expiry=relativedelta(years=5), key_size=4096, is_ca=True, @@ -44,7 +46,7 @@ def initialize_message_broker_certs(omd_root: Path, site_name: str) -> None: bundle = ca.issue_new_certificate( common_name=site_name, # used for user identification - organization=f"Checkmk Site {site_name}", + organization=_ORG_TEMPLATE.format(site_name), expiry=relativedelta(years=2), key_size=4096, ) @@ -52,31 +54,27 @@ def initialize_message_broker_certs(omd_root: Path, site_name: str) -> None: PersistedCertificateWithPrivateKey.persist( bundle, messaging.site_cert_file(omd_root), messaging.site_key_file(omd_root) ) + messaging.trusted_cas_file(omd_root).write_text(cacert_file.read_text()) def _parse_arguments(argv: list[str]) -> Arguments: - parser = argparse.ArgumentParser( - description="Ensure the message broker certificates are created" - ) - parser.add_argument("omd_root", type=Path, help="The OMD root directory") - parser.add_argument("site_name", type=str, help="The site name") + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("omd_root", help="The OMD root directory") + parser.add_argument("site_name", help="The site name") args = parser.parse_args(argv[1:]) return Arguments( - omd_root=args.omd_root, - site_name=args.site_name, + omd_root=Path(args.omd_root), + site_name=str(args.site_name), ) -def main(argv: list[str] | None = None) -> int: +def main(argv: list[str]) -> int: logger = logging.getLogger("cmk-message-broker-certs") logger.addHandler(handler := logging.StreamHandler(stream=sys.stdout)) handler.setFormatter(logging.Formatter("%(message)s")) logger.setLevel(logging.INFO) - if argv is None: - argv = sys.argv - try: args = _parse_arguments(argv) initialize_message_broker_certs(args.omd_root, args.site_name) @@ -88,4 +86,4 @@ def main(argv: list[str] | None = None) -> int: if __name__ == "__main__": - main() + main(sys.argv) diff --git a/buildscripts/docker_image_aliases/register.py b/buildscripts/docker_image_aliases/register.py index 34c32fea536..25873281564 100755 --- a/buildscripts/docker_image_aliases/register.py +++ b/buildscripts/docker_image_aliases/register.py @@ -28,7 +28,7 @@ from pathlib import Path from typing import List, Optional, Sequence, Tuple -import docker # type: ignore +import docker # type: ignore[import-untyped] import yaml LOG = logging.getLogger("register-dia") diff --git a/buildscripts/infrastructure/build-nodes/scripts/install-buildifier.sh b/buildscripts/infrastructure/build-nodes/scripts/install-buildifier.sh index 7af103ea7f6..fbef6ea8d3a 100755 --- a/buildscripts/infrastructure/build-nodes/scripts/install-buildifier.sh +++ b/buildscripts/infrastructure/build-nodes/scripts/install-buildifier.sh @@ -22,6 +22,10 @@ install_package() { } case "$DISTRO" in + ubuntu-20*) + echo "ERROR: Your version of go is too old for $DISTRO in order to install buildifier via 'go install ...'" + exit 1 + ;; ubuntu-*) install_package ;; diff --git a/buildscripts/infrastructure/build-nodes/scripts/install-development.sh b/buildscripts/infrastructure/build-nodes/scripts/install-development.sh index a39905b05e3..8bd1c0ee6dd 100755 --- a/buildscripts/infrastructure/build-nodes/scripts/install-development.sh +++ b/buildscripts/infrastructure/build-nodes/scripts/install-development.sh @@ -52,16 +52,17 @@ install_packages() { install_basic_tools() { print_green "Installing common basic tools ..." local PACKAGES_TO_INSTALL=( - "binutils" # "strip" required to cleanup during strip_binaries - "curl" # curl is used to download artifacts from Nexus - "doxygen" # to be able to create docs in the unlikely event - "gawk" # TBC - "git" # git is used by install-[bazel, cmake, iwyu, patchelf, protobuf-cpp].sh - "gnupg" # "apt-key" used by install-docker - "lsb-release" # lsb is used by install-[clang, docker, packer, nodejs].sh - "make" # don't forget your towel when you're taveling :) - "sudo" # some make calls require sudo - "wget" # wget is used by install-[clang, packer, protobuf-cpp].sh + "binutils" # "strip" required to cleanup during strip_binaries + "curl" # curl is used to download artifacts from Nexus + "doxygen" # to be able to create docs in the unlikely event + "gawk" # TBC + "git" # git is used by install-[bazel, cmake, iwyu, patchelf, protobuf-cpp].sh + "gnupg" # "apt-key" used by install-docker + "lsb-release" # lsb is used by install-[clang, docker, packer, nodejs].sh + "make" # don't forget your towel when you're taveling :) + "sudo" # some make calls require sudo + "wget" # wget is used by install-[clang, packer, protobuf-cpp].sh + "libglib2.0-dev" # required by packages/glib and therfore transitive by python unit tests ) install_packages "${PACKAGES_TO_INSTALL[@]}" print_green "Common basic tool installation done" @@ -372,6 +373,21 @@ install_for_localize_dev() { print_green "Installation for Localization development done" } +install_for_bazel() { + # install Bazel for package building + print_green "Installing Bazel/Bazelisk ..." + + export TARGET_DIR="${INSTALL_PATH}" + "${SCRIPT_DIR}"/install-bazel.sh + + install_packages golang-go + + # install_packages golang-go + "${SCRIPT_DIR}"/install-buildifier.sh + + print_green "Installation of Bazel/Bazelisk done" +} + POSITIONAL_ARGS=() PROFILE_ARGS=() INSTALL_PATH=/opt @@ -561,18 +577,9 @@ fi if [[ $REQUIRES_NEXUS -gt 0 || $INSTALL_FOR_BAZEL -eq 1 ]]; then # only localize or web is installed, which don't require nexus interactions - # install Bazel for package building - print_green "Installing Bazel/Bazelisk ..." - - export TARGET_DIR="${INSTALL_PATH}" - "${SCRIPT_DIR}"/install-bazel.sh - - print_green "Installation of Bazel/Bazelisk done" + install_for_bazel fi -# install_packages golang-go -# "${SCRIPT_DIR}"/install-buildifier.sh - perform_cleanup if [[ ${#IMPORTANT_MESSAGES[@]} -gt 0 ]]; then diff --git a/buildscripts/scripts/assert_build_artifacts.py b/buildscripts/scripts/assert_build_artifacts.py index eb397bf4288..41f32ce05af 100755 --- a/buildscripts/scripts/assert_build_artifacts.py +++ b/buildscripts/scripts/assert_build_artifacts.py @@ -9,7 +9,6 @@ from collections.abc import Iterator from pathlib import Path -import docker # type: ignore import requests sys.path.insert(0, Path(__file__).parent.parent.parent.as_posix()) @@ -95,6 +94,7 @@ def file_exists_on_download_server(filename: str, version: str, credentials: Cre requests.head( f"https://download.checkmk.com/checkmk/{version}/{filename}", auth=(credentials.username, credentials.password), + timeout=10, ).status_code != 200 ): diff --git a/buildscripts/scripts/build-cmk-container.py b/buildscripts/scripts/build-cmk-container.py index 364bdeb025f..f310ba853c6 100644 --- a/buildscripts/scripts/build-cmk-container.py +++ b/buildscripts/scripts/build-cmk-container.py @@ -51,7 +51,7 @@ from tempfile import mkdtemp from typing import Union -import docker # type: ignore +import docker # type: ignore[import-untyped] sys.path.insert(0, Path(__file__).parent.parent.parent.as_posix()) from buildscripts.scripts.lib.common import cwd, strtobool @@ -127,13 +127,10 @@ def parse_arguments() -> argparse.Namespace: def run_cmd( cmd: Union[list[str], str], - shell: bool = False, raise_exception: bool = True, print_stdout: bool = True, ) -> subprocess.CompletedProcess: - completed_process = subprocess.run( - cmd, encoding="utf-8", capture_output=True, shell=shell, check=False - ) + completed_process = subprocess.run(cmd, encoding="utf-8", capture_output=True, check=False) if raise_exception and completed_process.returncode != 0: raise Exception( f"Failed to execute command '{' '.join(cmd)}' with: {completed_process.stdout}, {completed_process.stderr}" diff --git a/buildscripts/scripts/build-cmk-packages.groovy b/buildscripts/scripts/build-cmk-packages.groovy index 1335e6babd4..883656d353f 100644 --- a/buildscripts/scripts/build-cmk-packages.groovy +++ b/buildscripts/scripts/build-cmk-packages.groovy @@ -355,6 +355,14 @@ def main() { "${upload_path}", INTERNAL_DEPLOY_PORT, ); + + if (EDITION.toLowerCase() == "saas" && versioning.is_official_release(cmk_version_rc_aware)) { + // check-mk-saas-2.3.0p17*.deb + .hash + artifacts_helper.upload_files_to_nexus( + "${node_version_dir}/${cmk_version_rc_aware}/${package_name}*", + "${ARTIFACT_STORAGE}/repository/saas-patch-releases/", + ); + } } } @@ -392,6 +400,14 @@ def main() { if (deploy_to_website) { artifacts_helper.deploy_to_website(cmk_version_rc_aware); } + + if (EDITION.toLowerCase() == "saas" && versioning.is_official_release(cmk_version_rc_aware)) { + // check-mk-saas-2.3.0p17.cse.tar.gz + .hash + artifacts_helper.upload_files_to_nexus( + "${WORKSPACE}/versions/${cmk_version_rc_aware}/check-mk-saas-${cmk_version}*", + "${ARTIFACT_STORAGE}/repository/saas-patch-releases/", + ); + } } } } diff --git a/buildscripts/scripts/get_distros.py b/buildscripts/scripts/get_distros.py index a5c9de701cb..42183b581f5 100755 --- a/buildscripts/scripts/get_distros.py +++ b/buildscripts/scripts/get_distros.py @@ -9,8 +9,6 @@ from collections.abc import Iterable from pathlib import Path -import yaml - sys.path.insert(0, Path(__file__).parent.parent.parent.as_posix()) from buildscripts.scripts.lib.common import flatten, load_editions_file @@ -58,28 +56,30 @@ def print_editions(args: Args, loaded_yaml: dict) -> None: def test_distro_lists(): - with open(Path(__file__).parent.parent.parent / "editions.yml") as editions_file: - edition_distros = yaml.load(editions_file, Loader=yaml.FullLoader)["editions"] + edition_distros = load_editions_file(Path(__file__).parent.parent.parent / "editions.yml")[ + "editions" + ] + # fmt: off assert distros_for_use_case(edition_distros, "enterprise", "release") == [ "almalinux-9", "cma-4", "debian-11", "debian-12", - "sles-15sp3", "sles-15sp4", "sles-15sp5", + "sles-15sp3", "sles-15sp4", "sles-15sp5", "sles-15sp6", "ubuntu-22.04", "ubuntu-24.04", ] assert distros_for_use_case(edition_distros, "enterprise", "daily") == [ "almalinux-9", "cma-4", - "debian-12", - "sles-15sp5", - "ubuntu-22.04", "ubuntu-23.10", "ubuntu-24.04" + "debian-11", "debian-12", + "sles-15sp3", "sles-15sp4", "sles-15sp5", "sles-15sp6", + "ubuntu-22.04", "ubuntu-23.10", "ubuntu-24.04", ] assert distros_for_use_case(edition_distros, "all", "all") == [ "almalinux-9", "cma-4", "debian-11", "debian-12", - "sles-15sp3", "sles-15sp4", "sles-15sp5", + "sles-15sp3", "sles-15sp4", "sles-15sp5", "sles-15sp6", "ubuntu-22.04", "ubuntu-23.10", "ubuntu-24.04" ] # fmt: on diff --git a/buildscripts/scripts/lib/common.py b/buildscripts/scripts/lib/common.py index a28f8b23773..1777ab34f5f 100644 --- a/buildscripts/scripts/lib/common.py +++ b/buildscripts/scripts/lib/common.py @@ -42,7 +42,7 @@ def strtobool(val: str | bool) -> bool: def load_editions_file(filename: str | Path) -> dict: with open(filename) as editions_file: - return yaml.load(editions_file, Loader=yaml.FullLoader) + return yaml.safe_load(editions_file) @contextmanager diff --git a/buildscripts/scripts/lib/registry.py b/buildscripts/scripts/lib/registry.py index d7c6fe360ba..3c366938660 100644 --- a/buildscripts/scripts/lib/registry.py +++ b/buildscripts/scripts/lib/registry.py @@ -16,10 +16,10 @@ from typing import NamedTuple, Self, TypeAlias from urllib.parse import urlparse -import docker # type: ignore +import docker # type: ignore[import-untyped] import requests -from cmk.utils.version import BuildDate, ReleaseType, Version +from cmk.ccc.version import BuildDate, ReleaseType, Version sys.path.insert(0, Path(__file__).parent.parent.parent.parent.as_posix()) from tests.testlib.utils import get_cmk_download_credentials as _get_cmk_download_credentials diff --git a/buildscripts/scripts/pin_dependencies.py b/buildscripts/scripts/pin_dependencies.py index 0f21e1c816b..6d047621a61 100755 --- a/buildscripts/scripts/pin_dependencies.py +++ b/buildscripts/scripts/pin_dependencies.py @@ -9,7 +9,7 @@ import re from typing import Iterator -import pipfile # type: ignore +import pipfile # type: ignore[import-untyped] def insert_pinned_version(p_to_v: dict[str, str], args: argparse.Namespace) -> None: @@ -58,7 +58,7 @@ def parse_arguments() -> argparse.Namespace: return parser.parse_args() -if __name__ == "__main__": +def main() -> None: args = parse_arguments() loaded_pipfile = pipfile.Pipfile.load(args.path_to_pipfile) with open(args.path_to_pipfile_lock) as pl: @@ -75,3 +75,7 @@ def parse_arguments() -> argparse.Namespace: ) package_to_version[package] = version insert_pinned_version(package_to_version, args) + + +if __name__ == "__main__": + main() diff --git a/buildscripts/scripts/publish_cloud_images.py b/buildscripts/scripts/publish_cloud_images.py index ead712bb9ad..208e24ccc06 100755 --- a/buildscripts/scripts/publish_cloud_images.py +++ b/buildscripts/scripts/publish_cloud_images.py @@ -9,9 +9,9 @@ import json import os import sys -from typing import Final, Iterator +from typing import Final -import boto3 # type: ignore[import] +import boto3 from azure.identity import DefaultAzureCredential from azure.mgmt.compute import ComputeManagementClient from azure.mgmt.compute.models import ( @@ -258,14 +258,17 @@ def __init__( resource_group: str, ): super().__init__(version, build_tag, image_name) + assert self.version is not None + credentials = DefaultAzureCredential() self.subscription_id = subscription_id self.resource_group = resource_group + # The image name is hardcoded, because we changing this for each new + # major or minor version would require going through the complete + # listing process again. + # The gallery ID is only visible internally and not visible by users. # Use Checkmk_Cloud_Edition_2.2b5 for e.g. testing - assert self.version.base is not None - self.gallery_image_name = ( - f"Checkmk-Cloud-Edition-{self.version.base.major}.{self.version.base.minor}" - ) + self.gallery_image_name = "Checkmk-Cloud-Edition-2.2" self.compute_client = ComputeManagementClient( credentials, self.subscription_id, @@ -275,18 +278,20 @@ def __init__( self.subscription_id, ) - def get_azure_image_id(self) -> Iterator[str]: + def get_azure_image_id(self) -> str: resource_list = self.resource_client.resources.list_by_resource_group( self.resource_group, filter=f"name eq '{self.image_name}'", ) - yield next(resource_list).id + first_id = next(resource_list).id if another_match := next(resource_list, None): raise RuntimeError( f"Cannot identify a unique azure image by using {self.image_name=}. " f"Found also: {another_match}" ) + return first_id + @staticmethod def azure_compatible_version(version: Version) -> str: """ @@ -298,7 +303,7 @@ def azure_compatible_version(version: Version) -> str: return f"{version.base.major}.{version.base.minor}.{version.release.value}" async def build_gallery_image(self): - image_id = list(self.get_azure_image_id())[0] + image_id = self.get_azure_image_id() print(f"Creating new gallery image from {self.version=} by using {image_id=}") self.update_succesful( self.compute_client.gallery_image_versions.begin_create_or_update( diff --git a/buildscripts/scripts/stages.yml b/buildscripts/scripts/stages.yml index 9823b29d77f..aa5dd8ec657 100644 --- a/buildscripts/scripts/stages.yml +++ b/buildscripts/scripts/stages.yml @@ -159,7 +159,7 @@ VARIABLES: SH: "echo '${CHANGED_FILES_REL}' | grep '^packages/cmk-frontend-vue/' || true" - NAME: CHANGED_SHARED_TYPING_FILES - SH: "echo '${CHANGED_FILES_REL}' | grep '^packages/cmk-shared-typing/\\|^cmk/gui/form_specs/vue/shared_type_defs.py\\|^packages/cmk-frontend-vue/src/form/components/vue_formspec_components.ts' || true" + SH: "echo '${CHANGED_FILES_REL}' | grep '^packages/cmk-shared-typing/\\|^cmk/gui/watolib/notification_types.py\\|^cmk/gui/form_specs/vue/shared_type_defs.py\\|^packages/cmk-frontend-vue/src/form/components/vue_formspec_components.ts\\|^packages/cmk-frontend-vue/src/notification/type_defs.ts' || true" - NAME: CHANGED_CMK_FRONTEND_FILES SH: "echo '${CHANGED_FILES_REL}' | grep '^packages/cmk-frontend/' || true" @@ -205,12 +205,10 @@ STAGES: - NAME: "Python Unit Tests" ONLY_WHEN_NOT_EMPTY: CHANGED_REFERENCE_IMAGE,CHANGED_FIND_PYTHON_FILES_SCRIPT,CHANGED_PYTHON_FILES,CHANGED_PIPFILE_LOCK,CHANGED_PYPROJECT_TOML_FILE,CHANGED_TESTS_MAKEFILE,CHANGED_RUN_PIPENV_SCRIPT,CHANGED_CHECKMAN_FILES DIR: "tests" - ENV_VARS: - PYTEST_ADDOPTS: "--junitxml=${RESULTS}/python3-unit-junit.xml --color=no" COMMAND: "make test-unit-docker" TEXT_ON_SKIP: "No Python files changed" RESULT_CHECK_TYPE: "JUNIT" - RESULT_CHECK_FILE_PATTERN: "results/python3-unit-junit.xml" + RESULT_CHECK_FILE_PATTERN: "results/testlogs/unit/repo/test.xml" - NAME: "Python License Headers Test" ONLY_WHEN_NOT_EMPTY: CHANGED_REFERENCE_IMAGE,CHANGED_FIND_PYTHON_FILES_SCRIPT,CHANGED_PYTHON_FILES diff --git a/buildscripts/scripts/trigger-cmk-build-chain.groovy b/buildscripts/scripts/trigger-cmk-build-chain.groovy index 7fcde460cbb..ceebff32374 100644 --- a/buildscripts/scripts/trigger-cmk-build-chain.groovy +++ b/buildscripts/scripts/trigger-cmk-build-chain.groovy @@ -61,10 +61,9 @@ def main() { def build_image = edition != "managed"; - // TODO: saas has all tests disabled for now. Need some way to login in those tests, SAASDEV-664 def run_int_tests = true; def run_comp_tests = !(edition in ["saas", "managed"]); - def run_image_tests = edition != "managed"; + def run_image_tests = !(edition in ["saas", "managed"]); def run_update_tests = (edition in ["enterprise", "cloud", "saas"]); print( diff --git a/buildscripts/scripts/unpublish-container-image.py b/buildscripts/scripts/unpublish-container-image.py index 89ef74d8a63..55816c90762 100644 --- a/buildscripts/scripts/unpublish-container-image.py +++ b/buildscripts/scripts/unpublish-container-image.py @@ -6,7 +6,7 @@ from collections.abc import Iterator, Sequence from typing import Literal -from cmk.utils.version import Version +from cmk.ccc.version import Version from .lib.common import load_editions_file from .lib.registry import DockerImage, edition_to_registry, get_default_registries, Registry diff --git a/buildscripts/scripts/utils/docker_image_aliases_helper.groovy b/buildscripts/scripts/utils/docker_image_aliases_helper.groovy index 78679e91615..d62d1dabdf2 100644 --- a/buildscripts/scripts/utils/docker_image_aliases_helper.groovy +++ b/buildscripts/scripts/utils/docker_image_aliases_helper.groovy @@ -92,7 +92,7 @@ inside_container = {Map arg1=[:], Closure arg2 -> # BEGIN COMMON CODE with run-in-docker.sh if [ -e "${container_shadow_workspace}/cache" ]; then # Bazel creates files without write permission - chmod -R a+w ${container_shadow_workspace}/cache + chmod -R u+w ${container_shadow_workspace}/cache fi mkdir -p ${container_shadow_workspace}/home mkdir -p ${container_shadow_workspace}/home/.cache diff --git a/buildscripts/scripts/utils/upload_artifacts.groovy b/buildscripts/scripts/utils/upload_artifacts.groovy index 908861aa79c..8cc5f33e85f 100644 --- a/buildscripts/scripts/utils/upload_artifacts.groovy +++ b/buildscripts/scripts/utils/upload_artifacts.groovy @@ -61,7 +61,7 @@ def download_version_dir(DOWNLOAD_SOURCE, def upload_version_dir(SOURCE_PATH, UPLOAD_DEST, PORT, EXCLUDE_PATTERN="") { println(""" - ||== upload_version_dir ================================================================ + ||== upload_version_dir ==================================================================== || SOURCE_PATH = |${SOURCE_PATH}| || UPLOAD_DEST = |${UPLOAD_DEST}| || PORT = |${PORT}| @@ -106,6 +106,24 @@ def upload_via_rsync(archive_base, cmk_version, filename, upload_dest, upload_po } } +def upload_files_to_nexus(SOURCE_PATTERN, UPLOAD_DEST) { + println(""" + ||== upload_files_to_nexus() ================================================ + || SOURCE_PATTERN = |${SOURCE_PATTERN}| + || UPLOAD_DEST = |${UPLOAD_DEST}| + ||====================================================================== + """.stripMargin()); + + withCredentials([usernamePassword(credentialsId: 'nexus', passwordVariable: 'NEXUS_PASSWORD', usernameVariable: 'NEXUS_USERNAME')]) { + sh(""" + for i in ${SOURCE_PATTERN}; do + echo "Upload \${i} to Nexus"; + curl -sSf -u "${NEXUS_USERNAME}:${NEXUS_PASSWORD}" --upload-file "\${i}" "${UPLOAD_DEST}"; + done + """); + } +} + def create_hash(FILE_PATH) { sh(""" cd \$(dirname ${FILE_PATH}); diff --git a/buildscripts/scripts/utils/versioning.groovy b/buildscripts/scripts/utils/versioning.groovy index c7255d7b972..d2f928f2c7e 100644 --- a/buildscripts/scripts/utils/versioning.groovy +++ b/buildscripts/scripts/utils/versioning.groovy @@ -6,6 +6,9 @@ import groovy.transform.Field /* groovylint-disable DuplicateListLiteral */ +// ATTENTION: The paths added here for removal MUST NOT include slashes, because +// the command used in the function patch_folders will then fail and +// paths will not be removed as expected. @Field def REPO_PATCH_RULES = [\ "raw": [\ @@ -22,9 +25,8 @@ def REPO_PATCH_RULES = [\ "saas", \ "cse", \ "cse.py", \ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/{cme,cee,cce}"],\ - "folders_to_be_created": [\ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/{cme,cee,cce}"]], \ + "cmk.cee.dcd.plugins.connectors.connectors_api"],\ + "folders_to_be_created": []], \ "enterprise": [\ "paths_to_be_removed": [\ "managed", \ @@ -35,10 +37,8 @@ def REPO_PATCH_RULES = [\ "cce.py", \ "saas", \ "cse", \ - "cse.py", \ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/{cme,cce}"], \ - "folders_to_be_created": [\ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/{cme,cce}"]], \ + "cse.py"], \ + "folders_to_be_created": []], \ "managed": [\ "paths_to_be_removed": [\ "saas", \ @@ -52,18 +52,14 @@ def REPO_PATCH_RULES = [\ "cme.py", \ "saas", \ "cse", \ - "cse.py", \ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/cme"], \ - "folders_to_be_created": [\ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/cme"]], \ + "cse.py"], \ + "folders_to_be_created": []], \ "saas": [\ "paths_to_be_removed": [\ "managed", \ "cme", \ - "cme.py", \ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/cme"], \ - "folders_to_be_created": [\ - "packages/cmk-frontend/src/themes/{facelift,modern-dark}/scss/cme"]], \ + "cme.py"], \ + "folders_to_be_created": []], \ ]; /* groovylint-enable DuplicateListLiteral */ @@ -247,4 +243,12 @@ def strip_rc_number_from_version(VERSION) { return VERSION.split("-rc")[0]; } +def is_official_release(version) { + if (strip_rc_number_from_version(version) ==~ /((\d+.\d+.\d+)(([pib])(\d+))?)/) { + return true; + } else { + return false; + } +} + return this; diff --git a/buildscripts/scripts/validate_changes.py b/buildscripts/scripts/validate_changes.py index 299ba1e5cc2..a873c5caefa 100755 --- a/buildscripts/scripts/validate_changes.py +++ b/buildscripts/scripts/validate_changes.py @@ -17,11 +17,11 @@ import json import logging import os +import re import subprocess import sys import time from collections.abc import Mapping, Sequence -from functools import reduce from pathlib import Path from typing import Any @@ -125,7 +125,7 @@ def load_file(filename: Path) -> tuple[Sequence[Vars], Stages]: """Read and parse a YAML file containing 'VARIABLES' and 'STAGES' and return a tuple with typed content""" try: - raw_data = yaml.load(Path.read_text(filename), Loader=yaml.BaseLoader) + raw_data = yaml.safe_load(Path.read_text(filename)) except FileNotFoundError: raise RuntimeError( f"Could not find {filename}. Must be a YAML file containing stage declarations." @@ -142,7 +142,12 @@ def replace_variables(string: str, env_vars: Vars) -> str: >>> replace_variables("foo: ${foo}", {"foo": "bar"}) 'foo: bar' """ - return reduce(lambda s, kv: str.replace(s, f"${{{kv[0]}}}", kv[1]), env_vars.items(), string) + + def replace_match(match: re.Match) -> str: + var_name = match.group(1) + return env_vars.get(var_name, match.group(0)) + + return re.sub(r"\$\{(\w+)\}", replace_match, string) def apply_variables(in_data: StageInfo, env_vars: Vars) -> StageInfo: @@ -236,7 +241,17 @@ def evaluate_vars(raw_vars: Sequence[Vars], env_vars: Vars) -> Vars: ) LOG.debug("evaluate %r run command %r", e["NAME"], cmd) - replace_newlines = e.get("REPLACE_NEWLINES", "false") in ( + replace_newlines = convert_newline_entry_to_bool(e.get("REPLACE_NEWLINES", False)) + cmd_result = run_shell_command(cmd, replace_newlines) + LOG.debug("set to %r", cmd_result) + result[e["NAME"]] = cmd_result + + return result + + +def convert_newline_entry_to_bool(entry: str | bool) -> bool: + if isinstance(entry, str): + return entry.lower() in ( "y", "yes", "t", @@ -244,11 +259,8 @@ def evaluate_vars(raw_vars: Sequence[Vars], env_vars: Vars) -> Vars: "on", "1", ) - cmd_result = run_shell_command(cmd, replace_newlines) - LOG.debug("set to %r", cmd_result) - result[e["NAME"]] = cmd_result - return result + return bool(entry) def compile_stage_info(stages_file: Path, env_vars: Vars, no_skip: bool) -> tuple[Vars, Stages]: diff --git a/cmk/BUILD b/cmk/BUILD new file mode 100644 index 00000000000..62737881ebe --- /dev/null +++ b/cmk/BUILD @@ -0,0 +1,250 @@ +load("@aspect_rules_py//py:defs.bzl", "py_library") +load("@cmk_py//:requirements.bzl", "requirement") +load("@rules_python//python:packaging.bzl", "py_wheel") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") + +genrule( + name = "_generate_requirements_in", + srcs = [ + "@//:Pipfile", + "@//:Pipfile.lock", + ], + outs = ["requirements_in.orig"], + # We need to filter out editable reqs are the relative paths are not + # accessible in the sandbox. Failing to do so raises an `InstallationError`. + cmd = "pipenv requirements --dev | grep -Ev '^\\-e[[:space:]]' > $@", +) + +FILTER_OUT = [ + # Provided elsewhere + "rrdtool", + "protobuf", +] + +genrule( + name = "_prune_requirements_in", + srcs = ["requirements_in.orig"], + outs = ["requirements_in.txt"], + cmd = "cat $< | grep -v " + " ".join([("-e ^%s==" % pkg) for pkg in FILTER_OUT]) + " > $@", +) + +compile_pip_requirements( + name = "requirements", + timeout = "moderate", + env = { + "PIPENV_PYPI_MIRROR": "https://pypi.org/simple", + }, + extra_args = [ + "--no-strip-extras", # reconsider this? (https://github.com/jazzband/pip-tools/issues/1613) + "--quiet", + ], + requirements_in = "requirements_in.txt", + requirements_txt = "@//:requirements_lock.txt", + tags = ["manual"], + visibility = ["//visibility:public"], +) + +REQUIRED_EXTERNAL_DEPS = [ + # alphabetical order + "annotated-types", + "apispec", + "apispec-oneofschema", + "azure-identity", + "azure-storage-blob", + "boto3", + "botocore", + "cryptography", + "cython", + "dicttoxml", + "docstring-parser", + "exchangelib", # missing wheel + "feedparser", + "fido2", + "flask", + "GitPython", + "google-api-python-client", + "google-auth", + "google-cloud-asset", + "google-cloud-monitoring", + "icalendar", + "jinja2", + "jira", + "kubernetes", + "lxml", + "marshmallow", + "marshmallow-oneofschema", + "meraki", + "msal", + "netapp-ontap", # provided elsewhere + "numpy", + "oauthlib", + "openapi-spec-validator", + "opentelemetry-api", + "opentelemetry-exporter-otlp", + "opentelemetry-instrumentation-redis", + "opentelemetry-instrumentation-requests", + "opentelemetry-instrumentation-wsgi", + "opentelemetry-sdk", + "opentelemetry-semantic-conventions", + "opsgenie-sdk", + "paho-mqtt", + "paramiko", + "pillow", + "ply", + # "protobuf", # provided elsewhere + "psutil", + "psycopg2-binary", # missing wheel + "pyasn1", + "pydantic", + "pydantic_core", + "pyghmi", + "pyjwt", + "pymssql", + "pymysql", + "pyopenssl", + "pyparsing", + "pypdf", + "pyprof2calltree", + "pysaml2", + "pysmb", + "pysmi-lextudio", + "pysnmp-lextudio", + "python-active-directory", # missing wheel + "python-dateutil", + "python-ldap", # missing wheel + "python-snap7", + "pyyaml", + "recurring_ical_events", + "redfish", + "redis", + "reportlab", + "requests", + "requests-kerberos", # krb5: missing wheel + "requests-oauthlib", + "robotframework", + "roman", + "setproctitle", + "setuptools-scm", + "six", + "snmpsim-lextudio", + "typing-extensions", + "urllib3", + "vcrpy", +] + +CRE_PY = glob([ + "**/cre/**/*.py", + "**/cre.py", + "**/raw/**/*.py", + "**/raw.py", +]) + +CCE_PY = glob([ + "**/cce/**/*.py", + "**/cce.py", +]) + +CEE_PY = glob([ + "**/cee/**/*.py", + "**/cee.py", +]) + +CME_PY = glob([ + "**/cme/**/*.py", + "**/cme.py", +]) + +CSE_PY = glob([ + "**/cse/**/*.py", + "**/cse.py", +]) + +CMK_PACKAGES = [ + "//packages/cmk-agent-based", + "//packages/cmk-agent-receiver", + "//packages/cmk-crypto", + "//packages/cmk-graphing", + "//packages/cmk-livestatus-client", + "//packages/cmk-livestatus-client:py_livestatus", + "//packages/cmk-messaging", + "//packages/cmk-mkp-tool", + "//packages/cmk-rulesets", + "//packages/cmk-server-side-calls", + "//packages/cmk-trace", + "//packages/cmk-werks", +] + +py_library( + name = "lib_cmk", + srcs = glob( + # Keep in sync with `REPO_PATCH_RULES` from `versioning.groovy`. + include = ["**/*.py"], + exclude = CRE_PY + CCE_PY + CEE_PY + CME_PY + CSE_PY, + ), + data = ["gui/wsgi/applications/index.wsgi"], + imports = [".."], + visibility = [ + # for conftest + "//tests:__subpackages__", + ], + deps = [ + "@rrdtool_native//:rrdtool_python_lib", + ] + CMK_PACKAGES + [requirement(dep) for dep in REQUIRED_EXTERNAL_DEPS], +) + +py_library( + name = "lib_cmk_cre", + srcs = CRE_PY, + imports = [".."], + visibility = ["//tests:__subpackages__"], + deps = [ + "lib_cmk", + ], +) + +[py_library( + name = "lib_cmk_" + edition, + srcs = srcs, + imports = [".."], + visibility = ["//tests:__subpackages__"], + deps = [ + "lib_cmk", + "//non-free/cmc-protocols/protocols:py_config_proto", + ], +) for edition, srcs in [ + ("cce", CCE_PY), + ("cee", CEE_PY), + ("cme", CME_PY), + ("cse", CSE_PY), +]] + +py_library( + # The repo edition is only used for testing. + name = "lib_cmk_repo", + srcs = glob(["**/*.py"]), + data = ["gui/wsgi/applications/index.wsgi"], + imports = [".."], + visibility = ["//tests/unit:__pkg__"], + deps = [ + "@rrdtool_native//:rrdtool_python_lib", + ] + CMK_PACKAGES + [requirement(dep) for dep in REQUIRED_EXTERNAL_DEPS], +) + +[py_wheel( + name = "cmk_" + edition, + distribution = "checkmk", + requires = REQUIRED_EXTERNAL_DEPS, + # TODO(ml): cmk_version vs. PEP 440? + version = "1+" + edition, + visibility = ["//visibility:public"], + deps = [ + "lib_cmk", + "lib_cmk_" + edition, + ], +) for edition in [ + "cre", + "cce", + "cee", + "cme", + "cse", +]] diff --git a/cmk/base/api/agent_based/plugin_classes.py b/cmk/base/api/agent_based/plugin_classes.py index b0f678f0a88..f692b3c527c 100644 --- a/cmk/base/api/agent_based/plugin_classes.py +++ b/cmk/base/api/agent_based/plugin_classes.py @@ -6,6 +6,7 @@ from __future__ import annotations from collections.abc import Callable, Sequence +from dataclasses import dataclass from typing import Any, Literal, NamedTuple, Protocol from cmk.utils.check_utils import ParametersTypeAlias @@ -28,6 +29,12 @@ ) from cmk.discover_plugins import PluginLocation + +@dataclass(frozen=True) +class LegacyPluginLocation: + file_name: str + + InventoryFunction = Callable[..., InventoryResult] CheckFunction = Callable[..., CheckResult] @@ -53,7 +60,8 @@ class AgentSectionPlugin(NamedTuple): host_label_ruleset_name: RuleSetName | None host_label_ruleset_type: RuleSetTypeName supersedes: set[SectionName] - location: PluginLocation | None # not available for auto migrated plugins. + # We need to allow 'None' for the trivial agent section :-| + location: PluginLocation | LegacyPluginLocation | None class _OIDSpecLike(Protocol): @@ -86,7 +94,7 @@ class SNMPSectionPlugin(NamedTuple): detect_spec: SNMPDetectBaseType trees: Sequence[_SNMPTreeLike] supersedes: set[SectionName] - location: PluginLocation | None # not available for auto migrated plugins. + location: PluginLocation | LegacyPluginLocation SectionPlugin = AgentSectionPlugin | SNMPSectionPlugin @@ -104,7 +112,7 @@ class CheckPlugin(NamedTuple): check_default_parameters: ParametersTypeAlias | None check_ruleset_name: RuleSetName | None cluster_check_function: CheckFunction | None - location: PluginLocation | None # not available for auto migrated plugins. + location: PluginLocation | LegacyPluginLocation class InventoryPlugin(NamedTuple): diff --git a/cmk/base/api/agent_based/register/_discover.py b/cmk/base/api/agent_based/register/_discover.py index 829e57719c7..bd54ba7af49 100644 --- a/cmk/base/api/agent_based/register/_discover.py +++ b/cmk/base/api/agent_based/register/_discover.py @@ -8,6 +8,7 @@ from cmk.utils.plugin_loader import load_plugins_with_exceptions +from cmk import trace from cmk.agent_based.v2 import ( AgentSection, CheckPlugin, @@ -37,7 +38,10 @@ _ABPlugins = SimpleSNMPSection | SNMPSection | AgentSection | CheckPlugin | InventoryPlugin +tracer = trace.get_tracer() + +@tracer.start_as_current_span("load_all_plugins") def load_all_plugins(*, raise_errors: bool) -> list[str]: errors = [] for plugin_name, exception in load_plugins_with_exceptions("cmk.base.plugins.agent_based"): @@ -45,17 +49,20 @@ def load_all_plugins(*, raise_errors: bool) -> list[str]: if raise_errors: raise exception - discovered_plugins: DiscoveredPlugins[_ABPlugins] = discover_plugins( - PluginGroup.AGENT_BASED, entry_point_prefixes(), raise_errors=raise_errors - ) - errors.extend(f"Error in agent based plugin: {exc}" for exc in discovered_plugins.errors) - for location, plugin in discovered_plugins.plugins.items(): - try: - register_plugin_by_type(location, plugin, validate=raise_errors) - except Exception as exc: - if raise_errors: - raise - errors.append(f"Error in agent based plug-in {plugin.name} ({type(plugin)}): {exc}") + with tracer.start_as_current_span("discover_plugins"): + discovered_plugins: DiscoveredPlugins[_ABPlugins] = discover_plugins( + PluginGroup.AGENT_BASED, entry_point_prefixes(), raise_errors=raise_errors + ) + errors.extend(f"Error in agent based plugin: {exc}" for exc in discovered_plugins.errors) + + with tracer.start_as_current_span("load_discovered_plugins"): + for location, plugin in discovered_plugins.plugins.items(): + try: + register_plugin_by_type(location, plugin, validate=raise_errors) + except Exception as exc: + if raise_errors: + raise + errors.append(f"Error in agent based plug-in {plugin.name} ({type(plugin)}): {exc}") return errors diff --git a/cmk/base/api/agent_based/register/check_plugins.py b/cmk/base/api/agent_based/register/check_plugins.py index 0011af8f4a6..be144f619e6 100644 --- a/cmk/base/api/agent_based/register/check_plugins.py +++ b/cmk/base/api/agent_based/register/check_plugins.py @@ -14,7 +14,12 @@ from cmk.checkengine.checking import CheckPluginName from cmk.checkengine.sectionparser import ParsedSectionName -from cmk.base.api.agent_based.plugin_classes import CheckFunction, CheckPlugin, DiscoveryFunction +from cmk.base.api.agent_based.plugin_classes import ( + CheckFunction, + CheckPlugin, + DiscoveryFunction, + LegacyPluginLocation, +) from cmk.base.api.agent_based.register.utils import ( create_subscribed_sections, ITEM_VARIABLE, @@ -166,7 +171,7 @@ def create_check_plugin( check_default_parameters: ParametersTypeAlias | None = None, check_ruleset_name: str | None = None, cluster_check_function: Callable | None = None, - location: PluginLocation | None = None, + location: PluginLocation | LegacyPluginLocation, validate_kwargs: bool = True, ) -> CheckPlugin: """Return an CheckPlugin object after validating and converting the arguments one by one diff --git a/cmk/base/api/agent_based/register/check_plugins_legacy.py b/cmk/base/api/agent_based/register/check_plugins_legacy.py index bacaac82501..bada5334773 100644 --- a/cmk/base/api/agent_based/register/check_plugins_legacy.py +++ b/cmk/base/api/agent_based/register/check_plugins_legacy.py @@ -14,13 +14,14 @@ from contextlib import suppress from typing import Any -from cmk.utils.check_utils import maincheckify from cmk.utils.legacy_check_api import LegacyCheckDefinition from cmk.checkengine.parameters import Parameters -from cmk.base.api.agent_based.plugin_classes import CheckPlugin -from cmk.base.api.agent_based.register.check_plugins import create_check_plugin +from cmk.base.api.agent_based.plugin_classes import CheckPlugin, LegacyPluginLocation +from cmk.base.api.agent_based.register.check_plugins import ( + create_check_plugin, +) from cmk.agent_based.v1 import IgnoreResults, Metric, Result, Service, State from cmk.agent_based.v1.type_defs import CheckResult @@ -243,8 +244,8 @@ def check_migration_wrapper(params, section): # type: ignore[misc] def create_check_plugin_from_legacy( - check_plugin_name: str, check_info_element: LegacyCheckDefinition, + location: LegacyPluginLocation, *, validate_creation_kwargs: bool = True, ) -> CheckPlugin: @@ -253,22 +254,17 @@ def create_check_plugin_from_legacy( # handled gracefully raise ValueError(check_info_element.service_name) - new_check_name = maincheckify(check_plugin_name) - sections = [check_plugin_name.split(".", 1)[0]] - if "." in check_plugin_name: - assert sections == check_info_element.sections - discovery_function = _create_discovery_function(check_info_element) check_function = _create_check_function( - check_plugin_name, + check_info_element.name, check_info_element.service_name, check_info_element, ) return create_check_plugin( - name=new_check_name, - sections=sections, + name=check_info_element.name, + sections=check_info_element.sections, service_name=check_info_element.service_name, discovery_function=discovery_function, discovery_default_parameters=None, # legacy madness! @@ -276,5 +272,6 @@ def create_check_plugin_from_legacy( check_function=check_function, check_default_parameters=check_info_element.check_default_parameters or {}, check_ruleset_name=check_info_element.check_ruleset_name, + location=location, validate_kwargs=validate_creation_kwargs, ) diff --git a/cmk/base/api/agent_based/register/section_plugins.py b/cmk/base/api/agent_based/register/section_plugins.py index 3daf3851998..c098ee0f99b 100644 --- a/cmk/base/api/agent_based/register/section_plugins.py +++ b/cmk/base/api/agent_based/register/section_plugins.py @@ -25,6 +25,7 @@ AgentParseFunction, AgentSectionPlugin, HostLabelFunction, + LegacyPluginLocation, SimpleSNMPParseFunction, SNMPParseFunction, SNMPSectionPlugin, @@ -230,7 +231,7 @@ def _create_supersedes( def create_agent_section_plugin( agent_section_spec: AgentSection, - location: PluginLocation | None, + location: PluginLocation | LegacyPluginLocation, *, validate: bool, ) -> AgentSectionPlugin: @@ -273,7 +274,7 @@ def create_agent_section_plugin( def create_snmp_section_plugin( snmp_section_spec: SimpleSNMPSection | SNMPSection, - location: PluginLocation | None, + location: PluginLocation | LegacyPluginLocation, *, validate: bool, ) -> SNMPSectionPlugin: diff --git a/cmk/base/api/agent_based/register/section_plugins_legacy.py b/cmk/base/api/agent_based/register/section_plugins_legacy.py index 30271d326e8..256dc84bc9a 100644 --- a/cmk/base/api/agent_based/register/section_plugins_legacy.py +++ b/cmk/base/api/agent_based/register/section_plugins_legacy.py @@ -7,7 +7,11 @@ from collections.abc import Callable, Sequence from typing import cast -from cmk.base.api.agent_based.plugin_classes import AgentSectionPlugin, SNMPSectionPlugin +from cmk.base.api.agent_based.plugin_classes import ( + AgentSectionPlugin, + LegacyPluginLocation, + SNMPSectionPlugin, +) from cmk.base.api.agent_based.register.section_plugins import ( create_agent_section_plugin, create_snmp_section_plugin, @@ -29,6 +33,7 @@ def create_section_plugin_from_legacy( parse_function: Callable[[list], object], detect: SNMPDetectSpecification | None, fetch: SNMPTree | Sequence[SNMPTree] | None, + location: LegacyPluginLocation, ) -> SNMPSectionPlugin | AgentSectionPlugin: match fetch: case None: @@ -37,7 +42,7 @@ def create_section_plugin_from_legacy( name=name, parse_function=parse_function, ), - location=None, + location=location, validate=False, ) @@ -50,7 +55,7 @@ def create_section_plugin_from_legacy( fetch=fetch, detect=detect, ), - location=None, + location=location, validate=False, ) @@ -63,6 +68,6 @@ def create_section_plugin_from_legacy( fetch=fetch_list, detect=detect, ), - location=None, + location=location, validate=False, ) diff --git a/cmk/base/automations/__init__.py b/cmk/base/automations/__init__.py index 02e9c3bdc31..3b71e955f89 100644 --- a/cmk/base/automations/__init__.py +++ b/cmk/base/automations/__init__.py @@ -23,6 +23,10 @@ from cmk.base import check_api, config, profiling +from cmk import trace + +tracer = trace.get_tracer() + # TODO: Inherit from MKGeneralException class MKAutomationError(MKException): @@ -52,7 +56,10 @@ def execute(self, cmd: str, args: list[str]) -> Any: ) if automation.needs_checks: - with redirect_stdout(open(os.devnull, "w")): + with ( + tracer.start_as_current_span("load_all_plugins"), + redirect_stdout(open(os.devnull, "w")), + ): log.setup_console_logging() config.load_all_plugins( check_api.get_check_api_context, @@ -61,9 +68,11 @@ def execute(self, cmd: str, args: list[str]) -> Any: ) if automation.needs_config: - config.load(validate_hosts=False) + with tracer.start_as_current_span("load_config"): + config.load(validate_hosts=False) - result = automation.execute(args) + with tracer.start_as_current_span(f"execute_automation[{cmd}]"): + result = automation.execute(args) except (MKAutomationError, MKTimeout) as e: console.error(f"{e}", file=sys.stderr) diff --git a/cmk/base/automations/check_mk.py b/cmk/base/automations/check_mk.py index 8c45bb5134f..b0d7e7c25b2 100644 --- a/cmk/base/automations/check_mk.py +++ b/cmk/base/automations/check_mk.py @@ -180,6 +180,7 @@ from cmk.base.errorhandling import create_section_crash_dump from cmk.base.parent_scan import ScanConfig from cmk.base.server_side_calls import ( + ExecutableFinder, load_active_checks, load_special_agents, SpecialAgent, @@ -579,11 +580,14 @@ def make_final_service_name(sn: ServiceName) -> ServiceName: macros, ip_address_of, ), - host_attrs, config.http_proxies, make_final_service_name, cmk.utils.password_store.load(password_store_file), password_store_file, + ExecutableFinder( + cmk.utils.paths.local_nagios_plugins_dir, cmk.utils.paths.nagios_plugins_dir + ), + ip_lookup_failed=ip_lookup.is_fallback_ip(host_attrs["address"]), ) return [ @@ -1529,11 +1533,14 @@ def _get_service_info( macros, ip_address_of, ), - host_attrs, config.http_proxies, lambda x: config.get_final_service_description(x, translations), cmk.utils.password_store.load(password_store_file), password_store_file, + ExecutableFinder( + cmk.utils.paths.local_nagios_plugins_dir, cmk.utils.paths.nagios_plugins_dir + ), + ip_lookup_failed=ip_lookup.is_fallback_ip(host_attrs["address"]), ) active_checks = config_cache.active_checks(host_name) @@ -2057,6 +2064,9 @@ def get_special_agent_commandline( http_proxies, passwords, password_store_file, + ExecutableFinder( + cmk.utils.paths.local_special_agents_dir, cmk.utils.paths.special_agents_dir + ), ) if not params: @@ -2606,11 +2616,14 @@ def execute(self, args: list[str]) -> ActiveCheckResult: macros, ip_address_of, ), - host_attrs, config.http_proxies, lambda x: config.get_final_service_description(x, translations), cmk.utils.password_store.load(password_store_file), password_store_file, + ExecutableFinder( + cmk.utils.paths.local_nagios_plugins_dir, cmk.utils.paths.nagios_plugins_dir + ), + ip_lookup_failed=ip_lookup.is_fallback_ip(host_attrs["address"]), ) active_check = dict(config_cache.active_checks(host_name)).get(plugin, []) diff --git a/cmk/base/check_api.py b/cmk/base/check_api.py index b713c8d0269..ce5844c11f2 100644 --- a/cmk/base/check_api.py +++ b/cmk/base/check_api.py @@ -25,12 +25,10 @@ # pylint: disable=unused-import from cmk.utils.legacy_check_api import LegacyCheckDefinition as LegacyCheckDefinition -from cmk.utils.metrics import MetricName from cmk.utils.regex import regex as regex # pylint: disable=unused-import # pylint: disable=unused-import from cmk.checkengine.checkresults import state_markers as state_markers -from cmk.checkengine.submitters import ServiceDetails, ServiceState from cmk.base.config import CheckContext as _CheckContext from cmk.base.config import get_http_proxy as _get_http_proxy @@ -50,7 +48,7 @@ | tuple[str, float, Warn, Crit, _Bound, _Bound] ) -ServiceCheckResult = tuple[ServiceState, ServiceDetails, list[_MetricTuple]] +ServiceCheckResult = tuple[int, str, list[_MetricTuple]] # to ease migration: @@ -90,7 +88,7 @@ def _normalize_levels(levels: Levels) -> Levels: def _do_check_levels( value: int | float, levels: Levels, human_readable_func: Callable -) -> tuple[ServiceState, ServiceDetails]: +) -> tuple[int, str]: warn_upper, crit_upper, warn_lower, crit_lower = _normalize_levels(levels) # Critical cases if crit_upper is not None and value >= crit_upper: @@ -113,7 +111,7 @@ def _levelsinfo_ty(ty: str, warn: Warn, crit: Crit, human_readable_func: Callabl def _build_perfdata( - dsname: None | MetricName, + dsname: None | str, value: int | float, levels: Levels, boundaries: tuple | None, @@ -126,7 +124,7 @@ def _build_perfdata( def check_levels( # pylint: disable=too-many-branches value: int | float, - dsname: None | MetricName, + dsname: None | str, params: Any, unit: str = "", human_readable_func: Callable | None = None, diff --git a/cmk/base/check_legacy_includes/raritan.py b/cmk/base/check_legacy_includes/raritan.py index 87181636fe2..f9eb3bfc90e 100644 --- a/cmk/base/check_legacy_includes/raritan.py +++ b/cmk/base/check_legacy_includes/raritan.py @@ -96,6 +96,13 @@ "11": (2, "alarmed"), } +# SensorStateEnumeration (EMD-, PDU2, LHX-MIB) - simplified for plugs (on/off) +# nr. --> state human readable +raritan_pdu_plug_state = { + "7": "on", + "8": "off", +} + # . # .--Functions-----------------------------------------------------------. # | _____ _ _ | diff --git a/cmk/base/config.py b/cmk/base/config.py index dd8b4ea2d19..a2c49785f4b 100644 --- a/cmk/base/config.py +++ b/cmk/base/config.py @@ -102,14 +102,17 @@ from cmk.checkengine.checking import ( CheckPluginName, ConfiguredService, + merge_enforced_services, ServiceConfigurer, ServiceID, ) from cmk.checkengine.discovery import ( + AutocheckEntry, AutochecksManager, CheckPreviewEntry, DiscoveredLabelsCache, DiscoveryCheckParameters, + merge_cluster_autochecks, ) from cmk.checkengine.exitspec import ExitSpec from cmk.checkengine.fetcher import FetcherType, SourceType @@ -131,6 +134,7 @@ from cmk.base.api.agent_based.plugin_classes import ( AgentSectionPlugin, CheckPlugin, + LegacyPluginLocation, SNMPSectionPlugin, ) from cmk.base.api.agent_based.register.check_plugins_legacy import create_check_plugin_from_legacy @@ -140,6 +144,7 @@ from cmk.base.default_config import * # pylint: disable=wildcard-import,unused-wildcard-import from cmk.base.parent_scan import ScanConfig as ParentScanConfig from cmk.base.server_side_calls import ( + ExecutableFinder, load_special_agents, SpecialAgent, SpecialAgentCommandLine, @@ -147,7 +152,7 @@ ) from cmk.base.sources import SNMPFetcherConfig -from cmk import piggyback +from cmk import piggyback, trace from cmk.server_side_calls import v1 as server_side_calls_api from cmk.server_side_calls_backend.config_processing import PreprocessingResult @@ -165,6 +170,8 @@ # Non-existing edition layering... RRDObjectConfig: TypeAlias = object # type: ignore[no-redef] +tracer = trace.get_tracer() + _ContactgroupName = str # TODO: Prefix helper functions with "_". @@ -212,6 +219,9 @@ def __init__( ) -> None: self._data = {s.id(): s for s in services} + def __repr__(self) -> str: + return f"{self.__class__.__name__}(services={list(self._data.values())!r})" + def __getitem__(self, key: ServiceID) -> ConfiguredService: return self._data[key] @@ -242,6 +252,10 @@ def _aggregate_check_table_services( config_cache: ConfigCache, skip_ignored: bool, filter_mode: FilterMode, + get_autochecks: Callable[[HostAddress], Sequence[AutocheckEntry]], + configure_autochecks: Callable[ + [HostName, Sequence[AutocheckEntry]], Iterable[ConfiguredService] + ], ) -> Iterable[ConfiguredService]: sfilter = _ServiceFilter( host_name, @@ -258,7 +272,11 @@ def _aggregate_check_table_services( if is_cluster: # Add checks a cluster might receive from its nodes yield from ( - s for s in _get_clustered_services(config_cache, host_name) if sfilter.keep(s) + s + for s in _get_clustered_services( + config_cache, host_name, get_autochecks, configure_autochecks + ) + if sfilter.keep(s) ) else: yield from ( @@ -292,7 +310,9 @@ def _aggregate_check_table_services( yield from ( s # ... this adds it for node2 - for s in _get_services_from_cluster_nodes(config_cache, host_name) + for s in _get_services_from_cluster_nodes( + config_cache, host_name, get_autochecks, configure_autochecks + ) if sfilter.keep(s) # ... and this condition prevents it from being added on node3 # 'not is_mine' means: would it be there, it would be clustered. @@ -350,41 +370,54 @@ def is_mine(self, service: ConfiguredService) -> bool: def _get_services_from_cluster_nodes( - config_cache: ConfigCache, node_name: HostName + config_cache: ConfigCache, + node_name: HostName, + get_autochecks: Callable[[HostAddress], Sequence[AutocheckEntry]], + configure_autochecks: Callable[ + [HostName, Sequence[AutocheckEntry]], Iterable[ConfiguredService] + ], ) -> Iterable[ConfiguredService]: for cluster in config_cache.clusters_of(node_name): - yield from _get_clustered_services(config_cache, cluster) + yield from _get_clustered_services( + config_cache, cluster, get_autochecks, configure_autochecks + ) def _get_clustered_services( config_cache: ConfigCache, cluster_name: HostName, + get_autochecks: Callable[[HostAddress], Sequence[AutocheckEntry]], + configure_autochecks: Callable[ + [HostName, Sequence[AutocheckEntry]], Iterable[ConfiguredService] + ], ) -> Iterable[ConfiguredService]: nodes = config_cache.nodes(cluster_name) - nodes_discovered_services = ( - {} - if config_cache.is_ping_host(cluster_name) - else {node: config_cache.get_discovered_services(node) for node in nodes} - ) + if not config_cache.is_ping_host(cluster_name): - nodes_enforced_services = {node: config_cache.enforced_services_table(node) for node in nodes} + def appears_on_cluster(node_name: HostAddress, service_id: ServiceID) -> bool: + if config_cache.check_plugin_ignored(node_name, service_id[0]): + return False + description = service_description(config_cache.ruleset_matcher, node_name, *service_id) + return not config_cache.service_ignored(node_name, description) and ( + config_cache.effective_host(node_name, description) == cluster_name + ) - # Note: the way we return the services here means that for a service that is enforced on some - # nodes and discovered on others, the parameters of the service on the cluster will depend - # on the order of the nodes in the cluster. - for node in nodes: - yield from ( - service - for service in nodes_discovered_services[node] - if config_cache.effective_host(node, service.description) == cluster_name - ) - yield from ( - service - for _ruleset_name, service in nodes_enforced_services[node].values() - if config_cache.effective_host(node, service.description) == cluster_name + yield from configure_autochecks( + cluster_name, + merge_cluster_autochecks( + {node: get_autochecks(node) for node in nodes}, + appears_on_cluster, + ), ) + yield from merge_enforced_services( + {node_name: config_cache.enforced_services_table(node_name) for node_name in nodes}, + lambda node_name, service_name: ( + config_cache.effective_host(node_name, service_name) == cluster_name + ), + ) + @dataclasses.dataclass(frozen=True, kw_only=True) class ClusterCacheInfo: @@ -1344,14 +1377,6 @@ def get_http_proxy(http_proxy: tuple[str, str]) -> HTTPProxyConfig: check_info: dict[ object, object ] = {} # want: dict[str, LegacyCheckDefinition], but don't trust the plugins! -# for nagios config: keep track which plug-in lives where -legacy_check_plugin_files: dict[str, str] = {} -# Lookup for legacy names -legacy_check_plugin_names: dict[CheckPluginName, str] = {} -# optional functions for parameter precompilation -precompile_params: dict[str, Callable[[str, str, dict[str, Any]], Any]] = {} -# factory settings for dictionary-configured checks -factory_settings: dict[str, Mapping[str, Any]] = {} # definitions of special agents special_agent_info: dict[str, SpecialAgentInfoFunction] = {} @@ -1383,10 +1408,11 @@ def load_all_plugins( errors = agent_based_register.load_all_plugins(raise_errors=cmk.ccc.debug.enabled()) - # LEGACY CHECK PLUGINS - filelist = _get_plugin_paths(str(local_checks_dir), checks_dir) + with tracer.start_as_current_span("load_legacy_check_plugins"): + with tracer.start_as_current_span("discover_legacy_check_plugins"): + filelist = _get_plugin_paths(str(local_checks_dir), checks_dir) - errors.extend(load_checks(get_check_api_context, filelist)) + errors.extend(load_checks(get_check_api_context, filelist)) return errors @@ -1394,10 +1420,6 @@ def load_all_plugins( def _initialize_data_structures() -> None: """Initialize some data structures which are populated while loading the checks""" check_info.clear() - legacy_check_plugin_files.clear() - legacy_check_plugin_names.clear() - precompile_params.clear() - factory_settings.clear() special_agent_info.clear() @@ -1411,12 +1433,15 @@ def _get_plugin_paths(*dirs: str) -> list[str]: # NOTE: The given file names should better be absolute, otherwise # we depend on the current working directory, which is a bad idea, # especially in tests. +@tracer.start_as_current_span("load_legacy_checks") def load_checks( get_check_api_context: GetCheckApiContext, filelist: list[str], ) -> list[str]: loaded_files: set[str] = set() ignored_plugins_errors = [] + sane_check_info = {} + legacy_check_plugin_files: dict[str, str] = {} did_compile = False for f in filelist: @@ -1432,7 +1457,6 @@ def load_checks( # Make a copy of known plug-in names, we need to track them for nagios config generation known_checks = {str(k) for k in check_info} - known_agents = {str(k) for k in special_agent_info} did_compile |= load_precompiled_plugin(f, check_context) @@ -1449,28 +1473,24 @@ def load_checks( raise continue - for plugin_name in {str(k) for k in check_info}.difference(known_checks) | { - str(k) for k in special_agent_info - }.difference(known_agents): - legacy_check_plugin_files[plugin_name] = f - - # Now just drop everything we don't like; this is not a supported API anymore. - # Users affected by this will see a CRIT in their "Analyse Configuration" page. - sane_check_info = {} - for k, v in check_info.items(): - if isinstance(k, str) and isinstance(v, LegacyCheckDefinition): - sane_check_info[k] = v - continue - ignored_plugins_errors.append( - f"Ignoring outdated plug-in {k!r}: Format no longer supported" - " -- this API is deprecated!" - ) - - legacy_check_plugin_names.update({CheckPluginName(maincheckify(n)): n for n in sane_check_info}) + defined_checks = ((str(n), p) for n, p in check_info.items() if n not in known_checks) + for plugin_name, plugin in defined_checks: + if isinstance(plugin, LegacyCheckDefinition): + sane_check_info[plugin_name] = plugin + legacy_check_plugin_files[plugin.name] = f + else: + # Now just drop everything we don't like; this is not a supported API anymore. + # Users affected by this will see a CRIT in their "Analyse Configuration" page. + ignored_plugins_errors.append( + f"Ignoring outdated plug-in in {f!r}: Format no longer supported" + " -- this API is deprecated!" + ) - section_errors, sections = _make_agent_and_snmp_sections(sane_check_info) + section_errors, sections = _make_agent_and_snmp_sections( + sane_check_info.values(), legacy_check_plugin_files + ) check_errors, checks = _make_check_plugins( - sane_check_info, validate_creation_kwargs=did_compile + sane_check_info.values(), legacy_check_plugin_files, validate_creation_kwargs=did_compile ) _add_sections_to_register(sections) @@ -1484,7 +1504,6 @@ def new_check_context(get_check_api_context: GetCheckApiContext) -> CheckContext # Add the data structures where the checks register with Checkmk context = { "check_info": check_info, - "precompile_params": precompile_params, "special_agent_info": special_agent_info, } # NOTE: For better separation it would be better to copy the values, but @@ -1592,7 +1611,7 @@ def _add_sections_to_register(sections: Iterable[SNMPSectionPlugin | AgentSectio def _make_agent_and_snmp_sections( - legacy_checks: Mapping[str, LegacyCheckDefinition], + legacy_checks: Iterable[LegacyCheckDefinition], tracked_files: Mapping[str, str] ) -> tuple[list[str], Sequence[SNMPSectionPlugin | AgentSectionPlugin]]: """Here comes the next layer of converting-to-"new"-api. @@ -1602,16 +1621,18 @@ def _make_agent_and_snmp_sections( errors = [] sections = [] - for section_name, check_info_element in legacy_checks.items(): + for check_info_element in legacy_checks: if (parse_function := check_info_element.parse_function) is None: continue + file = tracked_files[check_info_element.name] try: sections.append( create_section_plugin_from_legacy( - name=section_name, + name=check_info_element.name, parse_function=parse_function, fetch=check_info_element.fetch, detect=check_info_element.detect, + location=LegacyPluginLocation(file), ) ) except (NotImplementedError, KeyError, AssertionError, ValueError) as exc: @@ -1620,7 +1641,7 @@ def _make_agent_and_snmp_sections( # passed un-parsed data unexpectedly. if cmk.ccc.debug.enabled(): raise MKGeneralException(exc) from exc - errors.append(AUTO_MIGRATION_ERR_MSG % ("section", section_name)) + errors.append(AUTO_MIGRATION_ERR_MSG % ("section", file)) return errors, sections @@ -1642,24 +1663,28 @@ def _add_checks_to_register(checks: Iterable[CheckPlugin]) -> None: def _make_check_plugins( - legacy_checks: Mapping[str, LegacyCheckDefinition], *, validate_creation_kwargs: bool + legacy_checks: Iterable[LegacyCheckDefinition], + tracked_files: Mapping[str, str], + *, + validate_creation_kwargs: bool, ) -> tuple[list[str], Sequence[CheckPlugin]]: """Here comes the next layer of converting-to-"new"-api. - For the new check-API in cmk/base/api/agent_based, we use the accumulated information + For the new check-API we use the accumulated information in check_info to create API compliant check plug-ins. """ errors = [] checks = [] - for check_plugin_name, check_info_element in sorted(legacy_checks.items()): + for check_info_element in legacy_checks: # skip pure section declarations: if check_info_element.service_name is None: continue + file = tracked_files[check_info_element.name] try: checks.append( create_check_plugin_from_legacy( - check_plugin_name, check_info_element, + location=LegacyPluginLocation(file), validate_creation_kwargs=validate_creation_kwargs, ) ) @@ -1668,7 +1693,7 @@ def _make_check_plugins( # will be silently droppend on most (all?) occasions. if cmk.ccc.debug.enabled(): raise MKGeneralException(exc) from exc - errors.append(AUTO_MIGRATION_ERR_MSG % ("check plug-in", check_plugin_name)) + errors.append(AUTO_MIGRATION_ERR_MSG % ("check plug-in", file)) return errors, checks @@ -1694,9 +1719,13 @@ def compute_check_parameters( params: Mapping[str, object], configured_parameters: TimespecificParameters | None = None, ) -> TimespecificParameters: - """Compute parameters for a check honoring factory settings, - default settings of user in main.mk, check_parameters[] and - the values code in autochecks (given as parameter params)""" + """Compute effective check parameters. + + Honoring (in order of precedence): + * the configured parameters + * the discovered parameters + * the plugins defaults + """ check_plugin = agent_based_register.get_check_plugin(plugin_name) if check_plugin is None: # handle vanished check plug-in return TimespecificParameters() @@ -1722,24 +1751,15 @@ def _get_configured_parameters( ruleset_name: RuleSetName | None, item: Item, ) -> TimespecificParameters: - descr = service_description(matcher, host, plugin_name, item) - - # parameters configured via check_parameters - extra = [ - TimespecificParameterSet.from_parameters(p) - for p in matcher.service_extra_conf(host, descr, check_parameters) - ] - if ruleset_name is None: - return TimespecificParameters(extra) - + return TimespecificParameters() + descr = service_description(matcher, host, plugin_name, item) return TimespecificParameters( [ # parameters configured via checkgroup_parameters TimespecificParameterSet.from_parameters(p) for p in _get_checkgroup_parameters(matcher, host, str(ruleset_name), item, descr) ] - + extra ) @@ -1907,6 +1927,19 @@ def make_hosts_config() -> Hosts: ) +def _make_clusters_nodes_maps() -> ( + tuple[Mapping[HostName, Sequence[HostName]], Mapping[HostName, Sequence[HostName]]] +): + clusters_of_cache: dict[HostName, list[HostName]] = {} + nodes_cache: dict[HostName, Sequence[HostName]] = {} + for cluster, hosts in clusters.items(): + clustername = HostName(cluster.split("|", 1)[0]) + for name in hosts: + clusters_of_cache.setdefault(name, []).append(clustername) + nodes_cache[clustername] = [HostName(h) for h in hosts] + return clusters_of_cache, nodes_cache + + class ConfigCache: def __init__(self) -> None: super().__init__() @@ -1944,17 +1977,19 @@ def initialize(self) -> ConfigCache: self._host_paths: dict[HostName, str] = ConfigCache._get_host_paths(host_paths) self._hosttags: dict[HostName, Sequence[TagID]] = {} + ( + self._clusters_of_cache, + self._nodes_cache, + ) = _make_clusters_nodes_maps() + self._autochecks_manager = AutochecksManager() self._discovered_labels_cache = DiscoveredLabelsCache( - self._autochecks_manager.get_autochecks + self._nodes_cache, self._autochecks_manager.get_autochecks ) - self._clusters_of_cache: dict[HostName, list[HostName]] = {} - self._nodes_cache: dict[HostName, list[HostName]] = {} self._effective_host_cache: dict[tuple[HostName, ServiceName, tuple | None], HostName] = {} self._check_mk_check_interval: dict[HostName, float] = {} self.hosts_config = make_hosts_config() - self._setup_clusters_nodes_cache() tag_to_group_map = ConfigCache.get_tag_to_group_map() self._collect_hosttags(tag_to_group_map) @@ -1970,7 +2005,13 @@ def initialize(self) -> ConfigCache: ), clusters_of=self._clusters_of_cache, nodes_of=self._nodes_cache, - all_configured_hosts=list(set(self.hosts_config)), + all_configured_hosts=frozenset( + itertools.chain( + self.hosts_config.hosts, + self.hosts_config.clusters, + self.hosts_config.shadow_hosts, + ) + ), builtin_host_labels_store=BuiltinHostLabelsStore(), debug_matching_stats=ruleset_matching_stats, ) @@ -2019,14 +2060,12 @@ def _discovered_labels_of_service( hostname: HostName, service_desc: ServiceName, ) -> Labels: - return { - label.name: label.value - for label in self._discovered_labels_cache.discovered_labels_of( - hostname, - service_desc, - functools.partial(service_description, self.ruleset_matcher), - ).values() - } + return self._discovered_labels_cache.discovered_labels_of( + hostname, + service_desc, + functools.partial(service_description, self.ruleset_matcher), + self.effective_host, + ) @staticmethod def get_tag_to_group_map() -> Mapping[TagID, TagGroupID]: @@ -2208,6 +2247,8 @@ def check_table( config_cache=self, skip_ignored=skip_ignored, filter_mode=filter_mode, + get_autochecks=self._autochecks_manager.get_autochecks, + configure_autochecks=self._service_configurer.configure_autochecks, ) ) @@ -2600,10 +2641,6 @@ def inventory_parameters( ), } - def custom_checks(self, host_name: HostName) -> Sequence[dict[Any, Any]]: - """Return the free form configured custom checks without formalization""" - return self.ruleset_matcher.get_host_values(host_name, custom_checks) - def active_checks(self, host_name: HostName) -> Sequence[SSCRules]: """Returns active checks configured for this host @@ -2632,6 +2669,10 @@ def make_active_checks() -> Sequence[SSCRules]: return self.__active_checks.setdefault(host_name, make_active_checks()) + def custom_checks(self, host_name: HostName) -> Sequence[dict[Any, Any]]: + """Return the free form configured custom checks without formalization""" + return self.ruleset_matcher.get_host_values(host_name, custom_checks) + def custom_check_preview_rows(self, host_name: HostName) -> Sequence[CheckPreviewEntry]: custom_checks_ = self.custom_checks(host_name) ignored_services = IgnoredServices(self, host_name) @@ -2696,39 +2737,44 @@ def special_agent_command_lines( password_store_file: Path, ip_address_of: IPLookup, ) -> Iterable[tuple[str, SpecialAgentCommandLine]]: - for agentname, params_seq in self.special_agents(host_name): - for params in params_seq: - host_attrs = self.get_host_attributes(host_name, ip_address_of) - macros = { + host_attrs = self.get_host_attributes(host_name, ip_address_of) + special_agent = SpecialAgent( + load_special_agents()[1], + special_agent_info, + host_name, + ip_address, + get_ssc_host_config( + host_name, + self.alias(host_name), + self.default_address_family(host_name), + self.ip_stack_config(host_name), + *self.additional_ipaddresses(host_name), + { "": ip_address or "", "": host_name, **self.get_host_macros_from_attributes(host_name, host_attrs), - } - additional_addresses_ipv4, additional_addresses_ipv6 = self.additional_ipaddresses( - host_name - ) - special_agent = SpecialAgent( - load_special_agents()[1], - special_agent_info, - host_name, - ip_address, - get_ssc_host_config( - host_name, - self.alias(host_name), - self.default_address_family(host_name), - self.ip_stack_config(host_name), - additional_addresses_ipv4, - additional_addresses_ipv6, - macros, - ip_address_of, - ), - host_attrs, - http_proxies, - passwords, - password_store_file, - ) - for agent_data in special_agent.iter_special_agent_commands(agentname, params): - yield agentname, agent_data + }, + ip_address_of, + ), + host_attrs, + http_proxies, + passwords, + password_store_file, + ExecutableFinder( + cmk.utils.paths.local_special_agents_dir, cmk.utils.paths.special_agents_dir + ), + ) + for agentname, params_seq in self.special_agents(host_name): + for params in params_seq: + try: + for agent_data in special_agent.iter_special_agent_commands(agentname, params): + yield agentname, agent_data + except Exception as exc: + if cmk.ccc.debug.enabled(): + raise + config_warnings.warn( + f"Config creation for special agent {agentname} failed on {host_name}: {exc}" + ) def collect_passwords(self) -> Mapping[str, str]: # consider making the hosts an argument. Sometimes we only need one. @@ -3291,9 +3337,7 @@ def _host_has_piggyback_data_right_now(self, host_name: HostAddress) -> bool: def _is_usable(data: piggyback.PiggybackMessage) -> bool: return (now - data.meta.last_update) <= piggy_config.max_cache_age(data.meta.source) - return any( - map(_is_usable, piggyback.get_piggyback_raw_data(host_name, cmk.utils.paths.omd_root)) - ) + return any(map(_is_usable, piggyback.get_messages_for(host_name, cmk.utils.paths.omd_root))) def _piggybacked_host_files(self, host_name: HostName) -> list[tuple[str | None, str, int]]: if rules := self.ruleset_matcher.get_host_values(host_name, piggybacked_host_files): @@ -3811,13 +3855,6 @@ def _checktype_ignored_for_host(check_plugin_name_str: str) -> bool: return _checktype_ignored_for_host(check_plugin_name_str) - def _setup_clusters_nodes_cache(self) -> None: - for cluster, hosts in clusters.items(): - clustername = HostName(cluster.split("|", 1)[0]) - for name in hosts: - self._clusters_of_cache.setdefault(name, []).append(clustername) - self._nodes_cache[clustername] = hosts - def get_cluster_cache_info(self) -> ClusterCacheInfo: return ClusterCacheInfo(clusters_of=self._clusters_of_cache, nodes_of=self._nodes_cache) @@ -4698,7 +4735,6 @@ def get_nested_rules(prefix: str, rulesets: dict[str, list]) -> Mapping[int, str id(cmc_service_rrd_config): "cmc_service_rrd_config", id(inv_retention_intervals): "inv_retention_intervals", id(periodic_discovery): "periodic_discovery", - id(check_parameters): "check_parameters", id(custom_checks): "custom_checks", id(host_label_rules): "host_label_rules", id(bulkwalk_hosts): "bulkwalk_hosts", diff --git a/cmk/base/core.py b/cmk/base/core.py index a11c247abd4..0cba0df3f4a 100644 --- a/cmk/base/core.py +++ b/cmk/base/core.py @@ -26,8 +26,9 @@ from cmk.base.config import ConfigCache, ConfiguredIPLookup from cmk.base.core_config import MonitoringCore -# suppress "Cannot find module" error from mypy +from cmk import trace +tracer = trace.get_tracer() # . # .--Control-------------------------------------------------------------. @@ -143,27 +144,33 @@ def do_core_action( monitoring_core: Literal["nagios", "cmc"], quiet: bool = False, ) -> None: - if not quiet: - print_("%sing monitoring core..." % action.value.title()) - - if monitoring_core == "nagios": - os.putenv("CORE_NOVERIFY", "yes") - command = ["%s/etc/init.d/core" % cmk.utils.paths.omd_root, action.value] - else: - command = ["omd", action.value, "cmc"] - - completed_process = subprocess.run( - command, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - close_fds=True, - check=False, - ) - if completed_process.returncode != 0: + with tracer.start_as_current_span( + f"do_core_action[{action.value}]", + attributes={ + "cmk.core_config.core": monitoring_core, + }, + ): if not quiet: - print_("ERROR: %r\n" % completed_process.stdout) - raise MKGeneralException( - f"Cannot {action.value} the monitoring core: {completed_process.stdout!r}" + print_("%sing monitoring core..." % action.value.title()) + + if monitoring_core == "nagios": + os.putenv("CORE_NOVERIFY", "yes") + command = ["%s/etc/init.d/core" % cmk.utils.paths.omd_root, action.value] + else: + command = ["omd", action.value, "cmc"] + + completed_process = subprocess.run( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + close_fds=True, + check=False, ) - if not quiet: - print_(tty.ok + "\n") + if completed_process.returncode != 0: + if not quiet: + print_("ERROR: %r\n" % completed_process.stdout) + raise MKGeneralException( + f"Cannot {action.value} the monitoring core: {completed_process.stdout!r}" + ) + if not quiet: + print_(tty.ok + "\n") diff --git a/cmk/base/core_config.py b/cmk/base/core_config.py index e7d47451c45..e3e93a04180 100644 --- a/cmk/base/core_config.py +++ b/cmk/base/core_config.py @@ -40,9 +40,13 @@ from cmk.base.config import ConfigCache, ObjectAttributes from cmk.base.nagios_utils import do_check_nagiosconfig +from cmk import trace + CoreCommandName = str CoreCommand = str +tracer = trace.get_tracer() + class MonitoringCore(abc.ABC): def __init__(self, licensing_handler_type: type[LicensingHandler]): @@ -69,7 +73,12 @@ def create_config( licensing_handler = self._licensing_handler_type.make() licensing_handler.persist_licensed_state(get_licensed_state_file_path()) self._create_config( - config_path, config_cache, ip_address_of, licensing_handler, passwords, hosts_to_update + config_path, + config_cache, + ip_address_of, + licensing_handler, + passwords, + hosts_to_update, ) if config.ruleset_matching_stats: config_cache.ruleset_matcher.persist_matching_stats( @@ -273,20 +282,28 @@ def do_create_config( ) try: - _create_core_config( - core, - config_cache, - ip_address_of, - hosts_to_update=hosts_to_update, - duplicates=duplicates, - ) + with tracer.start_as_current_span( + "create_core_config", + attributes={ + "cmk.core_config.core": core.name(), + "cmk.core_config.core_config.hosts_to_update": repr(hosts_to_update), + }, + ): + _create_core_config( + core, + config_cache, + ip_address_of, + hosts_to_update=hosts_to_update, + duplicates=duplicates, + ) except Exception as e: if cmk.ccc.debug.enabled(): raise raise MKGeneralException("Error creating configuration: %s" % e) if config.bake_agents_on_restart and not config.is_wato_slave_site: - _bake_on_restart(config_cache, all_hosts, skip_config_locking_for_bakery) + with tracer.start_as_current_span("bake_on_restart"): + _bake_on_restart(config_cache, all_hosts, skip_config_locking_for_bakery) def _bake_on_restart( @@ -298,8 +315,8 @@ def _bake_on_restart( agent_bakery, # pylint: disable=redefined-outer-name,import-outside-toplevel ) - from cmk.cee.bakery.type_defs import ( # pylint: disable=redefined-outer-name,import-outside-toplevel - BakeRevisionMode, + from cmk.cee.bakery.type_defs import ( + BakeRevisionMode, # pylint: disable=redefined-outer-name,import-outside-toplevel ) except ImportError: @@ -485,7 +502,8 @@ def get_service_attributes( attrs.update( ConfigCache._get_tag_attributes( - config_cache.ruleset_matcher.labels_of_service(hostname, description), "LABEL" + config_cache.ruleset_matcher.labels_of_service(hostname, description), + "LABEL", ) ) attrs.update( diff --git a/cmk/base/core_nagios/_create_config.py b/cmk/base/core_nagios/_create_config.py index a76fe412a5c..6c99e7c1784 100644 --- a/cmk/base/core_nagios/_create_config.py +++ b/cmk/base/core_nagios/_create_config.py @@ -70,8 +70,6 @@ def _create_config( self._create_core_config(config_path, licensing_handler, passwords, ip_address_of) self._precompile_hostchecks( config_path, - config.legacy_check_plugin_names, - config.legacy_check_plugin_files, precompile_mode=( PrecompileMode.DELAYED if config.delay_precompile else PrecompileMode.INSTANT ), @@ -116,8 +114,6 @@ def _create_core_config( def _precompile_hostchecks( self, config_path: VersionedConfigPath, - legacy_check_plugin_names: Mapping[CheckPluginName, str], - legacy_check_plugin_files: Mapping[str, str], *, precompile_mode: PrecompileMode, ) -> None: @@ -126,8 +122,6 @@ def _precompile_hostchecks( precompile_hostchecks( config_path, self._config_cache, - legacy_check_plugin_names, - legacy_check_plugin_files, precompile_mode=precompile_mode, ) with suppress(IOError): @@ -515,11 +509,14 @@ def get_dependencies(hostname: HostName, servicedesc: ServiceName) -> str: macros, ip_address_of, ), - host_attrs, config.http_proxies, lambda x: config.get_final_service_description(x, translations), stored_passwords, password_store.core_password_store_path(LATEST_CONFIG), + server_side_calls.ExecutableFinder( + cmk.utils.paths.local_nagios_plugins_dir, cmk.utils.paths.nagios_plugins_dir + ), + ip_lookup_failed=ip_lookup.is_fallback_ip(host_attrs["address"]), ) active_checks = config_cache.active_checks(hostname) diff --git a/cmk/base/core_nagios/_precompile_host_checks.py b/cmk/base/core_nagios/_precompile_host_checks.py index 35b22b0aa90..f6f2a73db4b 100644 --- a/cmk/base/core_nagios/_precompile_host_checks.py +++ b/cmk/base/core_nagios/_precompile_host_checks.py @@ -18,7 +18,7 @@ import re import socket import sys -from collections.abc import Mapping +from collections.abc import Iterable from pathlib import Path from typing import assert_never @@ -28,7 +28,6 @@ import cmk.utils.password_store import cmk.utils.paths from cmk.utils import tty -from cmk.utils.check_utils import section_name_of from cmk.utils.config_path import VersionedConfigPath from cmk.utils.hostaddress import HostAddress, HostName from cmk.utils.ip_lookup import IPStackConfig @@ -40,6 +39,7 @@ import cmk.base.api.agent_based.register as agent_based_register import cmk.base.utils from cmk.base import server_side_calls +from cmk.base.api.agent_based.plugin_classes import LegacyPluginLocation, SectionPlugin from cmk.base.config import ConfigCache, FilterMode, lookup_ip_address, save_packed_config from cmk.discover_plugins import PluginLocation @@ -108,8 +108,6 @@ def write( def precompile_hostchecks( config_path: VersionedConfigPath, config_cache: ConfigCache, - legacy_check_plugin_names: Mapping[CheckPluginName, str], - legacy_check_plugin_files: Mapping[str, str], *, precompile_mode: PrecompileMode, ) -> None: @@ -135,8 +133,6 @@ def precompile_hostchecks( config_cache, config_path, hostname, - legacy_check_plugin_names, - legacy_check_plugin_files, precompile_mode=precompile_mode, ) if host_check is None: @@ -157,62 +153,57 @@ def dump_precompiled_hostcheck( # pylint: disable=too-many-branches config_cache: ConfigCache, config_path: VersionedConfigPath, hostname: HostName, - legacy_check_plugin_names: Mapping[CheckPluginName, str], - legacy_check_plugin_files: Mapping[str, str], *, verify_site_python: bool = True, precompile_mode: PrecompileMode, ) -> str | None: ( - needed_legacy_check_plugin_names, needed_agent_based_check_plugin_names, needed_agent_based_inventory_plugin_names, - ) = _get_needed_plugin_names(config_cache, hostname, legacy_check_plugin_names) + ) = _get_needed_plugin_names(config_cache, hostname) if hostname in config_cache.hosts_config.clusters: assert config_cache.nodes(hostname) for node in config_cache.nodes(hostname): ( - node_needed_legacy_check_plugin_names, node_needed_agent_based_check_plugin_names, node_needed_agent_based_inventory_plugin_names, - ) = _get_needed_plugin_names(config_cache, node, legacy_check_plugin_names) - needed_legacy_check_plugin_names.update(node_needed_legacy_check_plugin_names) + ) = _get_needed_plugin_names(config_cache, node) needed_agent_based_check_plugin_names.update(node_needed_agent_based_check_plugin_names) needed_agent_based_inventory_plugin_names.update( node_needed_agent_based_inventory_plugin_names ) - needed_legacy_check_plugin_names.update( - _get_required_legacy_check_sections( - needed_agent_based_check_plugin_names, - needed_agent_based_inventory_plugin_names, - ) - ) + needed_legacy_special_agents = _get_needed_legacy_special_agents(config_cache, hostname) if not any( ( - needed_legacy_check_plugin_names, + needed_legacy_special_agents, needed_agent_based_check_plugin_names, needed_agent_based_inventory_plugin_names, ) ): return None + needed_agent_based_section_plugin_names = agent_based_register.get_relevant_raw_sections( + check_plugin_names=needed_agent_based_check_plugin_names, + inventory_plugin_names=needed_agent_based_inventory_plugin_names, + ) + locations = _get_needed_agent_based_locations( + needed_agent_based_section_plugin_names.values(), needed_agent_based_check_plugin_names, needed_agent_based_inventory_plugin_names, ) - checks_to_load = sorted( - _get_legacy_check_file_names_to_load( - needed_legacy_check_plugin_names, legacy_check_plugin_files + legacy_checks_to_load = sorted( + _get_needed_legacy_check_files( + needed_agent_based_section_plugin_names.values(), + needed_agent_based_check_plugin_names, + needed_legacy_special_agents, ) ) - for check_plugin_name in sorted(needed_legacy_check_plugin_names): - console.verbose_no_lf(f" {tty.green}{check_plugin_name}{tty.normal}", file=sys.stderr) - # IP addresses # FIXME: # What we construct here does not match what we need to assign it to `config.ipaddresses` and @@ -270,7 +261,7 @@ def dump_precompiled_hostcheck( # pylint: disable=too-many-branches dst=str(HostCheckStore.host_check_file_path(config_path, hostname)), verify_site_python=verify_site_python, locations=locations, - checks_to_load=checks_to_load, + checks_to_load=legacy_checks_to_load, ipaddresses=needed_ipaddresses, # type: ignore[arg-type] # see FIXME above. ipv6addresses=needed_ipv6addresses, # type: ignore[arg-type] # see FIXME above. hostname=hostname, @@ -289,15 +280,7 @@ def dump_precompiled_hostcheck( # pylint: disable=too-many-branches def _get_needed_plugin_names( config_cache: ConfigCache, host_name: HostName, - legacy_check_plugin_names: Mapping[CheckPluginName, str], -) -> tuple[set[str], set[CheckPluginName], set[InventoryPluginName]]: - ssc_api_special_agents = {p.name for p in server_side_calls.load_special_agents()[1].values()} - needed_legacy_check_plugin_names = { - f"agent_{name}" - for name, _p in config_cache.special_agents(host_name) - if name not in ssc_api_special_agents - } - +) -> tuple[set[CheckPluginName], set[InventoryPluginName]]: # Collect the needed check plug-in names using the host check table. # Even auto-migrated checks must be on the list of needed *agent based* plugins: # In those cases, the module attribute will be `None`, so nothing will @@ -305,127 +288,75 @@ def _get_needed_plugin_names( # when determining the needed *section* plugins. # This matters in cases where the section is migrated, but the check # plugins are not. - needed_agent_based_check_plugin_names = config_cache.check_table( - host_name, - filter_mode=FilterMode.INCLUDE_CLUSTERED, - skip_ignored=False, - ).needed_check_names() - - legacy_names = ( - _resolve_legacy_plugin_name(pn, legacy_check_plugin_names) - for pn in needed_agent_based_check_plugin_names - ) - needed_legacy_check_plugin_names.update(ln for ln in legacy_names if ln is not None) - - # Inventory plugins get passed parsed data these days. - # Load the required sections, or inventory plugins will crash upon unparsed data. - needed_agent_based_inventory_plugin_names: set[InventoryPluginName] = set() - if config_cache.hwsw_inventory_parameters(host_name).status_data_inventory: - for inventory_plugin in agent_based_register.iter_all_inventory_plugins(): - needed_agent_based_inventory_plugin_names.add(inventory_plugin.name) - for parsed_section_name in inventory_plugin.sections: - # check if we must add the legacy check plug-in: - legacy_check_name = legacy_check_plugin_names.get( - CheckPluginName(str(parsed_section_name)) - ) - if legacy_check_name is not None: - needed_legacy_check_plugin_names.add(legacy_check_name) - return ( - needed_legacy_check_plugin_names, - needed_agent_based_check_plugin_names, - needed_agent_based_inventory_plugin_names, + config_cache.check_table( + host_name, + filter_mode=FilterMode.INCLUDE_CLUSTERED, + skip_ignored=False, + ).needed_check_names(), + { + inventory_plugin.name + for inventory_plugin in agent_based_register.iter_all_inventory_plugins() + } + if config_cache.hwsw_inventory_parameters(host_name).status_data_inventory + else set(), ) -def _resolve_legacy_plugin_name( - check_plugin_name: CheckPluginName, legacy_check_plugin_names: Mapping[CheckPluginName, str] -) -> str | None: - legacy_name = legacy_check_plugin_names.get(check_plugin_name) - if legacy_name: - return legacy_name - - if not check_plugin_name.is_management_name(): - return None - - # See if me must include a legacy plug-in from which we derived the given one: - # A management plug-in *could have been* created on the fly, from a 'regular' legacy - # check plug-in. In this case, we must load that. - plugin = agent_based_register.get_check_plugin(check_plugin_name) - if not plugin or plugin.location is not None: - # it does *not* result from a legacy plugin, if module is not None - return None - - # just try to get the legacy name of the 'regular' plugin: - return legacy_check_plugin_names.get(check_plugin_name.create_basic_name()) - - -def _get_legacy_check_file_names_to_load( - needed_check_plugin_names: set[str], - legacy_check_plugin_files: Mapping[str, str], -) -> set[str]: - # check info table - # We need to include all those plugins that are referenced in the hosts - # check table. +def _get_needed_legacy_special_agents(config_cache: ConfigCache, host_name: HostName) -> set[str]: + ssc_api_special_agents = {p.name for p in server_side_calls.load_special_agents()[1].values()} return { - filename - for check_plugin_name in needed_check_plugin_names - for filename in _find_check_plugins(check_plugin_name, legacy_check_plugin_files) + f"agent_{name}" + for name, _p in config_cache.special_agents(host_name) + if name not in ssc_api_special_agents } -def _find_check_plugins(checktype: str, legacy_check_plugin_files: Mapping[str, str]) -> set[str]: - """Find files to be included in precompile host check for a certain - check (for example df or mem.used). - - In case of checks with a period (subchecks) we might have to include both "mem" and "mem.used". - The subcheck *may* be implemented in a separate file.""" - return { - filename - for candidate in (section_name_of(checktype), checktype) - # in case there is no "main check" anymore, the lookup fails -> skip. - if (filename := legacy_check_plugin_files.get(candidate)) is not None - } +def _get_needed_legacy_check_files( + section_plugins: Iterable[SectionPlugin], + check_plugin_names: Iterable[CheckPluginName], + legacy_special_agent_names: set[str], +) -> set[str]: + return ( + { + section.location.file_name + for section in section_plugins + if isinstance(section.location, LegacyPluginLocation) + } + | { + check_plugin.location.file_name + for check_plugin_name in check_plugin_names + if (check_plugin := agent_based_register.get_check_plugin(check_plugin_name)) + is not None + and isinstance(check_plugin.location, LegacyPluginLocation) + } + | { + f"{os.path.join(base, name)}.py" + for base in (cmk.utils.paths.local_checks_dir, cmk.utils.paths.checks_dir) + for name in legacy_special_agent_names + } + ) def _get_needed_agent_based_locations( - check_plugin_names: set[CheckPluginName], - inventory_plugin_names: set[InventoryPluginName], + section_plugins: Iterable[SectionPlugin], + check_plugin_names: Iterable[CheckPluginName], + inventory_plugin_names: Iterable[InventoryPluginName], ) -> list[PluginLocation]: modules = { plugin.location for plugin in [agent_based_register.get_check_plugin(p) for p in check_plugin_names] - if plugin is not None and plugin.location is not None + if plugin is not None and isinstance(plugin.location, PluginLocation) } modules.update( plugin.location for plugin in [agent_based_register.get_inventory_plugin(p) for p in inventory_plugin_names] - if plugin is not None and plugin.location is not None + if plugin is not None and isinstance(plugin.location, PluginLocation) ) modules.update( section.location - for section in agent_based_register.get_relevant_raw_sections( - check_plugin_names=check_plugin_names, - inventory_plugin_names=inventory_plugin_names, - ).values() - if section.location is not None + for section in section_plugins + if isinstance(section.location, PluginLocation) ) return sorted(modules, key=lambda l: (l.module, l.name or "")) - - -def _get_required_legacy_check_sections( - check_plugin_names: set[CheckPluginName], - inventory_plugin_names: set[InventoryPluginName], -) -> set[str]: - """ - new style plug-in may have a dependency to a legacy check - """ - required_legacy_check_sections = set() - for section in agent_based_register.get_relevant_raw_sections( - check_plugin_names=check_plugin_names, - inventory_plugin_names=inventory_plugin_names, - ).values(): - if section.location is None: - required_legacy_check_sections.add(str(section.name)) - return required_legacy_check_sections diff --git a/cmk/base/default_config/base.py b/cmk/base/default_config/base.py index cd8b7d1d9ba..9af061f60ff 100644 --- a/cmk/base/default_config/base.py +++ b/cmk/base/default_config/base.py @@ -185,7 +185,6 @@ class _PeriodicDiscovery(TypedDict): "tag_groups": [], } static_checks: dict[str, list[RuleSpec[list[object]]]] = {} -check_parameters: list[RuleSpec[Any]] = [] checkgroup_parameters: dict[str, list[RuleSpec[Mapping[str, object]]]] = {} # for HW/SW Inventory inv_parameters: dict[str, list[RuleSpec[Mapping[str, object]]]] = {} diff --git a/cmk/base/diagnostics.py b/cmk/base/diagnostics.py index 8b971829845..c7b4778f3f8 100644 --- a/cmk/base/diagnostics.py +++ b/cmk/base/diagnostics.py @@ -62,7 +62,7 @@ from cmk.utils.local_secrets import AutomationUserSecret from cmk.utils.log import console, section from cmk.utils.paths import omd_root -from cmk.utils.structured_data import load_tree, SDNodeName, SDRawTree +from cmk.utils.structured_data import load_tree, SDNodeName, SDRawTree, serialize_tree from cmk.utils.user import UserId if cmk_version.edition(cmk.utils.paths.omd_root) in [ @@ -829,7 +829,7 @@ def _collect_infos(self) -> SDRawTree: raise DiagnosticsElementError( "No HW/SW Inventory node 'Software > Applications > Checkmk'" ) - return node.serialize() + return serialize_tree(node) # ---collect exiting files------------------------------------------------ diff --git a/cmk/base/errorhandling/_crash.py b/cmk/base/errorhandling/_crash.py index 1830bd0e080..13a66869d32 100644 --- a/cmk/base/errorhandling/_crash.py +++ b/cmk/base/errorhandling/_crash.py @@ -24,7 +24,7 @@ from cmk.checkengine.checking import CheckPluginName -from cmk.piggyback import get_piggyback_raw_data +from cmk.piggyback import get_messages_for CrashReportStore = crash_reporting.CrashReportStore @@ -172,9 +172,7 @@ def _read_agent_output(hostname: HostName) -> AgentRawData | None: pass # Note: this is not quite what the fetcher does :( - agent_outputs.extend( - r.raw_data for r in get_piggyback_raw_data(hostname, cmk.utils.paths.omd_root) - ) + agent_outputs.extend(r.raw_data for r in get_messages_for(hostname, cmk.utils.paths.omd_root)) if agent_outputs: return AgentRawData(b"\n".join(agent_outputs)) diff --git a/cmk/base/legacy_checks/3ware_disks.py b/cmk/base/legacy_checks/3ware_disks.py index 2f4649fd457..e76ab860314 100644 --- a/cmk/base/legacy_checks/3ware_disks.py +++ b/cmk/base/legacy_checks/3ware_disks.py @@ -85,6 +85,7 @@ def parse_3ware_disks(string_table: StringTable) -> StringTable: check_info["3ware_disks"] = LegacyCheckDefinition( + name="3ware_disks", parse_function=parse_3ware_disks, service_name="RAID 3ware disk %s", discovery_function=inventory_3ware_disks, diff --git a/cmk/base/legacy_checks/3ware_info.py b/cmk/base/legacy_checks/3ware_info.py index e925f08a765..b35b4bbc83a 100644 --- a/cmk/base/legacy_checks/3ware_info.py +++ b/cmk/base/legacy_checks/3ware_info.py @@ -51,6 +51,7 @@ def parse_3ware_info(string_table: StringTable) -> StringTable: check_info["3ware_info"] = LegacyCheckDefinition( + name="3ware_info", parse_function=parse_3ware_info, service_name="RAID 3ware controller %s", discovery_function=inventory_3ware_info, diff --git a/cmk/base/legacy_checks/3ware_units.py b/cmk/base/legacy_checks/3ware_units.py index edcb6d68883..c930264d144 100644 --- a/cmk/base/legacy_checks/3ware_units.py +++ b/cmk/base/legacy_checks/3ware_units.py @@ -71,6 +71,7 @@ def parse_3ware_units(string_table: StringTable) -> StringTable: check_info["3ware_units"] = LegacyCheckDefinition( + name="3ware_units", parse_function=parse_3ware_units, service_name="RAID 3ware unit %s", discovery_function=inventory_3ware_units, diff --git a/cmk/base/legacy_checks/acme_certificates.py b/cmk/base/legacy_checks/acme_certificates.py index b720e94ec0c..0fbb012e981 100644 --- a/cmk/base/legacy_checks/acme_certificates.py +++ b/cmk/base/legacy_checks/acme_certificates.py @@ -63,6 +63,7 @@ def parse_acme_certificates(string_table: StringTable) -> StringTable: check_info["acme_certificates"] = LegacyCheckDefinition( + name="acme_certificates", parse_function=parse_acme_certificates, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/acme_fan.py b/cmk/base/legacy_checks/acme_fan.py index e70ff4cd572..c3535bb86fd 100644 --- a/cmk/base/legacy_checks/acme_fan.py +++ b/cmk/base/legacy_checks/acme_fan.py @@ -40,6 +40,7 @@ def parse_acme_fan(string_table: StringTable) -> StringTable: check_info["acme_fan"] = LegacyCheckDefinition( + name="acme_fan", parse_function=parse_acme_fan, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/acme_powersupply.py b/cmk/base/legacy_checks/acme_powersupply.py index 72482f9e164..694aee53b96 100644 --- a/cmk/base/legacy_checks/acme_powersupply.py +++ b/cmk/base/legacy_checks/acme_powersupply.py @@ -33,6 +33,7 @@ def parse_acme_powersupply(string_table: StringTable) -> StringTable: check_info["acme_powersupply"] = LegacyCheckDefinition( + name="acme_powersupply", parse_function=parse_acme_powersupply, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/acme_sbc_snmp.py b/cmk/base/legacy_checks/acme_sbc_snmp.py index 2878cc6adde..46164e9e945 100644 --- a/cmk/base/legacy_checks/acme_sbc_snmp.py +++ b/cmk/base/legacy_checks/acme_sbc_snmp.py @@ -62,6 +62,7 @@ def parse_acme_sbc_snmp(string_table: StringTable) -> StringTable | None: check_info["acme_sbc_snmp"] = LegacyCheckDefinition( + name="acme_sbc_snmp", parse_function=parse_acme_sbc_snmp, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/acme_temp.py b/cmk/base/legacy_checks/acme_temp.py index 1d14d11172b..d8a264d8bc8 100644 --- a/cmk/base/legacy_checks/acme_temp.py +++ b/cmk/base/legacy_checks/acme_temp.py @@ -60,6 +60,7 @@ def parse_acme_temp(string_table: StringTable) -> StringTable: check_info["acme_temp"] = LegacyCheckDefinition( + name="acme_temp", parse_function=parse_acme_temp, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/acme_voltage.py b/cmk/base/legacy_checks/acme_voltage.py index ef712826267..66a4f19f349 100644 --- a/cmk/base/legacy_checks/acme_voltage.py +++ b/cmk/base/legacy_checks/acme_voltage.py @@ -76,6 +76,7 @@ def parse_acme_voltage(string_table: StringTable) -> StringTable: check_info["acme_voltage"] = LegacyCheckDefinition( + name="acme_voltage", parse_function=parse_acme_voltage, detect=DETECT_ACME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ad_replication.py b/cmk/base/legacy_checks/ad_replication.py index 970223cd6b7..af5039af943 100644 --- a/cmk/base/legacy_checks/ad_replication.py +++ b/cmk/base/legacy_checks/ad_replication.py @@ -183,6 +183,7 @@ def parse_ad_replication(string_table: StringTable) -> StringTable: check_info["ad_replication"] = LegacyCheckDefinition( + name="ad_replication", parse_function=parse_ad_replication, service_name="AD Replication %s", discovery_function=inventory_ad_replication, diff --git a/cmk/base/legacy_checks/adva_fsp_temp.py b/cmk/base/legacy_checks/adva_fsp_temp.py index 863c125360e..eb4aeac87a2 100644 --- a/cmk/base/legacy_checks/adva_fsp_temp.py +++ b/cmk/base/legacy_checks/adva_fsp_temp.py @@ -51,6 +51,7 @@ def parse_adva_fsp_temp(string_table: StringTable) -> StringTable: check_info["adva_fsp_temp"] = LegacyCheckDefinition( + name="adva_fsp_temp", parse_function=parse_adva_fsp_temp, detect=equals(".1.3.6.1.2.1.1.1.0", "Fiber Service Platform F7"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/agent_hivemanager.py b/cmk/base/legacy_checks/agent_hivemanager.py deleted file mode 100644 index d771cac398e..00000000000 --- a/cmk/base/legacy_checks/agent_hivemanager.py +++ /dev/null @@ -1,22 +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. - - -# mypy: disable-error-code="list-item" - -from collections.abc import Sequence - -from cmk.base.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_hivemanager_arguments( - params: tuple, hostname: str, ipaddress: str | None -) -> Sequence[str]: - # User, Password - return [ipaddress or hostname, params[0], passwordstore_get_cmdline("%s", params[1])] - - -special_agent_info["hivemanager"] = agent_hivemanager_arguments diff --git a/cmk/base/legacy_checks/agent_hivemanager_ng.py b/cmk/base/legacy_checks/agent_hivemanager_ng.py deleted file mode 100644 index 1a01021adc2..00000000000 --- a/cmk/base/legacy_checks/agent_hivemanager_ng.py +++ /dev/null @@ -1,38 +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. - -# { -# 'url': 'https://cloud.aerohive.com', -# 'vhm_id': '12345', -# 'api_token': 'SDLKFJ32401ac1KSjKLLWIUDSKDJW', -# 'client_id': '123a4b56', -# 'client_secret': '1abc23456d13098123098e', -# 'redirect_url': 'https://www.getpostman.com/oauth2/callback' -# } - - -# mypy: disable-error-code="list-item" - -from collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_hivemanager_ng_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str]: - return [ - params["url"], - params["vhm_id"], - params["api_token"], - params["client_id"], - passwordstore_get_cmdline("%s", params["client_secret"]), - params["redirect_url"], - ] - - -special_agent_info["hivemanager_ng"] = agent_hivemanager_ng_arguments diff --git a/cmk/base/legacy_checks/agent_hp_msa.py b/cmk/base/legacy_checks/agent_hp_msa.py deleted file mode 100644 index b4c1d10b97e..00000000000 --- a/cmk/base/legacy_checks/agent_hp_msa.py +++ /dev/null @@ -1,28 +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. - - -# mypy: disable-error-code="list-item" - -from collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_hp_msa_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str]: - return [ - "-u", - params["username"], - "-p", - passwordstore_get_cmdline("%s", params["password"]), - ipaddress or hostname, - ] - - -special_agent_info["hp_msa"] = agent_hp_msa_arguments 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/base/legacy_checks/agent_innovaphone.py b/cmk/base/legacy_checks/agent_innovaphone.py deleted file mode 100644 index 02cb4b5071f..00000000000 --- a/cmk/base/legacy_checks/agent_innovaphone.py +++ /dev/null @@ -1,29 +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.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_innovaphone_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str | tuple[str, str, str]]: - auth_info = params["auth_basic"] - username = auth_info["username"] - password = passwordstore_get_cmdline("%s", auth_info["password"]) - args = [hostname, username, password] - protocol = params.get("protocol") - if protocol: - args.extend(["--protocol", protocol]) - if params.get("no-cert-check"): - args.append("--no-cert-check") - return args - - -special_agent_info["innovaphone"] = agent_innovaphone_arguments diff --git a/cmk/base/legacy_checks/agent_jolokia.py b/cmk/base/legacy_checks/agent_jolokia.py deleted file mode 100644 index 264583fe320..00000000000 --- a/cmk/base/legacy_checks/agent_jolokia.py +++ /dev/null @@ -1,39 +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. - - -# mypy: disable-error-code="list-item" - -from collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_jolokia_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str]: - arglist = ["--server", ipaddress or hostname] - - for param in ["port", "suburi", "instance", "protocol"]: - if param in params: - arglist += ["--%s" % param, "%s" % params[param]] - - if login := params.get("login"): - user, password, mode = login - arglist += [ - "--user", - user, - "--password", - passwordstore_get_cmdline("%s", password), - "--mode", - mode, - ] - - return arglist - - -special_agent_info["jolokia"] = agent_jolokia_arguments diff --git a/cmk/base/legacy_checks/agent_random.py b/cmk/base/legacy_checks/agent_random.py deleted file mode 100644 index b1f75f267d6..00000000000 --- a/cmk/base/legacy_checks/agent_random.py +++ /dev/null @@ -1,26 +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. - -# { -# 'tcp_port': 4711, -# 'secret': 'wef', -# 'infos': ['hostsystem', 'virtualmachine'], -# 'user': 'wefwef' -# } - - -from collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.config import special_agent_info - - -def agent_random_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str]: - return [hostname] - - -special_agent_info["random"] = agent_random_arguments diff --git a/cmk/base/legacy_checks/agent_storeonce4x.py b/cmk/base/legacy_checks/agent_storeonce4x.py deleted file mode 100644 index 5180dadff4d..00000000000 --- a/cmk/base/legacy_checks/agent_storeonce4x.py +++ /dev/null @@ -1,29 +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.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_storeonce4x_arguments( - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str | tuple[str, str, str]]: - args = [ - params["user"], - passwordstore_get_cmdline("%s", params["password"]), - hostname, - ] - - if "cert" in params and params["cert"] is True: - args.append("--verify_ssl") - - return args - - -special_agent_info["storeonce4x"] = agent_storeonce4x_arguments diff --git a/cmk/base/legacy_checks/agent_vsphere.py b/cmk/base/legacy_checks/agent_vsphere.py deleted file mode 100644 index f7915baa817..00000000000 --- a/cmk/base/legacy_checks/agent_vsphere.py +++ /dev/null @@ -1,73 +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. - -# { -# 'tcp_port': 443, -# 'secret': 'wef', -# 'infos': ['hostsystem', 'virtualmachine'], -# 'user': 'wefwef' -# } - - -# mypy: disable-error-code="list-item" - -from collections.abc import Mapping, Sequence -from typing import Any - -from cmk.base.check_api import passwordstore_get_cmdline -from cmk.base.config import special_agent_info - - -def agent_vsphere_arguments( # pylint: disable=too-many-branches - params: Mapping[str, Any], hostname: str, ipaddress: str | None -) -> Sequence[str | tuple[str, str, str]]: - args = [] - if "tcp_port" in params: - args += ["-p", "%d" % params["tcp_port"]] - - args += ["-u", params["user"]] - args += [passwordstore_get_cmdline("-s=%s", params["secret"])] - args += ["-i", ",".join(params["infos"])] - - # True: Queried host is a host system - # False: Queried host is the vCenter - if params["direct"]: - args += ["--direct", "--hostname", hostname] - - if params.get("skip_placeholder_vms", True): - args.append("-P") - - if "spaces" in params: - args += ["--spaces", params["spaces"]] - - if "timeout" in params: - args += ["--timeout", params["timeout"]] - - if v_display := params.get("vm_pwr_display"): - args += ["--vm_pwr_display", v_display] - - if vm_piggyname := params.get("vm_piggyname"): - args += ["--vm_piggyname", vm_piggyname] - - if h_display := params.get("host_pwr_display"): - args += ["--host_pwr_display", h_display] - - if params.get("snapshots_on_host", False): - args += ["--snapshots-on-host"] - - cert_verify = params.get("ssl", True) - if cert_verify is False: - args += ["--no-cert-check"] - elif cert_verify is True: - args += ["--cert-server-name", hostname] - else: - args += ["--cert-server-name", cert_verify] - - args.append(ipaddress or hostname) - - return args - - -special_agent_info["vsphere"] = agent_vsphere_arguments diff --git a/cmk/base/legacy_checks/aironet_errors.py b/cmk/base/legacy_checks/aironet_errors.py index 798296e9ab4..5760c95e596 100644 --- a/cmk/base/legacy_checks/aironet_errors.py +++ b/cmk/base/legacy_checks/aironet_errors.py @@ -49,6 +49,7 @@ def parse_aironet_errors(string_table: StringTable) -> StringTable: check_info["aironet_errors"] = LegacyCheckDefinition( + name="aironet_errors", parse_function=parse_aironet_errors, detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.9.1.525"), diff --git a/cmk/base/legacy_checks/aix_hacmp_resources.py b/cmk/base/legacy_checks/aix_hacmp_resources.py index a1accabda83..ec7ad5fc2ad 100644 --- a/cmk/base/legacy_checks/aix_hacmp_resources.py +++ b/cmk/base/legacy_checks/aix_hacmp_resources.py @@ -66,6 +66,7 @@ def check_aix_hacmp_resources(item, params, parsed): check_info["aix_hacmp_resources"] = LegacyCheckDefinition( + name="aix_hacmp_resources", parse_function=parse_aix_hacmp_resources, service_name="HACMP RG %s", discovery_function=inventory_aix_hacmp_resources, diff --git a/cmk/base/legacy_checks/aix_paging.py b/cmk/base/legacy_checks/aix_paging.py index 5b1dfe78b2d..8fb0eb13193 100644 --- a/cmk/base/legacy_checks/aix_paging.py +++ b/cmk/base/legacy_checks/aix_paging.py @@ -65,6 +65,7 @@ def discover_aix_paging(section): check_info["aix_paging"] = LegacyCheckDefinition( + name="aix_paging", parse_function=parse_aix_paging, service_name="Page Space %s", discovery_function=discover_aix_paging, diff --git a/cmk/base/legacy_checks/akcp_daisy_temp.py b/cmk/base/legacy_checks/akcp_daisy_temp.py index 012da556ddf..9a2a1d1e03d 100644 --- a/cmk/base/legacy_checks/akcp_daisy_temp.py +++ b/cmk/base/legacy_checks/akcp_daisy_temp.py @@ -44,6 +44,7 @@ def parse_akcp_daisy_temp(string_table: Sequence[StringTable]) -> Sequence[Strin check_info["akcp_daisy_temp"] = LegacyCheckDefinition( + name="akcp_daisy_temp", parse_function=parse_akcp_daisy_temp, detect=all_of( any_of( diff --git a/cmk/base/legacy_checks/alcatel_temp.py b/cmk/base/legacy_checks/alcatel_temp.py index e5e8eec9704..9c191f87539 100644 --- a/cmk/base/legacy_checks/alcatel_temp.py +++ b/cmk/base/legacy_checks/alcatel_temp.py @@ -44,6 +44,7 @@ def check_alcatel_temp(item, params, info): check_info["alcatel_temp"] = LegacyCheckDefinition( + name="alcatel_temp", parse_function=parse_alcatel_temp, detect=DETECT_ALCATEL, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/alcatel_temp_aos7.py b/cmk/base/legacy_checks/alcatel_temp_aos7.py index 01dc9fd7b68..f497aebedcb 100644 --- a/cmk/base/legacy_checks/alcatel_temp_aos7.py +++ b/cmk/base/legacy_checks/alcatel_temp_aos7.py @@ -56,6 +56,7 @@ def discover_alcatel_temp_aos7(section): check_info["alcatel_temp_aos7"] = LegacyCheckDefinition( + name="alcatel_temp_aos7", detect=DETECT_ALCATEL_AOS7, fetch=SNMPTree( base=".1.3.6.1.4.1.6486.801.1.1.1.3.1.1.3.1", diff --git a/cmk/base/legacy_checks/alcatel_timetra_cpu.py b/cmk/base/legacy_checks/alcatel_timetra_cpu.py index 4a8eddd3bd8..51c1130c7b6 100644 --- a/cmk/base/legacy_checks/alcatel_timetra_cpu.py +++ b/cmk/base/legacy_checks/alcatel_timetra_cpu.py @@ -25,6 +25,7 @@ def parse_alcatel_timetra_cpu(string_table: StringTable) -> StringTable | None: check_info["alcatel_timetra_cpu"] = LegacyCheckDefinition( + name="alcatel_timetra_cpu", parse_function=parse_alcatel_timetra_cpu, detect=contains(".1.3.6.1.2.1.1.1.0", "TiMOS"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/allnet_ip_sensoric.py b/cmk/base/legacy_checks/allnet_ip_sensoric.py index 8c0121c8ad1..539fd8da7a9 100644 --- a/cmk/base/legacy_checks/allnet_ip_sensoric.py +++ b/cmk/base/legacy_checks/allnet_ip_sensoric.py @@ -102,6 +102,7 @@ def check_allnet_ip_sensoric_tension(item, _no_params, parsed): check_info["allnet_ip_sensoric.tension"] = LegacyCheckDefinition( + name="allnet_ip_sensoric_tension", # section already migrated! service_name="Electric Tension %s", sections=["allnet_ip_sensoric"], @@ -140,6 +141,7 @@ def check_allnet_ip_sensoric_temp(item, params, parsed): check_info["allnet_ip_sensoric.temp"] = LegacyCheckDefinition( + name="allnet_ip_sensoric_temp", # section already migrated! service_name="Temperature %s", sections=["allnet_ip_sensoric"], @@ -177,6 +179,7 @@ def check_allnet_ip_sensoric_humidity(item, params, parsed): check_info["allnet_ip_sensoric.humidity"] = LegacyCheckDefinition( + name="allnet_ip_sensoric_humidity", # section already migrated! service_name="Humidity %s", sections=["allnet_ip_sensoric"], @@ -222,6 +225,7 @@ def check_allnet_ip_sensoric_pressure(item, _no_params, parsed): check_info["allnet_ip_sensoric.pressure"] = LegacyCheckDefinition( + name="allnet_ip_sensoric_pressure", # section already migrated! service_name="Pressure %s", sections=["allnet_ip_sensoric"], diff --git a/cmk/base/legacy_checks/apc_ats_output.py b/cmk/base/legacy_checks/apc_ats_output.py deleted file mode 100644 index f7b49dfbf38..00000000000 --- a/cmk/base/legacy_checks/apc_ats_output.py +++ /dev/null @@ -1,84 +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.base.check_api import check_levels, LegacyCheckDefinition -from cmk.base.config import check_info - -from cmk.agent_based.v2 import SNMPTree -from cmk.plugins.lib.apc import DETECT_ATS - -# mypy: disable-error-code="var-annotated" - - -def parse_apc_ats_output(string_table): - parsed = {} - for index, voltage_str, current_str, perc_load_str, power_str in string_table: - for key, value_str, factor in [ - ("voltage", voltage_str, 1), - ("current", current_str, 0.1), - ("perc_load", perc_load_str, 1), - ("power", power_str, 1), - ]: - try: - value = float(value_str) * factor - except ValueError: - continue - instance = parsed.setdefault(index, {}) - instance[key] = value - return parsed - - -def discover_apc_ats_output(parsed): - yield from ((item, {}) for item in parsed) - - -def check_apc_ats_output(item, params, parsed): - if not (data := parsed.get(item)): - return - voltage = data.get("voltage") - power = data.get("power") - current = data.get("current") - perc_load = data.get("perc_load") - - if voltage is not None: - yield check_levels( - voltage, - "volt", - params.get("output_voltage_max", (None, None)) - + params.get("output_voltage_min", (None, None)), - infoname="Voltage", - unit="V", - ) - if power is not None: - yield 0, "Power: %.2f W" % power - - if current is not None: - yield 0, "Current: %.2f A" % current - - if perc_load is not None: - yield check_levels( - perc_load, - "load_perc", - params.get("load_perc_max", (None, None)) + params.get("load_perc_min", (None, None)), - infoname="Load", - unit="%", - ) - - -check_info["apc_ats_output"] = LegacyCheckDefinition( - detect=DETECT_ATS, - fetch=SNMPTree( - base=".1.3.6.1.4.1.318.1.1.8.5.4.3.1", - oids=["1", "3", "4", "10", "13"], - ), - parse_function=parse_apc_ats_output, - service_name="Phase %s output", - discovery_function=discover_apc_ats_output, - check_function=check_apc_ats_output, - check_ruleset_name="apc_ats_output", - check_default_parameters={ - "output_voltage_max": (240, 250), - "load_perc_max": (85.0, 95.0), - }, -) diff --git a/cmk/base/legacy_checks/apc_ats_status.py b/cmk/base/legacy_checks/apc_ats_status.py index 6fbd90739d0..3844e728ef0 100644 --- a/cmk/base/legacy_checks/apc_ats_status.py +++ b/cmk/base/legacy_checks/apc_ats_status.py @@ -85,6 +85,7 @@ def check_apc_ats_status(_no_item: Any, params: dict, parsed: Status) -> Iterabl check_info["apc_ats_status"] = LegacyCheckDefinition( + name="apc_ats_status", parse_function=parse_apc_ats_status, detect=DETECT_ATS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/apc_humidity.py b/cmk/base/legacy_checks/apc_humidity.py index 70dc441cc0e..48a3cd325a8 100644 --- a/cmk/base/legacy_checks/apc_humidity.py +++ b/cmk/base/legacy_checks/apc_humidity.py @@ -43,6 +43,7 @@ def parse_apc_humidity(string_table: StringTable) -> StringTable: check_info["apc_humidity"] = LegacyCheckDefinition( + name="apc_humidity", parse_function=parse_apc_humidity, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/apc_inrow_airflow.py b/cmk/base/legacy_checks/apc_inrow_airflow.py index aa08bbaea64..f44f44e41c7 100644 --- a/cmk/base/legacy_checks/apc_inrow_airflow.py +++ b/cmk/base/legacy_checks/apc_inrow_airflow.py @@ -53,6 +53,7 @@ def parse_apc_inrow_airflow(string_table: StringTable) -> StringTable: check_info["apc_inrow_airflow"] = LegacyCheckDefinition( + name="apc_inrow_airflow", parse_function=parse_apc_inrow_airflow, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/apc_inrow_temp.py b/cmk/base/legacy_checks/apc_inrow_temp.py index 4037f228f9c..0633a723159 100644 --- a/cmk/base/legacy_checks/apc_inrow_temp.py +++ b/cmk/base/legacy_checks/apc_inrow_temp.py @@ -45,6 +45,7 @@ def check_apc_inrow_temp(item, params, parsed): check_info["apc_inrow_temp"] = LegacyCheckDefinition( + name="apc_inrow_temp", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.318.1.1.13.3.2.2.2", diff --git a/cmk/base/legacy_checks/apc_rackpdu_power.py b/cmk/base/legacy_checks/apc_rackpdu_power.py index 89909250c1d..770f81b4d31 100644 --- a/cmk/base/legacy_checks/apc_rackpdu_power.py +++ b/cmk/base/legacy_checks/apc_rackpdu_power.py @@ -14,6 +14,7 @@ def discover_apc_rackpdu_power(section): check_info["apc_rackpdu_power"] = LegacyCheckDefinition( + name="apc_rackpdu_power", service_name="PDU %s", discovery_function=discover_apc_rackpdu_power, check_function=check_elphase, diff --git a/cmk/base/legacy_checks/apc_sts_inputs.py b/cmk/base/legacy_checks/apc_sts_inputs.py index 3cefef0b1c6..7dd63f8566d 100644 --- a/cmk/base/legacy_checks/apc_sts_inputs.py +++ b/cmk/base/legacy_checks/apc_sts_inputs.py @@ -54,6 +54,7 @@ def discover_apc_sts_inputs(section): check_info["apc_sts_inputs"] = LegacyCheckDefinition( + name="apc_sts_inputs", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.705.2.2"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/apc_symmetra.py b/cmk/base/legacy_checks/apc_symmetra.py index 51ed98abc35..58f9df3487f 100644 --- a/cmk/base/legacy_checks/apc_symmetra.py +++ b/cmk/base/legacy_checks/apc_symmetra.py @@ -284,6 +284,7 @@ def check_apc_symmetra(_no_item, params, parsed): # pylint: disable=too-many-br check_info["apc_symmetra"] = LegacyCheckDefinition( + name="apc_symmetra", detect=DETECT, fetch=[ SNMPTree( @@ -352,6 +353,7 @@ def check_apc_symmetra_temp(item, params, parsed): check_info["apc_symmetra.temp"] = LegacyCheckDefinition( + name="apc_symmetra_temp", service_name="Temperature %s", sections=["apc_symmetra"], discovery_function=inventory_apc_symmetra_temp, @@ -386,6 +388,7 @@ def check_apc_symmetra_elphase(item, params, parsed): check_info["apc_symmetra.elphase"] = LegacyCheckDefinition( + name="apc_symmetra_elphase", service_name="Phase %s", sections=["apc_symmetra"], discovery_function=inventory_apc_symmetra_elphase, diff --git a/cmk/base/legacy_checks/apc_symmetra_ext_temp.py b/cmk/base/legacy_checks/apc_symmetra_ext_temp.py index 4fb0313d219..19f3922cc18 100644 --- a/cmk/base/legacy_checks/apc_symmetra_ext_temp.py +++ b/cmk/base/legacy_checks/apc_symmetra_ext_temp.py @@ -34,6 +34,7 @@ def parse_apc_symmetra_ext_temp(string_table: StringTable) -> StringTable: check_info["apc_symmetra_ext_temp"] = LegacyCheckDefinition( + name="apc_symmetra_ext_temp", parse_function=parse_apc_symmetra_ext_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/apc_symmetra_input.py b/cmk/base/legacy_checks/apc_symmetra_input.py index 232c9508b18..729f025bbf4 100644 --- a/cmk/base/legacy_checks/apc_symmetra_input.py +++ b/cmk/base/legacy_checks/apc_symmetra_input.py @@ -29,6 +29,7 @@ def discover_apc_symmetra_input(section): check_info["apc_symmetra_input"] = LegacyCheckDefinition( + name="apc_symmetra_input", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.318.1.1.1.3.2", diff --git a/cmk/base/legacy_checks/apc_symmetra_output.py b/cmk/base/legacy_checks/apc_symmetra_output.py index 928751b261f..29b0522f318 100644 --- a/cmk/base/legacy_checks/apc_symmetra_output.py +++ b/cmk/base/legacy_checks/apc_symmetra_output.py @@ -39,6 +39,7 @@ def discover_apc_symmetra_output(section): check_info["apc_symmetra_output"] = LegacyCheckDefinition( + name="apc_symmetra_output", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.318.1.1.1.4.2", diff --git a/cmk/base/legacy_checks/apc_symmetra_test.py b/cmk/base/legacy_checks/apc_symmetra_test.py index 6feeff5aed6..45929ee7886 100644 --- a/cmk/base/legacy_checks/apc_symmetra_test.py +++ b/cmk/base/legacy_checks/apc_symmetra_test.py @@ -115,6 +115,7 @@ def parse_apc_symmetra_test(string_table: StringTable) -> StringTable: check_info["apc_symmetra_test"] = LegacyCheckDefinition( + name="apc_symmetra_test", parse_function=parse_apc_symmetra_test, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/appdynamics_memory.py b/cmk/base/legacy_checks/appdynamics_memory.py index 63958813c93..641dd32fcbe 100644 --- a/cmk/base/legacy_checks/appdynamics_memory.py +++ b/cmk/base/legacy_checks/appdynamics_memory.py @@ -111,6 +111,7 @@ def parse_appdynamics_memory(string_table: StringTable) -> StringTable: check_info["appdynamics_memory"] = LegacyCheckDefinition( + name="appdynamics_memory", parse_function=parse_appdynamics_memory, service_name="AppDynamics Memory %s", discovery_function=inventory_appdynamics_memory, diff --git a/cmk/base/legacy_checks/appdynamics_sessions.py b/cmk/base/legacy_checks/appdynamics_sessions.py index ca4e057b071..01f560c3226 100644 --- a/cmk/base/legacy_checks/appdynamics_sessions.py +++ b/cmk/base/legacy_checks/appdynamics_sessions.py @@ -61,6 +61,7 @@ def parse_appdynamics_sessions(string_table: StringTable) -> StringTable: check_info["appdynamics_sessions"] = LegacyCheckDefinition( + name="appdynamics_sessions", parse_function=parse_appdynamics_sessions, service_name="AppDynamics Sessions %s", discovery_function=inventory_appdynamics_sessions, diff --git a/cmk/base/legacy_checks/appdynamics_web_container.py b/cmk/base/legacy_checks/appdynamics_web_container.py index 25f18795828..2de4ee37e05 100644 --- a/cmk/base/legacy_checks/appdynamics_web_container.py +++ b/cmk/base/legacy_checks/appdynamics_web_container.py @@ -105,6 +105,7 @@ def check_appdynamics_web_container( check_info["appdynamics_web_container"] = LegacyCheckDefinition( + name="appdynamics_web_container", service_name="AppDynamics Web Container %s", parse_function=parse_appdynamics_web_container, discovery_function=discover_appdynamics_web_container, diff --git a/cmk/base/legacy_checks/arris_cmts_cpu.py b/cmk/base/legacy_checks/arris_cmts_cpu.py index 697d1d5d0a2..0eff2abc427 100644 --- a/cmk/base/legacy_checks/arris_cmts_cpu.py +++ b/cmk/base/legacy_checks/arris_cmts_cpu.py @@ -48,6 +48,7 @@ def parse_arris_cmts_cpu(string_table: StringTable) -> StringTable: check_info["arris_cmts_cpu"] = LegacyCheckDefinition( + name="arris_cmts_cpu", parse_function=parse_arris_cmts_cpu, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4998.2.1"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/arris_cmts_mem.py b/cmk/base/legacy_checks/arris_cmts_mem.py index bba712b79f2..68a4668fe8d 100644 --- a/cmk/base/legacy_checks/arris_cmts_mem.py +++ b/cmk/base/legacy_checks/arris_cmts_mem.py @@ -48,6 +48,7 @@ def check_arris_cmts_mem(item, params, parsed): check_info["arris_cmts_mem"] = LegacyCheckDefinition( + name="arris_cmts_mem", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4998.2.1"), fetch=SNMPTree( base=".1.3.6.1.4.1.4998.1.1.5.3.2.1.1", diff --git a/cmk/base/legacy_checks/arris_cmts_temp.py b/cmk/base/legacy_checks/arris_cmts_temp.py index 92def4eb76d..eb0070f42e5 100644 --- a/cmk/base/legacy_checks/arris_cmts_temp.py +++ b/cmk/base/legacy_checks/arris_cmts_temp.py @@ -31,6 +31,7 @@ def parse_arris_cmts_temp(string_table: StringTable) -> StringTable: check_info["arris_cmts_temp"] = LegacyCheckDefinition( + name="arris_cmts_temp", parse_function=parse_arris_cmts_temp, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4998.2.1"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/artec_temp.py b/cmk/base/legacy_checks/artec_temp.py index ff4f5889dd0..e274eea7e8f 100644 --- a/cmk/base/legacy_checks/artec_temp.py +++ b/cmk/base/legacy_checks/artec_temp.py @@ -28,6 +28,7 @@ def parse_artec_temp(string_table: StringTable) -> StringTable | None: check_info["artec_temp"] = LegacyCheckDefinition( + name="artec_temp", parse_function=parse_artec_temp, detect=all_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"), diff --git a/cmk/base/legacy_checks/aruba_cpu_util.py b/cmk/base/legacy_checks/aruba_cpu_util.py index d9204b30464..8283be5453c 100644 --- a/cmk/base/legacy_checks/aruba_cpu_util.py +++ b/cmk/base/legacy_checks/aruba_cpu_util.py @@ -37,6 +37,7 @@ def discover_aruba_cpu_util(section): check_info["aruba_cpu_util"] = LegacyCheckDefinition( + name="aruba_cpu_util", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.14823"), fetch=SNMPTree( base=".1.3.6.1.4.1.14823.2.2.1.1.1.9.1", diff --git a/cmk/base/legacy_checks/atto_fibrebridge_chassis.py b/cmk/base/legacy_checks/atto_fibrebridge_chassis.py index b264d34f309..e6e2b4efeeb 100644 --- a/cmk/base/legacy_checks/atto_fibrebridge_chassis.py +++ b/cmk/base/legacy_checks/atto_fibrebridge_chassis.py @@ -54,6 +54,7 @@ def check_atto_fibrebridge_chassis_temp(item, params, parsed): check_info["atto_fibrebridge_chassis.temp"] = LegacyCheckDefinition( + name="atto_fibrebridge_chassis_temp", service_name="Temperature %s", sections=["atto_fibrebridge_chassis"], discovery_function=inventory_atto_fibrebridge_chassis_temp, @@ -86,6 +87,7 @@ def check_atto_fibrebridge_chassis(_no_item, _no_params, parsed): check_info["atto_fibrebridge_chassis"] = LegacyCheckDefinition( + name="atto_fibrebridge_chassis", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4547"), fetch=SNMPTree( base=".1.3.6.1.4.1.4547.2.3.2", diff --git a/cmk/base/legacy_checks/atto_fibrebridge_fcport.py b/cmk/base/legacy_checks/atto_fibrebridge_fcport.py index e54085fd16a..ca04d503e13 100644 --- a/cmk/base/legacy_checks/atto_fibrebridge_fcport.py +++ b/cmk/base/legacy_checks/atto_fibrebridge_fcport.py @@ -40,6 +40,7 @@ def parse_atto_fibrebridge_fcport(string_table: StringTable) -> StringTable: check_info["atto_fibrebridge_fcport"] = LegacyCheckDefinition( + name="atto_fibrebridge_fcport", parse_function=parse_atto_fibrebridge_fcport, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4547"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/avaya_45xx_cpu.py b/cmk/base/legacy_checks/avaya_45xx_cpu.py index 96d4a425036..00025b31ce9 100644 --- a/cmk/base/legacy_checks/avaya_45xx_cpu.py +++ b/cmk/base/legacy_checks/avaya_45xx_cpu.py @@ -31,6 +31,7 @@ def parse_avaya_45xx_cpu(string_table: StringTable) -> StringTable: check_info["avaya_45xx_cpu"] = LegacyCheckDefinition( + name="avaya_45xx_cpu", parse_function=parse_avaya_45xx_cpu, detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.45.3"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/avaya_45xx_temp.py b/cmk/base/legacy_checks/avaya_45xx_temp.py index e7e3322fdf3..ac83f08ba11 100644 --- a/cmk/base/legacy_checks/avaya_45xx_temp.py +++ b/cmk/base/legacy_checks/avaya_45xx_temp.py @@ -28,6 +28,7 @@ def parse_avaya_45xx_temp(string_table: StringTable) -> StringTable: check_info["avaya_45xx_temp"] = LegacyCheckDefinition( + name="avaya_45xx_temp", parse_function=parse_avaya_45xx_temp, detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.45.3"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/avaya_88xx.py b/cmk/base/legacy_checks/avaya_88xx.py index ec574a72941..caaa449e5d5 100644 --- a/cmk/base/legacy_checks/avaya_88xx.py +++ b/cmk/base/legacy_checks/avaya_88xx.py @@ -63,6 +63,7 @@ def check_avaya_88xx(item, params, parsed): check_info["avaya_88xx"] = LegacyCheckDefinition( + name="avaya_88xx", detect=DETECT_AVAYA, # RAPID-CITY MIB, fetch=SNMPTree( @@ -80,6 +81,7 @@ def check_avaya_88xx(item, params, parsed): ) check_info["avaya_88xx.fan"] = LegacyCheckDefinition( + name="avaya_88xx_fan", service_name="Fan %s Status", sections=["avaya_88xx"], discovery_function=inventory_avaya_88xx_fan, diff --git a/cmk/base/legacy_checks/avaya_88xx_cpu.py b/cmk/base/legacy_checks/avaya_88xx_cpu.py index fb4e05215f4..d43249c8a68 100644 --- a/cmk/base/legacy_checks/avaya_88xx_cpu.py +++ b/cmk/base/legacy_checks/avaya_88xx_cpu.py @@ -29,6 +29,7 @@ def parse_avaya_88xx_cpu(string_table: StringTable) -> StringTable | None: check_info["avaya_88xx_cpu"] = LegacyCheckDefinition( + name="avaya_88xx_cpu", parse_function=parse_avaya_88xx_cpu, detect=DETECT_AVAYA, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/avaya_chassis_temp.py b/cmk/base/legacy_checks/avaya_chassis_temp.py index d33917d0f27..e76b9b104c9 100644 --- a/cmk/base/legacy_checks/avaya_chassis_temp.py +++ b/cmk/base/legacy_checks/avaya_chassis_temp.py @@ -27,6 +27,7 @@ def parse_avaya_chassis_temp(string_table: StringTable) -> StringTable: check_info["avaya_chassis_temp"] = LegacyCheckDefinition( + name="avaya_chassis_temp", parse_function=parse_avaya_chassis_temp, detect=DETECT_AVAYA, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/aws_cloudwatch_alarms_limits.py b/cmk/base/legacy_checks/aws_cloudwatch_alarms_limits.py index ad56591fe7d..ebe6f9d70d8 100644 --- a/cmk/base/legacy_checks/aws_cloudwatch_alarms_limits.py +++ b/cmk/base/legacy_checks/aws_cloudwatch_alarms_limits.py @@ -20,6 +20,7 @@ def discover_aws_cloudwatch_alarms_limits(section): check_info["aws_cloudwatch_alarms_limits"] = LegacyCheckDefinition( + name="aws_cloudwatch_alarms_limits", parse_function=parse_aws_limits_generic, service_name="AWS/CloudWatch Alarms Limits %s", discovery_function=discover_aws_cloudwatch_alarms_limits, diff --git a/cmk/base/legacy_checks/aws_costs_and_usage.py b/cmk/base/legacy_checks/aws_costs_and_usage.py index e2056b7217c..67eaf84b9fd 100644 --- a/cmk/base/legacy_checks/aws_costs_and_usage.py +++ b/cmk/base/legacy_checks/aws_costs_and_usage.py @@ -73,6 +73,7 @@ def check_aws_costs_and_usage_summary(item, params, parsed): check_info["aws_costs_and_usage"] = LegacyCheckDefinition( + name="aws_costs_and_usage", parse_function=parse_aws_costs_and_usage, service_name="AWS/CE %s", discovery_function=inventory_aws_costs_and_usage_summary, @@ -117,6 +118,7 @@ def check_aws_costs_and_usage_per_service(item, params, parsed): check_info["aws_costs_and_usage.per_service"] = LegacyCheckDefinition( + name="aws_costs_and_usage_per_service", service_name="AWS/CE %s", sections=["aws_costs_and_usage"], discovery_function=inventory_aws_costs_and_usage_per_service, diff --git a/cmk/base/legacy_checks/aws_dynamodb_limits.py b/cmk/base/legacy_checks/aws_dynamodb_limits.py index 6ac5b3e903e..1f16aeb7ae6 100644 --- a/cmk/base/legacy_checks/aws_dynamodb_limits.py +++ b/cmk/base/legacy_checks/aws_dynamodb_limits.py @@ -20,6 +20,7 @@ def discover_aws_dynamodb_limits(section): check_info["aws_dynamodb_limits"] = LegacyCheckDefinition( + name="aws_dynamodb_limits", parse_function=parse_aws_limits_generic, service_name="AWS/DynamoDB Limits %s", discovery_function=discover_aws_dynamodb_limits, diff --git a/cmk/base/legacy_checks/aws_dynamodb_summary.py b/cmk/base/legacy_checks/aws_dynamodb_summary.py index 45f45fdbb71..aff1fb831d8 100644 --- a/cmk/base/legacy_checks/aws_dynamodb_summary.py +++ b/cmk/base/legacy_checks/aws_dynamodb_summary.py @@ -54,6 +54,7 @@ def check_aws_dynamodb_summary(item, params, parsed): check_info["aws_dynamodb_summary"] = LegacyCheckDefinition( + name="aws_dynamodb_summary", parse_function=parse_aws, service_name="AWS/DynamoDB Summary", discovery_function=discover_aws_dynamodb_summary, diff --git a/cmk/base/legacy_checks/aws_dynamodb_table.py b/cmk/base/legacy_checks/aws_dynamodb_table.py index 1e5f0291acd..995e8be65bb 100644 --- a/cmk/base/legacy_checks/aws_dynamodb_table.py +++ b/cmk/base/legacy_checks/aws_dynamodb_table.py @@ -46,6 +46,7 @@ def parse_aws_dynamodb_table(string_table): check_info["aws_dynamodb_table"] = LegacyCheckDefinition( + name="aws_dynamodb_table", parse_function=parse_aws_dynamodb_table, ) @@ -176,6 +177,7 @@ def discover_aws_dynamodb_table_read_capacity(p): check_info["aws_dynamodb_table.read_capacity"] = LegacyCheckDefinition( + name="aws_dynamodb_table_read_capacity", service_name="AWS/DynamoDB Read Capacity", sections=["aws_dynamodb_table"], discovery_function=discover_aws_dynamodb_table_read_capacity, @@ -201,6 +203,7 @@ def discover_aws_dynamodb_table_write_capacity(p): check_info["aws_dynamodb_table.write_capacity"] = LegacyCheckDefinition( + name="aws_dynamodb_table_write_capacity", service_name="AWS/DynamoDB Write Capacity", sections=["aws_dynamodb_table"], discovery_function=discover_aws_dynamodb_table_write_capacity, @@ -221,6 +224,7 @@ def discover_aws_dynamodb_table_write_capacity(p): ) check_info["aws_dynamodb_table.latency"] = LegacyCheckDefinition( + name="aws_dynamodb_table_latency", service_name="AWS/DynamoDB Latency", sections=["aws_dynamodb_table"], discovery_function=inventory_aws_dynamodb_latency, diff --git a/cmk/base/legacy_checks/aws_ebs_summary.py b/cmk/base/legacy_checks/aws_ebs_summary.py index a1546c713c1..b7e999f5c78 100644 --- a/cmk/base/legacy_checks/aws_ebs_summary.py +++ b/cmk/base/legacy_checks/aws_ebs_summary.py @@ -74,6 +74,7 @@ def check_aws_ebs_summary(item, params, parsed): check_info["aws_ebs_summary"] = LegacyCheckDefinition( + name="aws_ebs_summary", parse_function=parse_aws_summary, service_name="AWS/EBS Summary", discovery_function=discover_aws_ebs_summary, @@ -106,6 +107,7 @@ def discover_aws_ebs_summary_health(p): check_info["aws_ebs_summary.health"] = LegacyCheckDefinition( + name="aws_ebs_summary_health", service_name="AWS/EBS Health %s", sections=["aws_ebs_summary"], discovery_function=discover_aws_ebs_summary_health, diff --git a/cmk/base/legacy_checks/aws_ec2_limits.py b/cmk/base/legacy_checks/aws_ec2_limits.py index df49b1b60a6..0a092debdc0 100644 --- a/cmk/base/legacy_checks/aws_ec2_limits.py +++ b/cmk/base/legacy_checks/aws_ec2_limits.py @@ -50,6 +50,7 @@ def discover_aws_ec2_limits(section): check_info["aws_ec2_limits"] = LegacyCheckDefinition( + name="aws_ec2_limits", parse_function=parse_aws_limits_generic, service_name="AWS/EC2 Limits %s", discovery_function=discover_aws_ec2_limits, diff --git a/cmk/base/legacy_checks/aws_ec2_security_groups.py b/cmk/base/legacy_checks/aws_ec2_security_groups.py index 0bfaedc7cee..a282880bba0 100644 --- a/cmk/base/legacy_checks/aws_ec2_security_groups.py +++ b/cmk/base/legacy_checks/aws_ec2_security_groups.py @@ -30,6 +30,7 @@ def check_aws_ec2_security_groups(item, params, parsed): check_info["aws_ec2_security_groups"] = LegacyCheckDefinition( + name="aws_ec2_security_groups", parse_function=parse_aws, service_name="AWS/EC2 Security Groups", discovery_function=inventory_aws_ec2_security_groups, diff --git a/cmk/base/legacy_checks/aws_elb.py b/cmk/base/legacy_checks/aws_elb.py index e4caf0943d6..75b33773a4d 100644 --- a/cmk/base/legacy_checks/aws_elb.py +++ b/cmk/base/legacy_checks/aws_elb.py @@ -93,6 +93,7 @@ def discover_aws_elb(p): check_info["aws_elb"] = LegacyCheckDefinition( + name="aws_elb", parse_function=parse_aws_elb, service_name="AWS/ELB Statistics", discovery_function=discover_aws_elb, @@ -133,6 +134,7 @@ def discover_aws_elb_latency(p): check_info["aws_elb.latency"] = LegacyCheckDefinition( + name="aws_elb_latency", service_name="AWS/ELB Latency", sections=["aws_elb"], discovery_function=discover_aws_elb_latency, @@ -165,6 +167,7 @@ def discover_aws_elb_http_elb(p): check_info["aws_elb.http_elb"] = LegacyCheckDefinition( + name="aws_elb_http_elb", service_name="AWS/ELB HTTP ELB", sections=["aws_elb"], discovery_function=discover_aws_elb_http_elb, @@ -197,6 +200,7 @@ def discover_aws_elb_http_backend(p): check_info["aws_elb.http_backend"] = LegacyCheckDefinition( + name="aws_elb_http_backend", service_name="AWS/ELB HTTP Backend", sections=["aws_elb"], discovery_function=discover_aws_elb_http_backend, @@ -263,6 +267,7 @@ def discover_aws_elb_healthy_hosts(p): check_info["aws_elb.healthy_hosts"] = LegacyCheckDefinition( + name="aws_elb_healthy_hosts", service_name="AWS/ELB Healthy Hosts", sections=["aws_elb"], discovery_function=discover_aws_elb_healthy_hosts, @@ -306,6 +311,7 @@ def discover_aws_elb_backend_connection_errors(p): check_info["aws_elb.backend_connection_errors"] = LegacyCheckDefinition( + name="aws_elb_backend_connection_errors", service_name="AWS/ELB Backend Connection Errors", sections=["aws_elb"], discovery_function=discover_aws_elb_backend_connection_errors, diff --git a/cmk/base/legacy_checks/aws_elb_health.py b/cmk/base/legacy_checks/aws_elb_health.py index 4dcad3c6377..eb488ec4184 100644 --- a/cmk/base/legacy_checks/aws_elb_health.py +++ b/cmk/base/legacy_checks/aws_elb_health.py @@ -48,6 +48,7 @@ def check_aws_elb_health(item, params, parsed): check_info["aws_elb_health"] = LegacyCheckDefinition( + name="aws_elb_health", parse_function=parse_aws_elb_health, service_name="AWS/ELB Health ", discovery_function=discover_aws_elb_health, diff --git a/cmk/base/legacy_checks/aws_elb_limits.py b/cmk/base/legacy_checks/aws_elb_limits.py index 5bb47d39d33..563cf733a64 100644 --- a/cmk/base/legacy_checks/aws_elb_limits.py +++ b/cmk/base/legacy_checks/aws_elb_limits.py @@ -20,6 +20,7 @@ def discover_aws_elb_limits(section): check_info["aws_elb_limits"] = LegacyCheckDefinition( + name="aws_elb_limits", parse_function=parse_aws_limits_generic, service_name="AWS/ELB Limits %s", discovery_function=discover_aws_elb_limits, diff --git a/cmk/base/legacy_checks/aws_elb_summary.py b/cmk/base/legacy_checks/aws_elb_summary.py index 3d8cd7ac2ef..d1980a7d19c 100644 --- a/cmk/base/legacy_checks/aws_elb_summary.py +++ b/cmk/base/legacy_checks/aws_elb_summary.py @@ -18,6 +18,7 @@ def discover_aws_elb_summary(section: GenericAWSSection) -> Iterable[tuple[None, check_info["aws_elb_summary"] = LegacyCheckDefinition( + name="aws_elb_summary", parse_function=parse_aws, service_name="AWS/ELB Summary", discovery_function=discover_aws_elb_summary, diff --git a/cmk/base/legacy_checks/aws_elbv2_application.py b/cmk/base/legacy_checks/aws_elbv2_application.py index 580efdfa6fe..9ce1c62676c 100644 --- a/cmk/base/legacy_checks/aws_elbv2_application.py +++ b/cmk/base/legacy_checks/aws_elbv2_application.py @@ -81,6 +81,7 @@ def discover_aws_elbv2_application(p): check_info["aws_elbv2_application"] = LegacyCheckDefinition( + name="aws_elbv2_application", parse_function=parse_aws_elbv2_application, service_name="AWS/ApplicationELB LCUs", discovery_function=discover_aws_elbv2_application, @@ -140,6 +141,7 @@ def discover_aws_elbv2_application_connections(p): check_info["aws_elbv2_application.connections"] = LegacyCheckDefinition( + name="aws_elbv2_application_connections", service_name="AWS/ApplicationELB Connections", sections=["aws_elbv2_application"], discovery_function=discover_aws_elbv2_application_connections, @@ -171,6 +173,7 @@ def discover_aws_elbv2_application_http_elb(p): check_info["aws_elbv2_application.http_elb"] = LegacyCheckDefinition( + name="aws_elbv2_application_http_elb", service_name="AWS/ApplicationELB HTTP ELB", sections=["aws_elbv2_application"], discovery_function=discover_aws_elbv2_application_http_elb, @@ -223,6 +226,7 @@ def discover_aws_elbv2_application_http_redirects(p): check_info["aws_elbv2_application.http_redirects"] = LegacyCheckDefinition( + name="aws_elbv2_application_http_redirects", service_name="AWS/ApplicationELB HTTP Redirects", sections=["aws_elbv2_application"], discovery_function=discover_aws_elbv2_application_http_redirects, @@ -283,6 +287,7 @@ def discover_aws_elbv2_application_statistics(p): check_info["aws_elbv2_application.statistics"] = LegacyCheckDefinition( + name="aws_elbv2_application_statistics", service_name="AWS/ApplicationELB Statistics", sections=["aws_elbv2_application"], discovery_function=discover_aws_elbv2_application_statistics, diff --git a/cmk/base/legacy_checks/aws_elbv2_application_target_groups_http.py b/cmk/base/legacy_checks/aws_elbv2_application_target_groups_http.py index 4e453dc4a25..77b1830ba33 100644 --- a/cmk/base/legacy_checks/aws_elbv2_application_target_groups_http.py +++ b/cmk/base/legacy_checks/aws_elbv2_application_target_groups_http.py @@ -40,6 +40,7 @@ def check_aws_application_elb_target_groups_http(item, params, section): check_info["aws_elbv2_application_target_groups_http"] = LegacyCheckDefinition( + name="aws_elbv2_application_target_groups_http", parse_function=parse_aws_elbv2_target_groups_http, service_name="AWS/ApplicationELB HTTP %s", discovery_function=discover_aws_application_elb_target_groups_http, diff --git a/cmk/base/legacy_checks/aws_elbv2_application_target_groups_lambda.py b/cmk/base/legacy_checks/aws_elbv2_application_target_groups_lambda.py index 8d606f9790b..69428f7fd1c 100644 --- a/cmk/base/legacy_checks/aws_elbv2_application_target_groups_lambda.py +++ b/cmk/base/legacy_checks/aws_elbv2_application_target_groups_lambda.py @@ -50,6 +50,7 @@ def check_aws_application_elb_target_groups_lambda(item, params, section): check_info["aws_elbv2_application_target_groups_lambda"] = LegacyCheckDefinition( + name="aws_elbv2_application_target_groups_lambda", parse_function=parse_aws_elbv2_target_groups_lambda, service_name="AWS/ApplicationELB Lambda %s", discovery_function=discover_aws_elbv2_target_groups_lambda, diff --git a/cmk/base/legacy_checks/aws_elbv2_limits.py b/cmk/base/legacy_checks/aws_elbv2_limits.py index f4ab66d8455..b88a422577c 100644 --- a/cmk/base/legacy_checks/aws_elbv2_limits.py +++ b/cmk/base/legacy_checks/aws_elbv2_limits.py @@ -20,6 +20,7 @@ def discover_aws_elbv2_limits(section): check_info["aws_elbv2_limits"] = LegacyCheckDefinition( + name="aws_elbv2_limits", parse_function=parse_aws_limits_generic, service_name="AWS/ELBv2 Limits %s", discovery_function=discover_aws_elbv2_limits, diff --git a/cmk/base/legacy_checks/aws_elbv2_network.py b/cmk/base/legacy_checks/aws_elbv2_network.py index f49846edf00..f7e3b03becf 100644 --- a/cmk/base/legacy_checks/aws_elbv2_network.py +++ b/cmk/base/legacy_checks/aws_elbv2_network.py @@ -74,6 +74,7 @@ def discover_aws_elbv2_network(p): check_info["aws_elbv2_network"] = LegacyCheckDefinition( + name="aws_elbv2_network", parse_function=parse_aws_elbv2_network, service_name="AWS/NetworkELB LCUs", discovery_function=discover_aws_elbv2_network, @@ -126,6 +127,7 @@ def discover_aws_elbv2_network_connections(p): check_info["aws_elbv2_network.connections"] = LegacyCheckDefinition( + name="aws_elbv2_network_connections", service_name="AWS/NetworkELB Connections", sections=["aws_elbv2_network"], discovery_function=discover_aws_elbv2_network_connections, @@ -229,6 +231,7 @@ def discover_aws_elbv2_network_tls_handshakes(p): check_info["aws_elbv2_network.tls_handshakes"] = LegacyCheckDefinition( + name="aws_elbv2_network_tls_handshakes", service_name="AWS/NetworkELB TLS Handshakes", sections=["aws_elbv2_network"], discovery_function=discover_aws_elbv2_network_tls_handshakes, @@ -278,6 +281,7 @@ def discover_aws_elbv2_network_rst_packets(p): check_info["aws_elbv2_network.rst_packets"] = LegacyCheckDefinition( + name="aws_elbv2_network_rst_packets", service_name="AWS/NetworkELB Reset Packets", sections=["aws_elbv2_network"], discovery_function=discover_aws_elbv2_network_rst_packets, @@ -327,6 +331,7 @@ def discover_aws_elbv2_network_statistics(p): check_info["aws_elbv2_network.statistics"] = LegacyCheckDefinition( + name="aws_elbv2_network_statistics", service_name="AWS/NetworkELB Statistics", sections=["aws_elbv2_network"], discovery_function=discover_aws_elbv2_network_statistics, diff --git a/cmk/base/legacy_checks/aws_elbv2_summary.py b/cmk/base/legacy_checks/aws_elbv2_summary.py index 7aaa4cabb86..00d42da46d5 100644 --- a/cmk/base/legacy_checks/aws_elbv2_summary.py +++ b/cmk/base/legacy_checks/aws_elbv2_summary.py @@ -33,6 +33,7 @@ def check_aws_elbv2_summary_application(item, params, parsed): check_info["aws_elbv2_summary"] = LegacyCheckDefinition( + name="aws_elbv2_summary", parse_function=parse_aws_elbv2_summary, service_name="AWS/ApplicationELB Summary", discovery_function=inventory_aws_elbv2_summary_application, @@ -53,6 +54,7 @@ def check_aws_elbv2_summary_network(item, params, parsed): check_info["aws_elbv2_summary.network"] = LegacyCheckDefinition( + name="aws_elbv2_summary_network", service_name="AWS/NetworkELB Summary", sections=["aws_elbv2_summary"], discovery_function=inventory_aws_elbv2_summary_network, diff --git a/cmk/base/legacy_checks/aws_elbv2_target_groups.py b/cmk/base/legacy_checks/aws_elbv2_target_groups.py index 249180bed76..0fc8e14199b 100644 --- a/cmk/base/legacy_checks/aws_elbv2_target_groups.py +++ b/cmk/base/legacy_checks/aws_elbv2_target_groups.py @@ -89,6 +89,7 @@ def check_aws_application_elb_target_groups(item, params, parsed): check_info["aws_elbv2_target_groups"] = LegacyCheckDefinition( + name="aws_elbv2_target_groups", parse_function=parse_aws_elbv2_target_groups, service_name="AWS/ApplicationELB Target Groups", discovery_function=inventory_aws_application_elb_target_groups, @@ -109,6 +110,7 @@ def check_aws_network_elb_target_groups(item, params, parsed): check_info["aws_elbv2_target_groups.network"] = LegacyCheckDefinition( + name="aws_elbv2_target_groups_network", service_name="AWS/NetworkELB Target Groups", sections=["aws_elbv2_target_groups"], discovery_function=inventory_aws_network_elb_target_groups, diff --git a/cmk/base/legacy_checks/aws_glacier.py b/cmk/base/legacy_checks/aws_glacier.py index a225349c981..04e77ec3761 100644 --- a/cmk/base/legacy_checks/aws_glacier.py +++ b/cmk/base/legacy_checks/aws_glacier.py @@ -71,6 +71,7 @@ def check_aws_glacier_archives(item, params, parsed): check_info["aws_glacier"] = LegacyCheckDefinition( + name="aws_glacier", parse_function=parse_aws_glacier, service_name="AWS/Glacier Vault: %s", discovery_function=inventory_aws_glacier, @@ -128,6 +129,7 @@ def check_aws_glacier_summary(item, params, parsed): check_info["aws_glacier.summary"] = LegacyCheckDefinition( + name="aws_glacier_summary", service_name="AWS/Glacier Summary", sections=["aws_glacier"], discovery_function=discover_aws_glacier_summary, diff --git a/cmk/base/legacy_checks/aws_glacier_limits.py b/cmk/base/legacy_checks/aws_glacier_limits.py index 83a77095ae5..91291b87874 100644 --- a/cmk/base/legacy_checks/aws_glacier_limits.py +++ b/cmk/base/legacy_checks/aws_glacier_limits.py @@ -30,6 +30,7 @@ def discover_aws_glacier_limits(section): check_info["aws_glacier_limits"] = LegacyCheckDefinition( + name="aws_glacier_limits", parse_function=parse_aws_limits_generic, service_name="AWS/Glacier Limits %s", discovery_function=discover_aws_glacier_limits, diff --git a/cmk/base/legacy_checks/aws_rds_limits.py b/cmk/base/legacy_checks/aws_rds_limits.py index 0dfd3ea4a24..4cc81ad4b8a 100644 --- a/cmk/base/legacy_checks/aws_rds_limits.py +++ b/cmk/base/legacy_checks/aws_rds_limits.py @@ -43,6 +43,7 @@ def discover_aws_rds_limits(section): check_info["aws_rds_limits"] = LegacyCheckDefinition( + name="aws_rds_limits", parse_function=parse_aws_rds_limits, service_name="AWS/RDS Limits %s", discovery_function=discover_aws_rds_limits, diff --git a/cmk/base/legacy_checks/aws_rds_summary.py b/cmk/base/legacy_checks/aws_rds_summary.py index cf2d46d6528..0b063f28a83 100644 --- a/cmk/base/legacy_checks/aws_rds_summary.py +++ b/cmk/base/legacy_checks/aws_rds_summary.py @@ -54,6 +54,7 @@ def check_aws_rds_summary(item, params, parsed): check_info["aws_rds_summary"] = LegacyCheckDefinition( + name="aws_rds_summary", parse_function=parse_aws_rds_summary, service_name="AWS/RDS Summary", discovery_function=discover_aws_rds_summary, @@ -100,6 +101,7 @@ def discover_aws_rds_summary_db_status(p): check_info["aws_rds_summary.db_status"] = LegacyCheckDefinition( + name="aws_rds_summary_db_status", service_name="AWS/RDS %s Info", sections=["aws_rds_summary"], discovery_function=discover_aws_rds_summary_db_status, diff --git a/cmk/base/legacy_checks/aws_s3.py b/cmk/base/legacy_checks/aws_s3.py index 47d909ca1fa..328d43f46ff 100644 --- a/cmk/base/legacy_checks/aws_s3.py +++ b/cmk/base/legacy_checks/aws_s3.py @@ -87,6 +87,7 @@ def discover_aws_s3(p): check_info["aws_s3"] = LegacyCheckDefinition( + name="aws_s3", parse_function=parse_aws_s3, service_name="AWS/S3 Objects %s", discovery_function=discover_aws_s3, @@ -140,6 +141,7 @@ def check_aws_s3_summary(item, params, parsed): check_info["aws_s3.summary"] = LegacyCheckDefinition( + name="aws_s3_summary", service_name="AWS/S3 Summary", sections=["aws_s3"], discovery_function=discover_aws_s3_summary, diff --git a/cmk/base/legacy_checks/aws_s3_limits.py b/cmk/base/legacy_checks/aws_s3_limits.py index 585b506f72a..6d22112c9dd 100644 --- a/cmk/base/legacy_checks/aws_s3_limits.py +++ b/cmk/base/legacy_checks/aws_s3_limits.py @@ -20,6 +20,7 @@ def discover_aws_s3_limits(section): check_info["aws_s3_limits"] = LegacyCheckDefinition( + name="aws_s3_limits", parse_function=parse_aws_limits_generic, service_name="AWS/S3 Limits %s", discovery_function=discover_aws_s3_limits, diff --git a/cmk/base/legacy_checks/aws_s3_requests.py b/cmk/base/legacy_checks/aws_s3_requests.py index 406f679083e..8d373797963 100644 --- a/cmk/base/legacy_checks/aws_s3_requests.py +++ b/cmk/base/legacy_checks/aws_s3_requests.py @@ -97,6 +97,7 @@ def discover_aws_s3_requests(p): check_info["aws_s3_requests"] = LegacyCheckDefinition( + name="aws_s3_requests", parse_function=parse_aws_s3, service_name="AWS/S3 Requests %s", discovery_function=discover_aws_s3_requests, @@ -131,6 +132,7 @@ def discover_aws_s3_requests_http_errors(p): check_info["aws_s3_requests.http_errors"] = LegacyCheckDefinition( + name="aws_s3_requests_http_errors", service_name="AWS/S3 HTTP Errors %s", sections=["aws_s3_requests"], discovery_function=discover_aws_s3_requests_http_errors, @@ -185,6 +187,7 @@ def discover_aws_s3_requests_latency(p): check_info["aws_s3_requests.latency"] = LegacyCheckDefinition( + name="aws_s3_requests_latency", service_name="AWS/S3 Latency %s", sections=["aws_s3_requests"], discovery_function=discover_aws_s3_requests_latency, @@ -226,6 +229,7 @@ def discover_aws_s3_requests_traffic_stats(p): check_info["aws_s3_requests.traffic_stats"] = LegacyCheckDefinition( + name="aws_s3_requests_traffic_stats", service_name="AWS/S3 Traffic Stats %s", sections=["aws_s3_requests"], discovery_function=discover_aws_s3_requests_traffic_stats, @@ -266,6 +270,7 @@ def discover_aws_s3_requests_select_object(p): check_info["aws_s3_requests.select_object"] = LegacyCheckDefinition( + name="aws_s3_requests_select_object", service_name="AWS/S3 SELECT Object %s", sections=["aws_s3_requests"], discovery_function=discover_aws_s3_requests_select_object, diff --git a/cmk/base/legacy_checks/aws_wafv2_limits.py b/cmk/base/legacy_checks/aws_wafv2_limits.py index 36a717c91c3..83920219cd9 100644 --- a/cmk/base/legacy_checks/aws_wafv2_limits.py +++ b/cmk/base/legacy_checks/aws_wafv2_limits.py @@ -20,6 +20,7 @@ def discover_aws_wafv2_limits(section): check_info["aws_wafv2_limits"] = LegacyCheckDefinition( + name="aws_wafv2_limits", parse_function=parse_aws_limits_generic, service_name="AWS/WAFV2 Limits %s", discovery_function=discover_aws_wafv2_limits, diff --git a/cmk/base/legacy_checks/aws_wafv2_summary.py b/cmk/base/legacy_checks/aws_wafv2_summary.py index 23190421734..2177d09958b 100644 --- a/cmk/base/legacy_checks/aws_wafv2_summary.py +++ b/cmk/base/legacy_checks/aws_wafv2_summary.py @@ -58,6 +58,7 @@ def check_aws_wafv2_summary(item, params, parsed): check_info["aws_wafv2_summary"] = LegacyCheckDefinition( + name="aws_wafv2_summary", parse_function=parse_aws, service_name="AWS/WAFV2 Summary", discovery_function=discover_aws_wafv2_summary, diff --git a/cmk/base/legacy_checks/aws_wafv2_web_acl.py b/cmk/base/legacy_checks/aws_wafv2_web_acl.py index 64a61e3c597..79ffce0a52b 100644 --- a/cmk/base/legacy_checks/aws_wafv2_web_acl.py +++ b/cmk/base/legacy_checks/aws_wafv2_web_acl.py @@ -75,6 +75,7 @@ def discover_aws_wafv2_web_acl(p): check_info["aws_wafv2_web_acl"] = LegacyCheckDefinition( + name="aws_wafv2_web_acl", parse_function=parse_aws_wafv2_web_acl, service_name="AWS/WAFV2 Web ACL Requests", discovery_function=discover_aws_wafv2_web_acl, diff --git a/cmk/base/legacy_checks/azure_ad.py b/cmk/base/legacy_checks/azure_ad.py index e47c979e961..e65d40b4950 100644 --- a/cmk/base/legacy_checks/azure_ad.py +++ b/cmk/base/legacy_checks/azure_ad.py @@ -77,6 +77,7 @@ def check_azure_users(item, _no_params, parsed): check_info["azure_ad"] = LegacyCheckDefinition( + name="azure_ad", parse_function=parse_azure_ad, service_name="AD Users", discovery_function=discover_ad_users, @@ -132,6 +133,7 @@ def check_azure_sync(item, params, parsed): check_info["azure_ad.sync"] = LegacyCheckDefinition( + name="azure_ad_sync", service_name="AD Sync %s", sections=["azure_ad"], discovery_function=discover_sync, diff --git a/cmk/base/legacy_checks/azure_agent_info.py b/cmk/base/legacy_checks/azure_agent_info.py index 8ee333c7767..b87ad65140a 100644 --- a/cmk/base/legacy_checks/azure_agent_info.py +++ b/cmk/base/legacy_checks/azure_agent_info.py @@ -161,6 +161,7 @@ def check_azure_agent_info(_no_item, params, parsed): check_info["azure_agent_info"] = LegacyCheckDefinition( + name="azure_agent_info", parse_function=parse_azure_agent_info, service_name="Azure Agent Info", discovery_function=discovery_azure_agent_info, diff --git a/cmk/base/legacy_checks/azure_databases.py b/cmk/base/legacy_checks/azure_databases.py index 163664e2f0b..6e534ff9448 100644 --- a/cmk/base/legacy_checks/azure_databases.py +++ b/cmk/base/legacy_checks/azure_databases.py @@ -37,6 +37,7 @@ def check_azure_databases_storage(item, params, section): check_info["azure_databases.storage"] = LegacyCheckDefinition( + name="azure_databases_storage", service_name="DB %s Storage", sections=["azure_databases"], discovery_function=discover_azure_by_metrics("average_storage_percent"), @@ -60,6 +61,7 @@ def check_azure_databases_deadlock(item, params, section): check_info["azure_databases.deadlock"] = LegacyCheckDefinition( + name="azure_databases_deadlock", service_name="DB %s Deadlocks", sections=["azure_databases"], discovery_function=discover_azure_by_metrics("average_deadlock"), @@ -86,6 +88,7 @@ def check_azure_databases_cpu(item, params, section): check_info["azure_databases.cpu"] = LegacyCheckDefinition( + name="azure_databases_cpu", service_name="DB %s CPU", sections=["azure_databases"], discovery_function=discover_azure_by_metrics("average_cpu_percent"), @@ -115,6 +118,7 @@ def check_azure_databases_dtu(item, params, section): check_info["azure_databases.dtu"] = LegacyCheckDefinition( + name="azure_databases_dtu", service_name="DB %s DTU", sections=["azure_databases"], discovery_function=discover_azure_by_metrics("average_dtu_consumption_percent"), @@ -144,6 +148,7 @@ def check_azure_databases_connections(item, params, section): check_info["azure_databases.connections"] = LegacyCheckDefinition( + name="azure_databases_connections", service_name="DB %s Connections", sections=["azure_databases"], discovery_function=discover_azure_by_metrics( @@ -176,6 +181,7 @@ def discover_azure_databases(section): check_info["azure_databases"] = LegacyCheckDefinition( + name="azure_databases", parse_function=parse_resources, service_name="DB %s", discovery_function=discover_azure_databases, diff --git a/cmk/base/legacy_checks/azure_sites.py b/cmk/base/legacy_checks/azure_sites.py index b806683bd4d..46b016de666 100644 --- a/cmk/base/legacy_checks/azure_sites.py +++ b/cmk/base/legacy_checks/azure_sites.py @@ -43,6 +43,7 @@ def discover_azure_sites(section): check_info["azure_sites"] = LegacyCheckDefinition( + name="azure_sites", parse_function=parse_resources, service_name="Site %s", discovery_function=discover_azure_sites, diff --git a/cmk/base/legacy_checks/azure_storageaccounts.py b/cmk/base/legacy_checks/azure_storageaccounts.py index 37139a2b5bb..51727cb7b80 100644 --- a/cmk/base/legacy_checks/azure_storageaccounts.py +++ b/cmk/base/legacy_checks/azure_storageaccounts.py @@ -48,6 +48,7 @@ def discover_azure_storageaccounts(section): check_info["azure_storageaccounts"] = LegacyCheckDefinition( + name="azure_storageaccounts", parse_function=parse_resources, service_name="Storage %s account", discovery_function=discover_azure_storageaccounts, @@ -83,6 +84,7 @@ def check_azure_storageaccounts_flow(item, params, section): check_info["azure_storageaccounts.flow"] = LegacyCheckDefinition( + name="azure_storageaccounts_flow", service_name="Storage %s flow", sections=["azure_storageaccounts"], discovery_function=discover_azure_by_metrics( @@ -122,6 +124,7 @@ def check_azure_storageaccounts_performance(item, params, section): check_info["azure_storageaccounts.performance"] = LegacyCheckDefinition( + name="azure_storageaccounts_performance", service_name="Storage %s performance", sections=["azure_storageaccounts"], discovery_function=discover_azure_by_metrics( diff --git a/cmk/base/legacy_checks/azure_usagedetails.py b/cmk/base/legacy_checks/azure_usagedetails.py index beb47fc2a69..5147985c657 100644 --- a/cmk/base/legacy_checks/azure_usagedetails.py +++ b/cmk/base/legacy_checks/azure_usagedetails.py @@ -51,6 +51,7 @@ def discover_azure_usagedetails(section): check_info["azure_usagedetails"] = LegacyCheckDefinition( + name="azure_usagedetails", parse_function=parse_azure_usagedetails, service_name="Costs %s", discovery_function=discover_azure_usagedetails, diff --git a/cmk/base/legacy_checks/barracuda_mail_latency.py b/cmk/base/legacy_checks/barracuda_mail_latency.py index 8b8c5a28e42..0fe0b648b40 100644 --- a/cmk/base/legacy_checks/barracuda_mail_latency.py +++ b/cmk/base/legacy_checks/barracuda_mail_latency.py @@ -32,6 +32,7 @@ def parse_barracuda_mail_latency(string_table: StringTable) -> StringTable | Non check_info["barracuda_mail_latency"] = LegacyCheckDefinition( + name="barracuda_mail_latency", parse_function=parse_barracuda_mail_latency, detect=DETECT_BARRACUDA, # The barracuda spam firewall does not response or returns a timeout error diff --git a/cmk/base/legacy_checks/barracuda_mailqueues.py b/cmk/base/legacy_checks/barracuda_mailqueues.py index 98a3bab0967..a505043e81d 100644 --- a/cmk/base/legacy_checks/barracuda_mailqueues.py +++ b/cmk/base/legacy_checks/barracuda_mailqueues.py @@ -50,6 +50,7 @@ def parse_barracuda_mailqueues(string_table: StringTable) -> StringTable | None: check_info["barracuda_mailqueues"] = LegacyCheckDefinition( + name="barracuda_mailqueues", parse_function=parse_barracuda_mailqueues, detect=DETECT_BARRACUDA, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/barracuda_system_cpu_util.py b/cmk/base/legacy_checks/barracuda_system_cpu_util.py index 6b62f4778a9..477f1d85733 100644 --- a/cmk/base/legacy_checks/barracuda_system_cpu_util.py +++ b/cmk/base/legacy_checks/barracuda_system_cpu_util.py @@ -29,6 +29,7 @@ def parse_barracuda_system_cpu_util(string_table: StringTable) -> StringTable | check_info["barracuda_system_cpu_util"] = LegacyCheckDefinition( + name="barracuda_system_cpu_util", parse_function=parse_barracuda_system_cpu_util, detect=DETECT_BARRACUDA, # The barracuda spam firewall does not response or returns a timeout error diff --git a/cmk/base/legacy_checks/bintec_cpu.py b/cmk/base/legacy_checks/bintec_cpu.py index d47706d9712..f3207b919f0 100644 --- a/cmk/base/legacy_checks/bintec_cpu.py +++ b/cmk/base/legacy_checks/bintec_cpu.py @@ -45,6 +45,7 @@ def parse_bintec_cpu(string_table: StringTable) -> StringTable: check_info["bintec_cpu"] = LegacyCheckDefinition( + name="bintec_cpu", parse_function=parse_bintec_cpu, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.272.4."), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bintec_sensors.py b/cmk/base/legacy_checks/bintec_sensors.py index 1efbce9d8a9..7d6fd47dd10 100644 --- a/cmk/base/legacy_checks/bintec_sensors.py +++ b/cmk/base/legacy_checks/bintec_sensors.py @@ -19,6 +19,7 @@ def parse_bintec_sensors(string_table: StringTable) -> StringTable: check_info["bintec_sensors"] = LegacyCheckDefinition( + name="bintec_sensors", parse_function=parse_bintec_sensors, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.272.4"), fetch=SNMPTree( @@ -53,6 +54,7 @@ def check_bintec_sensors_fan(item, params, info): check_info["bintec_sensors.fan"] = LegacyCheckDefinition( + name="bintec_sensors_fan", service_name="%s", sections=["bintec_sensors"], discovery_function=inventory_bintec_sensors_fan, @@ -89,6 +91,7 @@ def check_bintec_sensors_temp(item, params, info): check_info["bintec_sensors.temp"] = LegacyCheckDefinition( + name="bintec_sensors_temp", service_name="Temperature %s", sections=["bintec_sensors"], discovery_function=inventory_bintec_sensors_temp, @@ -130,6 +133,7 @@ def check_bintec_sensors_voltage(item, _no_params, info): check_info["bintec_sensors.voltage"] = LegacyCheckDefinition( + name="bintec_sensors_voltage", service_name="Voltage %s", sections=["bintec_sensors"], discovery_function=inventory_bintec_sensors_voltage, diff --git a/cmk/base/legacy_checks/blade_bays.py b/cmk/base/legacy_checks/blade_bays.py index d2f3e420bcc..6a59988472f 100644 --- a/cmk/base/legacy_checks/blade_bays.py +++ b/cmk/base/legacy_checks/blade_bays.py @@ -74,6 +74,7 @@ def check_blade_bays(item, params, parsed): check_info["blade_bays"] = LegacyCheckDefinition( + name="blade_bays", detect=DETECT_BLADE, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/blade_bx_powerfan.py b/cmk/base/legacy_checks/blade_bx_powerfan.py index c601a79c91b..2aa01fa112f 100644 --- a/cmk/base/legacy_checks/blade_bx_powerfan.py +++ b/cmk/base/legacy_checks/blade_bx_powerfan.py @@ -85,6 +85,7 @@ def parse_blade_bx_powerfan(string_table: StringTable) -> StringTable: check_info["blade_bx_powerfan"] = LegacyCheckDefinition( + name="blade_bx_powerfan", parse_function=parse_blade_bx_powerfan, detect=DETECT_BLADE_BX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/blade_bx_temp.py b/cmk/base/legacy_checks/blade_bx_temp.py index 5a7f856491b..bf5d9c88cd9 100644 --- a/cmk/base/legacy_checks/blade_bx_temp.py +++ b/cmk/base/legacy_checks/blade_bx_temp.py @@ -68,6 +68,7 @@ def parse_blade_bx_temp(string_table: StringTable) -> StringTable: check_info["blade_bx_temp"] = LegacyCheckDefinition( + name="blade_bx_temp", parse_function=parse_blade_bx_temp, detect=DETECT_BLADE_BX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bluecat_command_server.py b/cmk/base/legacy_checks/bluecat_command_server.py index 1cda77b0dcd..39cc8a43a4f 100644 --- a/cmk/base/legacy_checks/bluecat_command_server.py +++ b/cmk/base/legacy_checks/bluecat_command_server.py @@ -37,6 +37,7 @@ def parse_bluecat_command_server(string_table: StringTable) -> StringTable | Non check_info["bluecat_command_server"] = LegacyCheckDefinition( + name="bluecat_command_server", parse_function=parse_bluecat_command_server, detect=DETECT_BLUECAT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bluecat_ha.py b/cmk/base/legacy_checks/bluecat_ha.py index fc9972b7db9..80326736e33 100644 --- a/cmk/base/legacy_checks/bluecat_ha.py +++ b/cmk/base/legacy_checks/bluecat_ha.py @@ -43,6 +43,7 @@ def parse_bluecat_ha(string_table: StringTable) -> StringTable: check_info["bluecat_ha"] = LegacyCheckDefinition( + name="bluecat_ha", parse_function=parse_bluecat_ha, detect=DETECT_BLUECAT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bluecat_ntp.py b/cmk/base/legacy_checks/bluecat_ntp.py index 1e7f3798ea4..1204de82c18 100644 --- a/cmk/base/legacy_checks/bluecat_ntp.py +++ b/cmk/base/legacy_checks/bluecat_ntp.py @@ -55,6 +55,7 @@ def parse_bluecat_ntp(string_table: StringTable) -> StringTable: check_info["bluecat_ntp"] = LegacyCheckDefinition( + name="bluecat_ntp", parse_function=parse_bluecat_ntp, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13315"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bluecat_threads.py b/cmk/base/legacy_checks/bluecat_threads.py index e21a8816ee6..a3e1e350376 100644 --- a/cmk/base/legacy_checks/bluecat_threads.py +++ b/cmk/base/legacy_checks/bluecat_threads.py @@ -37,6 +37,7 @@ def parse_bluecat_threads(string_table: StringTable) -> StringTable: check_info["bluecat_threads"] = LegacyCheckDefinition( + name="bluecat_threads", parse_function=parse_bluecat_threads, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13315.100.200"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bluenet_meter.py b/cmk/base/legacy_checks/bluenet_meter.py index 5126c8bf286..a948562d443 100644 --- a/cmk/base/legacy_checks/bluenet_meter.py +++ b/cmk/base/legacy_checks/bluenet_meter.py @@ -31,6 +31,7 @@ def discover_bluenet_meter(section): check_info["bluenet_meter"] = LegacyCheckDefinition( + name="bluenet_meter", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21695.1"), fetch=SNMPTree( base=".1.3.6.1.4.1.21695.1.10.7.2.1", diff --git a/cmk/base/legacy_checks/bluenet_sensor.py b/cmk/base/legacy_checks/bluenet_sensor.py index 2547afe211d..a02e7c463dc 100644 --- a/cmk/base/legacy_checks/bluenet_sensor.py +++ b/cmk/base/legacy_checks/bluenet_sensor.py @@ -51,6 +51,7 @@ def parse_bluenet_sensor(string_table: StringTable) -> StringTable: check_info["bluenet_sensor"] = LegacyCheckDefinition( + name="bluenet_sensor", parse_function=parse_bluenet_sensor, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21695.1"), fetch=SNMPTree( @@ -105,6 +106,7 @@ def check_bluenet_sensor_hum(item, params, info): check_info["bluenet_sensor.hum"] = LegacyCheckDefinition( + name="bluenet_sensor_hum", service_name="Humidity %s", sections=["bluenet_sensor"], discovery_function=inventory_bluenet_sensor_hum, diff --git a/cmk/base/legacy_checks/brocade.py b/cmk/base/legacy_checks/brocade.py index 336785615c5..5e4777d7b1d 100644 --- a/cmk/base/legacy_checks/brocade.py +++ b/cmk/base/legacy_checks/brocade.py @@ -40,6 +40,7 @@ def parse_brocade(string_table: StringTable) -> StringTable: check_info["brocade"] = LegacyCheckDefinition( + name="brocade", parse_function=parse_brocade, detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1588.2.1.1"), @@ -82,6 +83,7 @@ def check_brocade_fan(item, params, info): check_info["brocade.fan"] = LegacyCheckDefinition( + name="brocade_fan", service_name="FAN %s", sections=["brocade"], discovery_function=inventory_brocade_fan, @@ -109,6 +111,7 @@ def check_brocade_power(item, _no_params, info): check_info["brocade.power"] = LegacyCheckDefinition( + name="brocade_power", service_name="Power supply %s", sections=["brocade"], discovery_function=inventory_brocade_power, @@ -130,6 +133,7 @@ def check_brocade_temp(item, params, info): check_info["brocade.temp"] = LegacyCheckDefinition( + name="brocade_temp", service_name="Temperature Ambient %s", sections=["brocade"], discovery_function=inventory_brocade_temp, diff --git a/cmk/base/legacy_checks/brocade_mlx.py b/cmk/base/legacy_checks/brocade_mlx.py index 78fe891a5ac..32733ab26c7 100644 --- a/cmk/base/legacy_checks/brocade_mlx.py +++ b/cmk/base/legacy_checks/brocade_mlx.py @@ -35,6 +35,7 @@ def parse_brocade_mlx(string_table: Sequence[StringTable]) -> Sequence[StringTab check_info["brocade_mlx"] = LegacyCheckDefinition( + name="brocade_mlx", parse_function=parse_brocade_mlx, detect=DETECT_MLX, fetch=[ @@ -101,6 +102,7 @@ def check_brocade_mlx_module(item, _no_params, info): check_info["brocade_mlx.module_status"] = LegacyCheckDefinition( + name="brocade_mlx_module_status", service_name="Status Module %s", sections=["brocade_mlx"], discovery_function=inventory_brocade_mlx_module, @@ -185,6 +187,7 @@ def check_brocade_mlx_module_mem(item, params, info): check_info["brocade_mlx.module_mem"] = LegacyCheckDefinition( + name="brocade_mlx_module_mem", service_name="Memory Module %s", sections=["brocade_mlx"], discovery_function=inventory_brocade_mlx_module_mem, @@ -264,6 +267,7 @@ def check_brocade_mlx_module_cpu(item, params, info): check_info["brocade_mlx.module_cpu"] = LegacyCheckDefinition( + name="brocade_mlx_module_cpu", service_name="CPU utilization Module %s", sections=["brocade_mlx"], discovery_function=inventory_brocade_mlx_module_cpu, diff --git a/cmk/base/legacy_checks/brocade_mlx_temp.py b/cmk/base/legacy_checks/brocade_mlx_temp.py index 2d7091620fb..c02ab465fc5 100644 --- a/cmk/base/legacy_checks/brocade_mlx_temp.py +++ b/cmk/base/legacy_checks/brocade_mlx_temp.py @@ -43,6 +43,7 @@ def check_brocade_mlx_temp(item, params, parsed): check_info["brocade_mlx_temp"] = LegacyCheckDefinition( + name="brocade_mlx_temp", detect=DETECT_MLX, fetch=SNMPTree( base=".1.3.6.1.4.1.1991.1.1.2.13.1.1", diff --git a/cmk/base/legacy_checks/brocade_sys.py b/cmk/base/legacy_checks/brocade_sys.py index 41221b31ea1..33413469b35 100644 --- a/cmk/base/legacy_checks/brocade_sys.py +++ b/cmk/base/legacy_checks/brocade_sys.py @@ -47,6 +47,7 @@ def check_brocade_sys_mem(item, params, parsed): check_info["brocade_sys.mem"] = LegacyCheckDefinition( + name="brocade_sys_mem", service_name="Memory", sections=["brocade_sys"], discovery_function=inventory_brocade_sys_mem, @@ -75,6 +76,7 @@ def check_brocade_sys(item, params, parsed): check_info["brocade_sys"] = LegacyCheckDefinition( + name="brocade_sys", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1588.2.1.1"), equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1916.2.306"), diff --git a/cmk/base/legacy_checks/brocade_tm.py b/cmk/base/legacy_checks/brocade_tm.py index f764ba569c9..129c3ffa831 100644 --- a/cmk/base/legacy_checks/brocade_tm.py +++ b/cmk/base/legacy_checks/brocade_tm.py @@ -78,6 +78,7 @@ def parse_brocade_tm(string_table: StringTable) -> StringTable: check_info["brocade_tm"] = LegacyCheckDefinition( + name="brocade_tm", parse_function=parse_brocade_tm, detect=DETECT_MLX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bvip_fans.py b/cmk/base/legacy_checks/bvip_fans.py index 141e38aee1a..ed344f63aee 100644 --- a/cmk/base/legacy_checks/bvip_fans.py +++ b/cmk/base/legacy_checks/bvip_fans.py @@ -32,6 +32,7 @@ def parse_bvip_fans(string_table: StringTable) -> StringTable: check_info["bvip_fans"] = LegacyCheckDefinition( + name="bvip_fans", parse_function=parse_bvip_fans, detect=DETECT_BVIP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bvip_link.py b/cmk/base/legacy_checks/bvip_link.py index 32b90507066..1bf18886ece 100644 --- a/cmk/base/legacy_checks/bvip_link.py +++ b/cmk/base/legacy_checks/bvip_link.py @@ -53,6 +53,7 @@ def parse_bvip_link(string_table: StringTable) -> StringTable: check_info["bvip_link"] = LegacyCheckDefinition( + name="bvip_link", parse_function=parse_bvip_link, detect=DETECT_BVIP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bvip_poe.py b/cmk/base/legacy_checks/bvip_poe.py index 3f634fa12c5..fef735fbacb 100644 --- a/cmk/base/legacy_checks/bvip_poe.py +++ b/cmk/base/legacy_checks/bvip_poe.py @@ -29,6 +29,7 @@ def parse_bvip_poe(string_table: StringTable) -> StringTable: check_info["bvip_poe"] = LegacyCheckDefinition( + name="bvip_poe", parse_function=parse_bvip_poe, detect=DETECT_BVIP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bvip_temp.py b/cmk/base/legacy_checks/bvip_temp.py index 32553b3132d..291a39c1928 100644 --- a/cmk/base/legacy_checks/bvip_temp.py +++ b/cmk/base/legacy_checks/bvip_temp.py @@ -31,6 +31,7 @@ def parse_bvip_temp(string_table: StringTable) -> StringTable: check_info["bvip_temp"] = LegacyCheckDefinition( + name="bvip_temp", parse_function=parse_bvip_temp, detect=DETECT_BVIP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/bvip_util.py b/cmk/base/legacy_checks/bvip_util.py index 937ff3e8516..1f79be1290c 100644 --- a/cmk/base/legacy_checks/bvip_util.py +++ b/cmk/base/legacy_checks/bvip_util.py @@ -36,6 +36,7 @@ def parse_bvip_util(string_table: StringTable) -> StringTable: check_info["bvip_util"] = LegacyCheckDefinition( + name="bvip_util", parse_function=parse_bvip_util, detect=DETECT_BVIP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cadvisor_cpu.py b/cmk/base/legacy_checks/cadvisor_cpu.py index 6f30256aeee..cbc7b4c19fc 100644 --- a/cmk/base/legacy_checks/cadvisor_cpu.py +++ b/cmk/base/legacy_checks/cadvisor_cpu.py @@ -57,6 +57,7 @@ def check_cadvisor_cpu(_item, params, parsed): check_info["cadvisor_cpu"] = LegacyCheckDefinition( + name="cadvisor_cpu", parse_function=parse_cadvisor_cpu, service_name="CPU utilization", discovery_function=discover_cadvisor_cpu, diff --git a/cmk/base/legacy_checks/cadvisor_df.py b/cmk/base/legacy_checks/cadvisor_df.py index dedddde93d0..5200dd6b08e 100644 --- a/cmk/base/legacy_checks/cadvisor_df.py +++ b/cmk/base/legacy_checks/cadvisor_df.py @@ -45,6 +45,7 @@ def check_cadvisor_df(item, _params, parsed): check_info["cadvisor_df"] = LegacyCheckDefinition( + name="cadvisor_df", parse_function=parse_cadvisor_df, service_name="Filesystem", discovery_function=discover_cadvisor_df, diff --git a/cmk/base/legacy_checks/cadvisor_memory.py b/cmk/base/legacy_checks/cadvisor_memory.py index fbf07117e3b..3111cecf711 100644 --- a/cmk/base/legacy_checks/cadvisor_memory.py +++ b/cmk/base/legacy_checks/cadvisor_memory.py @@ -72,6 +72,7 @@ def check_cadvisor_memory(_item, _params, parsed): check_info["cadvisor_memory"] = LegacyCheckDefinition( + name="cadvisor_memory", parse_function=parse_cadvisor_memory, service_name="Memory", discovery_function=discover_cadvisor_memory, diff --git a/cmk/base/legacy_checks/carel_sensors.py b/cmk/base/legacy_checks/carel_sensors.py index 9d39f515def..c7263aba1f4 100644 --- a/cmk/base/legacy_checks/carel_sensors.py +++ b/cmk/base/legacy_checks/carel_sensors.py @@ -77,6 +77,7 @@ def check_carel_sensors_temp(item, params, parsed): check_info["carel_sensors"] = LegacyCheckDefinition( + name="carel_sensors", detect=all_of( any_of(contains(".1.3.6.1.2.1.1.1.0", "pCO"), endswith(".1.3.6.1.2.1.1.1.0", "armv4l")), exists(".1.3.6.1.4.1.9839.1.1.0"), diff --git a/cmk/base/legacy_checks/casa_cpu_mem.py b/cmk/base/legacy_checks/casa_cpu_mem.py index 824ba0e5be6..46ad13b8f45 100644 --- a/cmk/base/legacy_checks/casa_cpu_mem.py +++ b/cmk/base/legacy_checks/casa_cpu_mem.py @@ -48,6 +48,7 @@ def check_casa_cpu_mem(item, params, parsed): check_info["casa_cpu_mem"] = LegacyCheckDefinition( + name="casa_cpu_mem", detect=DETECT_CASA, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/casa_cpu_temp.py b/cmk/base/legacy_checks/casa_cpu_temp.py index 12c859323c7..20725b725e9 100644 --- a/cmk/base/legacy_checks/casa_cpu_temp.py +++ b/cmk/base/legacy_checks/casa_cpu_temp.py @@ -51,6 +51,7 @@ def check_casa_cpu_temp(item, params, parsed): check_info["casa_cpu_temp"] = LegacyCheckDefinition( + name="casa_cpu_temp", detect=DETECT_CASA, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/casa_cpu_util.py b/cmk/base/legacy_checks/casa_cpu_util.py index d0021cde3d0..9a89b99e12e 100644 --- a/cmk/base/legacy_checks/casa_cpu_util.py +++ b/cmk/base/legacy_checks/casa_cpu_util.py @@ -55,6 +55,7 @@ def parse_casa_cpu_util(string_table: Sequence[StringTable]) -> Sequence[StringT check_info["casa_cpu_util"] = LegacyCheckDefinition( + name="casa_cpu_util", parse_function=parse_casa_cpu_util, detect=DETECT_CASA, fetch=[ diff --git a/cmk/base/legacy_checks/checkpoint_fan.py b/cmk/base/legacy_checks/checkpoint_fan.py index c0a4156c225..36b7df811bb 100644 --- a/cmk/base/legacy_checks/checkpoint_fan.py +++ b/cmk/base/legacy_checks/checkpoint_fan.py @@ -33,6 +33,7 @@ def parse_checkpoint_fan(string_table: StringTable) -> StringTable: check_info["checkpoint_fan"] = LegacyCheckDefinition( + name="checkpoint_fan", parse_function=parse_checkpoint_fan, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_memory.py b/cmk/base/legacy_checks/checkpoint_memory.py index c228e423650..295186d1522 100644 --- a/cmk/base/legacy_checks/checkpoint_memory.py +++ b/cmk/base/legacy_checks/checkpoint_memory.py @@ -41,6 +41,7 @@ def parse_checkpoint_memory(string_table: StringTable) -> StringTable: check_info["checkpoint_memory"] = LegacyCheckDefinition( + name="checkpoint_memory", parse_function=parse_checkpoint_memory, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_packets.py b/cmk/base/legacy_checks/checkpoint_packets.py index 3bc160638f7..f52a608ee91 100644 --- a/cmk/base/legacy_checks/checkpoint_packets.py +++ b/cmk/base/legacy_checks/checkpoint_packets.py @@ -65,6 +65,7 @@ def check_checkpoint_packets(_no_item, params, parsed): check_info["checkpoint_packets"] = LegacyCheckDefinition( + name="checkpoint_packets", detect=DETECT, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_temp.py b/cmk/base/legacy_checks/checkpoint_temp.py index 9d47b0784f3..f242d6db232 100644 --- a/cmk/base/legacy_checks/checkpoint_temp.py +++ b/cmk/base/legacy_checks/checkpoint_temp.py @@ -47,6 +47,7 @@ def parse_checkpoint_temp(string_table: StringTable) -> StringTable: check_info["checkpoint_temp"] = LegacyCheckDefinition( + name="checkpoint_temp", parse_function=parse_checkpoint_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_tunnels.py b/cmk/base/legacy_checks/checkpoint_tunnels.py index c5771890392..22350d24217 100644 --- a/cmk/base/legacy_checks/checkpoint_tunnels.py +++ b/cmk/base/legacy_checks/checkpoint_tunnels.py @@ -38,6 +38,7 @@ def parse_checkpoint_tunnels(string_table: StringTable) -> StringTable: check_info["checkpoint_tunnels"] = LegacyCheckDefinition( + name="checkpoint_tunnels", parse_function=parse_checkpoint_tunnels, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_voltage.py b/cmk/base/legacy_checks/checkpoint_voltage.py index 915688d65f4..817caadb918 100644 --- a/cmk/base/legacy_checks/checkpoint_voltage.py +++ b/cmk/base/legacy_checks/checkpoint_voltage.py @@ -30,6 +30,7 @@ def parse_checkpoint_voltage(string_table: StringTable) -> StringTable: check_info["checkpoint_voltage"] = LegacyCheckDefinition( + name="checkpoint_voltage", parse_function=parse_checkpoint_voltage, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/checkpoint_vsx.py b/cmk/base/legacy_checks/checkpoint_vsx.py index 31f84380b8a..f717a888496 100644 --- a/cmk/base/legacy_checks/checkpoint_vsx.py +++ b/cmk/base/legacy_checks/checkpoint_vsx.py @@ -136,6 +136,7 @@ def check_checkpoint_vsx(item, _no_params, parsed): check_info["checkpoint_vsx"] = LegacyCheckDefinition( + name="checkpoint_vsx", detect=DETECT_NEVER, fetch=[ SNMPTree( @@ -196,6 +197,7 @@ def check_checkpoint_vsx_connections(item, params, parsed): check_info["checkpoint_vsx.connections"] = LegacyCheckDefinition( + name="checkpoint_vsx_connections", service_name="VS %s Connections", sections=["checkpoint_vsx"], discovery_function=discover_key("conn_num"), @@ -251,6 +253,7 @@ def check_checkpoint_vsx_packets(item, params, parsed): check_info["checkpoint_vsx.packets"] = LegacyCheckDefinition( + name="checkpoint_vsx_packets", service_name="VS %s Packets", sections=["checkpoint_vsx"], discovery_function=discover_key("packets"), @@ -298,6 +301,7 @@ def check_checkpoint_vsx_traffic(item, params, parsed): check_info["checkpoint_vsx.traffic"] = LegacyCheckDefinition( + name="checkpoint_vsx_traffic", service_name="VS %s Traffic", sections=["checkpoint_vsx"], discovery_function=discover_key("bytes_accepted"), @@ -352,6 +356,7 @@ def check_checkpoint_vsx_status(item, _no_params, parsed): check_info["checkpoint_vsx.status"] = LegacyCheckDefinition( + name="checkpoint_vsx_status", service_name="VS %s Status", sections=["checkpoint_vsx"], discovery_function=discover_key("vs_ha_status"), diff --git a/cmk/base/legacy_checks/cisco_asa_connections.py b/cmk/base/legacy_checks/cisco_asa_connections.py index 3816922a0c3..88f4feb5767 100644 --- a/cmk/base/legacy_checks/cisco_asa_connections.py +++ b/cmk/base/legacy_checks/cisco_asa_connections.py @@ -47,6 +47,7 @@ def parse_cisco_asa_connections(string_table: StringTable) -> StringTable | None check_info["cisco_asa_connections"] = LegacyCheckDefinition( + name="cisco_asa_connections", parse_function=parse_cisco_asa_connections, detect=any_of( startswith(".1.3.6.1.2.1.1.1.0", "cisco adaptive security"), diff --git a/cmk/base/legacy_checks/cisco_cpu.py b/cmk/base/legacy_checks/cisco_cpu.py index 7242182f866..d32c5ebcddb 100644 --- a/cmk/base/legacy_checks/cisco_cpu.py +++ b/cmk/base/legacy_checks/cisco_cpu.py @@ -56,6 +56,7 @@ def parse_cisco_cpu(string_table: StringTable) -> StringTable: check_info["cisco_cpu"] = LegacyCheckDefinition( + name="cisco_cpu", parse_function=parse_cisco_cpu, detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "cisco"), diff --git a/cmk/base/legacy_checks/cisco_fru_powerusage.py b/cmk/base/legacy_checks/cisco_fru_powerusage.py index 2b9f4890df7..b9f4034392e 100644 --- a/cmk/base/legacy_checks/cisco_fru_powerusage.py +++ b/cmk/base/legacy_checks/cisco_fru_powerusage.py @@ -78,6 +78,7 @@ def inventory_cisco_fru_powerusage(parsed): check_info["cisco_fru_powerusage"] = LegacyCheckDefinition( + name="cisco_fru_powerusage", detect=DETECT_CISCO, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ip_sla.py b/cmk/base/legacy_checks/cisco_ip_sla.py index 407c61da040..2c878ad1039 100644 --- a/cmk/base/legacy_checks/cisco_ip_sla.py +++ b/cmk/base/legacy_checks/cisco_ip_sla.py @@ -162,6 +162,7 @@ def check_cisco_ip_sla(item, params, parsed): check_info["cisco_ip_sla"] = LegacyCheckDefinition( + name="cisco_ip_sla", detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "cisco"), contains(".1.3.6.1.2.1.1.1.0", "ios"), diff --git a/cmk/base/legacy_checks/cisco_nexus_cpu.py b/cmk/base/legacy_checks/cisco_nexus_cpu.py index a756484c8d7..ac0ad2fbcf8 100644 --- a/cmk/base/legacy_checks/cisco_nexus_cpu.py +++ b/cmk/base/legacy_checks/cisco_nexus_cpu.py @@ -39,6 +39,7 @@ def parse_cisco_nexus_cpu(string_table: StringTable) -> StringTable: check_info["cisco_nexus_cpu"] = LegacyCheckDefinition( + name="cisco_nexus_cpu", parse_function=parse_cisco_nexus_cpu, detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "cisco"), diff --git a/cmk/base/legacy_checks/cisco_oldcpu.py b/cmk/base/legacy_checks/cisco_oldcpu.py index 18d298bdaab..f512754a92e 100644 --- a/cmk/base/legacy_checks/cisco_oldcpu.py +++ b/cmk/base/legacy_checks/cisco_oldcpu.py @@ -35,6 +35,7 @@ def parse_cisco_oldcpu(string_table: StringTable) -> StringTable: check_info["cisco_oldcpu"] = LegacyCheckDefinition( + name="cisco_oldcpu", parse_function=parse_cisco_oldcpu, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.9.1.1745"), diff --git a/cmk/base/legacy_checks/cisco_prime_wifi_access_points.py b/cmk/base/legacy_checks/cisco_prime_wifi_access_points.py index b14034078e5..63f8c8ffbc6 100644 --- a/cmk/base/legacy_checks/cisco_prime_wifi_access_points.py +++ b/cmk/base/legacy_checks/cisco_prime_wifi_access_points.py @@ -47,6 +47,7 @@ def check_cisco_prime_wifi_access_points(item, params, parsed): check_info["cisco_prime_wifi_access_points"] = LegacyCheckDefinition( + name="cisco_prime_wifi_access_points", parse_function=parse_cisco_prime_wifi_access_points, service_name="Cisco Prime WiFi Access Points", discovery_function=discover_cisco_prime_wifi_access_points, diff --git a/cmk/base/legacy_checks/cisco_prime_wifi_connections.py b/cmk/base/legacy_checks/cisco_prime_wifi_connections.py index bf10cbd4cc5..e9119c7caf6 100644 --- a/cmk/base/legacy_checks/cisco_prime_wifi_connections.py +++ b/cmk/base/legacy_checks/cisco_prime_wifi_connections.py @@ -77,6 +77,7 @@ def check_cisco_prime_wifi_connections(item, params, parsed): check_info["cisco_prime_wifi_connections"] = LegacyCheckDefinition( + name="cisco_prime_wifi_connections", parse_function=parse_cisco_prime_wifi_connections, service_name="Cisco Prime WiFi Connections", discovery_function=discover_cisco_prime_wifi_connections, diff --git a/cmk/base/legacy_checks/cisco_srst_state.py b/cmk/base/legacy_checks/cisco_srst_state.py index 0c85efe28ca..ee41ee23bf0 100644 --- a/cmk/base/legacy_checks/cisco_srst_state.py +++ b/cmk/base/legacy_checks/cisco_srst_state.py @@ -36,6 +36,7 @@ def parse_cisco_srst_state(string_table: StringTable) -> StringTable | None: check_info["cisco_srst_state"] = LegacyCheckDefinition( + name="cisco_srst_state", parse_function=parse_cisco_srst_state, detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "cisco"), equals(".1.3.6.1.4.1.9.9.441.1.2.1.0", "1") diff --git a/cmk/base/legacy_checks/cisco_sys_mem.py b/cmk/base/legacy_checks/cisco_sys_mem.py index cd2b85162a8..b241a4c1bf2 100644 --- a/cmk/base/legacy_checks/cisco_sys_mem.py +++ b/cmk/base/legacy_checks/cisco_sys_mem.py @@ -37,6 +37,7 @@ def parse_cisco_sys_mem(string_table: StringTable) -> StringTable: check_info["cisco_sys_mem"] = LegacyCheckDefinition( + name="cisco_sys_mem", parse_function=parse_cisco_sys_mem, detect=startswith(".1.3.6.1.2.1.1.1.0", "Cisco NX-OS"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_cpu.py b/cmk/base/legacy_checks/cisco_ucs_cpu.py index cf9918d1964..fa8ebe86e7c 100644 --- a/cmk/base/legacy_checks/cisco_ucs_cpu.py +++ b/cmk/base/legacy_checks/cisco_ucs_cpu.py @@ -44,6 +44,7 @@ def parse_cisco_ucs_cpu(string_table: StringTable) -> StringTable: check_info["cisco_ucs_cpu"] = LegacyCheckDefinition( + name="cisco_ucs_cpu", parse_function=parse_cisco_ucs_cpu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_hdd.py b/cmk/base/legacy_checks/cisco_ucs_hdd.py index 154832f079a..bb1503beb0d 100644 --- a/cmk/base/legacy_checks/cisco_ucs_hdd.py +++ b/cmk/base/legacy_checks/cisco_ucs_hdd.py @@ -72,6 +72,7 @@ def check_cisco_ucs_hdd( check_info["cisco_ucs_hdd"] = LegacyCheckDefinition( + name="cisco_ucs_hdd", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.9.9.719.1.45.4.1", diff --git a/cmk/base/legacy_checks/cisco_ucs_lun.py b/cmk/base/legacy_checks/cisco_ucs_lun.py index 4ec050779fd..a5f74e74585 100644 --- a/cmk/base/legacy_checks/cisco_ucs_lun.py +++ b/cmk/base/legacy_checks/cisco_ucs_lun.py @@ -51,6 +51,7 @@ def parse_cisco_ucs_lun(string_table: StringTable) -> StringTable | None: check_info["cisco_ucs_lun"] = LegacyCheckDefinition( + name="cisco_ucs_lun", parse_function=parse_cisco_ucs_lun, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_mem_total.py b/cmk/base/legacy_checks/cisco_ucs_mem_total.py index cb577428abc..07a5af85dd1 100644 --- a/cmk/base/legacy_checks/cisco_ucs_mem_total.py +++ b/cmk/base/legacy_checks/cisco_ucs_mem_total.py @@ -29,6 +29,7 @@ def parse_cisco_ucs_mem_total(string_table: StringTable) -> StringTable | None: check_info["cisco_ucs_mem_total"] = LegacyCheckDefinition( + name="cisco_ucs_mem_total", parse_function=parse_cisco_ucs_mem_total, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_psu.py b/cmk/base/legacy_checks/cisco_ucs_psu.py index c9a649e12f4..27ec111e830 100644 --- a/cmk/base/legacy_checks/cisco_ucs_psu.py +++ b/cmk/base/legacy_checks/cisco_ucs_psu.py @@ -40,6 +40,7 @@ def parse_cisco_ucs_psu(string_table: StringTable) -> StringTable: check_info["cisco_ucs_psu"] = LegacyCheckDefinition( + name="cisco_ucs_psu", parse_function=parse_cisco_ucs_psu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_raid.py b/cmk/base/legacy_checks/cisco_ucs_raid.py index 86ec6c7bb49..24616d2bf25 100644 --- a/cmk/base/legacy_checks/cisco_ucs_raid.py +++ b/cmk/base/legacy_checks/cisco_ucs_raid.py @@ -45,6 +45,7 @@ def check_cisco_ucs_raid(_no_item, _no_params, section): check_info["cisco_ucs_raid"] = LegacyCheckDefinition( + name="cisco_ucs_raid", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.9.9.719.1.45.1.1", diff --git a/cmk/base/legacy_checks/cisco_ucs_system.py b/cmk/base/legacy_checks/cisco_ucs_system.py index f1a61453e1a..66a99567411 100644 --- a/cmk/base/legacy_checks/cisco_ucs_system.py +++ b/cmk/base/legacy_checks/cisco_ucs_system.py @@ -32,6 +32,7 @@ def parse_cisco_ucs_system(string_table: StringTable) -> StringTable | None: check_info["cisco_ucs_system"] = LegacyCheckDefinition( + name="cisco_ucs_system", parse_function=parse_cisco_ucs_system, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_ucs_temp_env.py b/cmk/base/legacy_checks/cisco_ucs_temp_env.py index 2d90e3c36f3..73cfc4e55ed 100644 --- a/cmk/base/legacy_checks/cisco_ucs_temp_env.py +++ b/cmk/base/legacy_checks/cisco_ucs_temp_env.py @@ -44,6 +44,7 @@ def check_cisco_ucs_temp_env(item, params, info): check_info["cisco_ucs_temp_env"] = LegacyCheckDefinition( + name="cisco_ucs_temp_env", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.9.9.719.1.9.44.1", diff --git a/cmk/base/legacy_checks/cisco_ucs_temp_mem.py b/cmk/base/legacy_checks/cisco_ucs_temp_mem.py index 16840c3b3a6..595c9b3f98f 100644 --- a/cmk/base/legacy_checks/cisco_ucs_temp_mem.py +++ b/cmk/base/legacy_checks/cisco_ucs_temp_mem.py @@ -37,6 +37,7 @@ def parse_cisco_ucs_temp_mem(string_table: StringTable) -> StringTable: check_info["cisco_ucs_temp_mem"] = LegacyCheckDefinition( + name="cisco_ucs_temp_mem", parse_function=parse_cisco_ucs_temp_mem, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cisco_vpn_sessions.py b/cmk/base/legacy_checks/cisco_vpn_sessions.py index cb0fad93807..a971708d1f3 100644 --- a/cmk/base/legacy_checks/cisco_vpn_sessions.py +++ b/cmk/base/legacy_checks/cisco_vpn_sessions.py @@ -39,6 +39,7 @@ def discover_cisco_vpn_sessions(section): check_info["cisco_vpn_sessions"] = LegacyCheckDefinition( + name="cisco_vpn_sessions", service_name="VPN Sessions %s", discovery_function=discover_cisco_vpn_sessions, check_function=check_cisco_vpn_sessions, diff --git a/cmk/base/legacy_checks/citrix_licenses.py b/cmk/base/legacy_checks/citrix_licenses.py index d4c4fdce5b2..2cf628aaa4d 100644 --- a/cmk/base/legacy_checks/citrix_licenses.py +++ b/cmk/base/legacy_checks/citrix_licenses.py @@ -51,6 +51,7 @@ def check_citrix_licenses(item, params, parsed): check_info["citrix_licenses"] = LegacyCheckDefinition( + name="citrix_licenses", parse_function=parse_citrix_licenses, service_name="Citrix Licenses %s", discovery_function=inventory_citrix_licenses, diff --git a/cmk/base/legacy_checks/citrix_serverload.py b/cmk/base/legacy_checks/citrix_serverload.py index 48e47df6f01..63e8ef4b04f 100644 --- a/cmk/base/legacy_checks/citrix_serverload.py +++ b/cmk/base/legacy_checks/citrix_serverload.py @@ -41,6 +41,7 @@ def parse_citrix_serverload(string_table: StringTable) -> StringTable: check_info["citrix_serverload"] = LegacyCheckDefinition( + name="citrix_serverload", parse_function=parse_citrix_serverload, service_name="Citrix Serverload", discovery_function=inventory_citrix_serverload, diff --git a/cmk/base/legacy_checks/citrix_sessions.py b/cmk/base/legacy_checks/citrix_sessions.py index 9b7cece551e..7ff6b9248f6 100644 --- a/cmk/base/legacy_checks/citrix_sessions.py +++ b/cmk/base/legacy_checks/citrix_sessions.py @@ -62,6 +62,7 @@ def parse_citrix_sessions(string_table: StringTable) -> StringTable: check_info["citrix_sessions"] = LegacyCheckDefinition( + name="citrix_sessions", parse_function=parse_citrix_sessions, service_name="Citrix Sessions", discovery_function=inventory_citrix_sessions, diff --git a/cmk/base/legacy_checks/climaveneta_fan.py b/cmk/base/legacy_checks/climaveneta_fan.py index 432893bc8ab..ae6a5f49bf4 100644 --- a/cmk/base/legacy_checks/climaveneta_fan.py +++ b/cmk/base/legacy_checks/climaveneta_fan.py @@ -27,6 +27,7 @@ def parse_climaveneta_fan(string_table: StringTable) -> StringTable: check_info["climaveneta_fan"] = LegacyCheckDefinition( + name="climaveneta_fan", parse_function=parse_climaveneta_fan, detect=equals(".1.3.6.1.2.1.1.1.0", "pCO Gateway"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/climaveneta_temp.py b/cmk/base/legacy_checks/climaveneta_temp.py index 53165642cb2..7bdf06fe1f0 100644 --- a/cmk/base/legacy_checks/climaveneta_temp.py +++ b/cmk/base/legacy_checks/climaveneta_temp.py @@ -52,6 +52,7 @@ def parse_climaveneta_temp(string_table: StringTable) -> StringTable: check_info["climaveneta_temp"] = LegacyCheckDefinition( + name="climaveneta_temp", parse_function=parse_climaveneta_temp, detect=equals(".1.3.6.1.2.1.1.1.0", "pCO Gateway"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/cmc_temp.py b/cmk/base/legacy_checks/cmc_temp.py index 83a7240d67a..2a7d24f170e 100644 --- a/cmk/base/legacy_checks/cmc_temp.py +++ b/cmk/base/legacy_checks/cmc_temp.py @@ -39,6 +39,7 @@ def parse_cmc_temp(string_table: Sequence[StringTable]) -> Sequence[StringTable] check_info["cmc_temp"] = LegacyCheckDefinition( + name="cmc_temp", parse_function=parse_cmc_temp, detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2606.1"), fetch=[ diff --git a/cmk/base/legacy_checks/cmciii_lcp_water.py b/cmk/base/legacy_checks/cmciii_lcp_water.py index ec8c3e4cb27..6845250c9bc 100644 --- a/cmk/base/legacy_checks/cmciii_lcp_water.py +++ b/cmk/base/legacy_checks/cmciii_lcp_water.py @@ -108,6 +108,7 @@ def parse_status(status_name): check_info["cmciii_lcp_water"] = LegacyCheckDefinition( + name="cmciii_lcp_water", detect=DETECT_CMCIII_LCP, fetch=SNMPTree( base=".1.3.6.1.4.1.2606.7.4.2.2.1.10", diff --git a/cmk/base/legacy_checks/cmctc.py b/cmk/base/legacy_checks/cmctc.py index 23f292597bb..33c4fe7e427 100644 --- a/cmk/base/legacy_checks/cmctc.py +++ b/cmk/base/legacy_checks/cmctc.py @@ -71,6 +71,7 @@ def check_cmctc_temp(item: str, params: TempParamType, section: Section) -> Iter check_info["cmctc_temp"] = LegacyCheckDefinition( + name="cmctc_temp", detect=DETECT_CMCTC, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/couchbase_buckets_cache.py b/cmk/base/legacy_checks/couchbase_buckets_cache.py index 1dd3053f47f..35da842d988 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_cache.py +++ b/cmk/base/legacy_checks/couchbase_buckets_cache.py @@ -34,6 +34,7 @@ def check_couchbase_buckets_cache(item, params, parsed): check_info["couchbase_buckets_cache"] = LegacyCheckDefinition( + name="couchbase_buckets_cache", parse_function=parse_couchbase_lines, service_name="Couchbase Bucket %s Cache", discovery_function=discover_couchbase_buckets_cache, diff --git a/cmk/base/legacy_checks/couchbase_buckets_fragmentation.py b/cmk/base/legacy_checks/couchbase_buckets_fragmentation.py index a5fcbf2cd50..79f156e11a6 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_fragmentation.py +++ b/cmk/base/legacy_checks/couchbase_buckets_fragmentation.py @@ -44,6 +44,7 @@ def check_couchbase_buckets_fragmentation(item, params, parsed): check_info["couchbase_buckets_fragmentation"] = LegacyCheckDefinition( + name="couchbase_buckets_fragmentation", parse_function=parse_couchbase_lines, service_name="Couchbase Bucket %s Fragmentation", discovery_function=discover_couchbase_buckets_fragmentation, diff --git a/cmk/base/legacy_checks/couchbase_buckets_items.py b/cmk/base/legacy_checks/couchbase_buckets_items.py index cb4dde378cf..1251049f81a 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_items.py +++ b/cmk/base/legacy_checks/couchbase_buckets_items.py @@ -73,6 +73,7 @@ def check_couchbase_buckets_items(item, params, parsed): check_info["couchbase_buckets_items"] = LegacyCheckDefinition( + name="couchbase_buckets_items", parse_function=parse_couchbase_lines, service_name="Couchbase Bucket %s Items", discovery_function=discover_couchbase_buckets_items, diff --git a/cmk/base/legacy_checks/couchbase_buckets_mem.py b/cmk/base/legacy_checks/couchbase_buckets_mem.py index 68942617181..3bc7b11b95f 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_mem.py +++ b/cmk/base/legacy_checks/couchbase_buckets_mem.py @@ -60,6 +60,7 @@ def check_couchbase_bucket_mem(item, params, parsed): check_info["couchbase_buckets_mem"] = LegacyCheckDefinition( + name="couchbase_buckets_mem", parse_function=parse_couchbase_lines, service_name="Couchbase Bucket %s Memory", discovery_function=discover_couchbase_buckets_mem, diff --git a/cmk/base/legacy_checks/couchbase_buckets_operations.py b/cmk/base/legacy_checks/couchbase_buckets_operations.py index d289ceeaef6..6831b7d6b14 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_operations.py +++ b/cmk/base/legacy_checks/couchbase_buckets_operations.py @@ -93,6 +93,7 @@ def check_couchbase_buckets_operations(item, params, parsed): check_info["couchbase_buckets_operations"] = LegacyCheckDefinition( + name="couchbase_buckets_operations", parse_function=parse_couchbase_buckets_operations, service_name="Couchbase Bucket %s Operations", discovery_function=discover_couchbase_buckets_operations, @@ -101,6 +102,7 @@ def check_couchbase_buckets_operations(item, params, parsed): ) check_info["couchbase_buckets_operations.total"] = LegacyCheckDefinition( + name="couchbase_buckets_operations_total", service_name="Couchbase Bucket Operations", sections=["couchbase_buckets_operations"], discovery_function=discover_couchbase_buckets_operations, diff --git a/cmk/base/legacy_checks/couchbase_buckets_vbuckets.py b/cmk/base/legacy_checks/couchbase_buckets_vbuckets.py index 5d1acffc4b5..d5037877168 100644 --- a/cmk/base/legacy_checks/couchbase_buckets_vbuckets.py +++ b/cmk/base/legacy_checks/couchbase_buckets_vbuckets.py @@ -80,6 +80,7 @@ def check_couchbase_buckets_vbuckets_replica(item, params, parsed): check_info["couchbase_buckets_vbuckets"] = LegacyCheckDefinition( + name="couchbase_buckets_vbuckets", parse_function=parse_couchbase_lines, service_name="Couchbase Bucket %s active vBuckets", discovery_function=discover_couchbase_buckets_vbuckets, @@ -88,6 +89,7 @@ def check_couchbase_buckets_vbuckets_replica(item, params, parsed): ) check_info["couchbase_buckets_vbuckets.replica"] = LegacyCheckDefinition( + name="couchbase_buckets_vbuckets_replica", service_name="Couchbase Bucket %s replica vBuckets", sections=["couchbase_buckets_vbuckets"], discovery_function=discover_couchbase_buckets_vbuckets, diff --git a/cmk/base/legacy_checks/couchbase_nodes_cache.py b/cmk/base/legacy_checks/couchbase_nodes_cache.py index 95dc8a2f8a6..0ca9ff13032 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_cache.py +++ b/cmk/base/legacy_checks/couchbase_nodes_cache.py @@ -57,6 +57,7 @@ def check_couchbase_nodes_cache(item, params, parsed): check_info["couchbase_nodes_cache"] = LegacyCheckDefinition( + name="couchbase_nodes_cache", parse_function=parse_couchbase_lines, service_name="Couchbase %s Cache", discovery_function=discover_couchbase_nodes_cache, diff --git a/cmk/base/legacy_checks/couchbase_nodes_info.py b/cmk/base/legacy_checks/couchbase_nodes_info.py index 5c98679b7e6..afd1030d70d 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_info.py +++ b/cmk/base/legacy_checks/couchbase_nodes_info.py @@ -47,6 +47,7 @@ def discover_couchbase_nodes_info(section): check_info["couchbase_nodes_info"] = LegacyCheckDefinition( + name="couchbase_nodes_info", parse_function=parse_couchbase_lines, service_name="Couchbase %s Info", discovery_function=discover_couchbase_nodes_info, diff --git a/cmk/base/legacy_checks/couchbase_nodes_items.py b/cmk/base/legacy_checks/couchbase_nodes_items.py index 1146b7d2aa1..fb4b9e20fd3 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_items.py +++ b/cmk/base/legacy_checks/couchbase_nodes_items.py @@ -53,6 +53,7 @@ def check_couchbase_nodes_items(item, params, parsed): check_info["couchbase_nodes_items"] = LegacyCheckDefinition( + name="couchbase_nodes_items", parse_function=parse_couchbase_lines, service_name="Couchbase %s vBucket items", discovery_function=discover_couchbase_nodes_items, diff --git a/cmk/base/legacy_checks/couchbase_nodes_operations.py b/cmk/base/legacy_checks/couchbase_nodes_operations.py index 8f018858f07..87920e7001a 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_operations.py +++ b/cmk/base/legacy_checks/couchbase_nodes_operations.py @@ -43,6 +43,7 @@ def check_couchbase_nodes_operations(item, params, parsed): check_info["couchbase_nodes_operations"] = LegacyCheckDefinition( + name="couchbase_nodes_operations", parse_function=parse_couchbase_nodes_operations, service_name="Couchbase %s Operations", discovery_function=discover_couchbase_buckets_nodes_operations, @@ -51,6 +52,7 @@ def check_couchbase_nodes_operations(item, params, parsed): ) check_info["couchbase_nodes_operations.total"] = LegacyCheckDefinition( + name="couchbase_nodes_operations_total", service_name="Couchbase Total Operations", sections=["couchbase_nodes_operations"], discovery_function=discover_couchbase_buckets_nodes_operations_total, diff --git a/cmk/base/legacy_checks/couchbase_nodes_size.py b/cmk/base/legacy_checks/couchbase_nodes_size.py index 8669736fd96..9371eaacb45 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_size.py +++ b/cmk/base/legacy_checks/couchbase_nodes_size.py @@ -16,6 +16,7 @@ def discover_couchbase_nodes_size(section): check_info["couchbase_nodes_size"] = LegacyCheckDefinition( + name="couchbase_nodes_size", parse_function=parse_couchbase_lines, discovery_function=discover_couchbase_nodes_size, ) @@ -53,6 +54,7 @@ def discover_couchbase_nodes_size_docs(section): check_info["couchbase_nodes_size.docs"] = LegacyCheckDefinition( + name="couchbase_nodes_size_docs", service_name="Couchbase %s Documents", sections=["couchbase_nodes_size"], discovery_function=discover_couchbase_nodes_size_docs, @@ -69,6 +71,7 @@ def discover_couchbase_nodes_size_spacial_views(section): check_info["couchbase_nodes_size.spacial_views"] = LegacyCheckDefinition( + name="couchbase_nodes_size_spacial_views", service_name="Couchbase %s Spacial Views", sections=["couchbase_nodes_size"], discovery_function=discover_couchbase_nodes_size_spacial_views, @@ -85,6 +88,7 @@ def discover_couchbase_nodes_size_couch_views(section): check_info["couchbase_nodes_size.couch_views"] = LegacyCheckDefinition( + name="couchbase_nodes_size_couch_views", service_name="Couchbase %s Couch Views", sections=["couchbase_nodes_size"], discovery_function=discover_couchbase_nodes_size_couch_views, diff --git a/cmk/base/legacy_checks/couchbase_nodes_stats.py b/cmk/base/legacy_checks/couchbase_nodes_stats.py index 1119ddbf447..26f3312d16e 100644 --- a/cmk/base/legacy_checks/couchbase_nodes_stats.py +++ b/cmk/base/legacy_checks/couchbase_nodes_stats.py @@ -17,6 +17,7 @@ def discover_couchbase_nodes_stats(section): check_info["couchbase_nodes_stats"] = LegacyCheckDefinition( + name="couchbase_nodes_stats", parse_function=parse_couchbase_lines, discovery_function=discover_couchbase_nodes_stats, ) @@ -37,6 +38,7 @@ def discover_couchbase_nodes_stats_cpu_util(section): check_info["couchbase_nodes_stats.cpu_util"] = LegacyCheckDefinition( + name="couchbase_nodes_stats_cpu_util", service_name="Couchbase %s CPU utilization", sections=["couchbase_nodes_stats"], discovery_function=discover_couchbase_nodes_stats_cpu_util, @@ -81,6 +83,7 @@ def discover_couchbase_nodes_stats_mem(section): check_info["couchbase_nodes_stats.mem"] = LegacyCheckDefinition( + name="couchbase_nodes_stats_mem", service_name="Couchbase %s Memory", sections=["couchbase_nodes_stats"], discovery_function=discover_couchbase_nodes_stats_mem, diff --git a/cmk/base/legacy_checks/cups_queues.py b/cmk/base/legacy_checks/cups_queues.py index 6f17d41abd4..b75f53e88e8 100644 --- a/cmk/base/legacy_checks/cups_queues.py +++ b/cmk/base/legacy_checks/cups_queues.py @@ -126,6 +126,7 @@ def check_cups_queues(item, params, parsed): check_info["cups_queues"] = LegacyCheckDefinition( + name="cups_queues", parse_function=parse_cups_queues, service_name="CUPS Queue %s", discovery_function=inventory_cups_queues, diff --git a/cmk/base/legacy_checks/datapower_cpu.py b/cmk/base/legacy_checks/datapower_cpu.py index 3e00592db4f..474e9ded41d 100644 --- a/cmk/base/legacy_checks/datapower_cpu.py +++ b/cmk/base/legacy_checks/datapower_cpu.py @@ -27,6 +27,7 @@ def parse_datapower_cpu(string_table: StringTable) -> StringTable: check_info["datapower_cpu"] = LegacyCheckDefinition( + name="datapower_cpu", parse_function=parse_datapower_cpu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/datapower_fs.py b/cmk/base/legacy_checks/datapower_fs.py index 5eaa8920a99..d8b7deaad2c 100644 --- a/cmk/base/legacy_checks/datapower_fs.py +++ b/cmk/base/legacy_checks/datapower_fs.py @@ -60,6 +60,7 @@ def parse_datapower_fs(string_table: StringTable) -> StringTable: check_info["datapower_fs"] = LegacyCheckDefinition( + name="datapower_fs", parse_function=parse_datapower_fs, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/datapower_mem.py b/cmk/base/legacy_checks/datapower_mem.py index 843c31d52ca..2503d791920 100644 --- a/cmk/base/legacy_checks/datapower_mem.py +++ b/cmk/base/legacy_checks/datapower_mem.py @@ -35,6 +35,7 @@ def parse_datapower_mem(string_table: StringTable) -> StringTable: check_info["datapower_mem"] = LegacyCheckDefinition( + name="datapower_mem", parse_function=parse_datapower_mem, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/datapower_temp.py b/cmk/base/legacy_checks/datapower_temp.py index 134bf551814..701a8c59070 100644 --- a/cmk/base/legacy_checks/datapower_temp.py +++ b/cmk/base/legacy_checks/datapower_temp.py @@ -47,6 +47,7 @@ def parse_datapower_temp(string_table: StringTable) -> StringTable: check_info["datapower_temp"] = LegacyCheckDefinition( + name="datapower_temp", parse_function=parse_datapower_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/db2_backup.py b/cmk/base/legacy_checks/db2_backup.py index 8653875ed36..d09d4582e41 100644 --- a/cmk/base/legacy_checks/db2_backup.py +++ b/cmk/base/legacy_checks/db2_backup.py @@ -47,6 +47,7 @@ def check_db2_backup(item, params, parsed): check_info["db2_backup"] = LegacyCheckDefinition( + name="db2_backup", parse_function=parse_db2_dbs, service_name="DB2 Backup %s", discovery_function=inventory_db2_backup, diff --git a/cmk/base/legacy_checks/db2_bp_hitratios.py b/cmk/base/legacy_checks/db2_bp_hitratios.py index 8e838d0f500..330c487bec9 100644 --- a/cmk/base/legacy_checks/db2_bp_hitratios.py +++ b/cmk/base/legacy_checks/db2_bp_hitratios.py @@ -92,6 +92,7 @@ def check_db2_bp_hitratios(item, _no_params, parsed): check_info["db2_bp_hitratios"] = LegacyCheckDefinition( + name="db2_bp_hitratios", parse_function=parse_db2_bp_hitratios, service_name="DB2 BP-Hitratios %s", discovery_function=inventory_db2_bp_hitratios, diff --git a/cmk/base/legacy_checks/db2_connections.py b/cmk/base/legacy_checks/db2_connections.py index 26d67c3fab2..9eb3685034f 100644 --- a/cmk/base/legacy_checks/db2_connections.py +++ b/cmk/base/legacy_checks/db2_connections.py @@ -57,6 +57,7 @@ def check_db2_connections(item, params, parsed): check_info["db2_connections"] = LegacyCheckDefinition( + name="db2_connections", parse_function=parse_db2_dbs, service_name="DB2 Connections %s", discovery_function=inventory_db2_connections, diff --git a/cmk/base/legacy_checks/db2_counters.py b/cmk/base/legacy_checks/db2_counters.py index a8959c20502..0ceaf5dc5e2 100644 --- a/cmk/base/legacy_checks/db2_counters.py +++ b/cmk/base/legacy_checks/db2_counters.py @@ -119,6 +119,7 @@ def check_db2_counters(item, params, parsed): check_info["db2_counters"] = LegacyCheckDefinition( + name="db2_counters", parse_function=parse_db2_counters, service_name="DB2 Counters %s", discovery_function=inventory_db2_counters, diff --git a/cmk/base/legacy_checks/db2_logsizes.py b/cmk/base/legacy_checks/db2_logsizes.py index 0a44d37fccc..a49a3b0159c 100644 --- a/cmk/base/legacy_checks/db2_logsizes.py +++ b/cmk/base/legacy_checks/db2_logsizes.py @@ -94,6 +94,7 @@ def check_db2_logsizes(item, params, parsed): check_info["db2_logsizes"] = LegacyCheckDefinition( + name="db2_logsizes", parse_function=parse_db2_logsizes, service_name="DB2 Logsize %s", discovery_function=inventory_db2_logsizes, diff --git a/cmk/base/legacy_checks/db2_mem.py b/cmk/base/legacy_checks/db2_mem.py index 32fd31801d8..14f29c313e5 100644 --- a/cmk/base/legacy_checks/db2_mem.py +++ b/cmk/base/legacy_checks/db2_mem.py @@ -64,6 +64,7 @@ def parse_db2_mem(string_table: StringTable) -> StringTable: check_info["db2_mem"] = LegacyCheckDefinition( + name="db2_mem", parse_function=parse_db2_mem, service_name="Memory %s", discovery_function=inventory_db2_mem, diff --git a/cmk/base/legacy_checks/db2_sort_overflow.py b/cmk/base/legacy_checks/db2_sort_overflow.py index 9d174b78166..c7473ebf8b0 100644 --- a/cmk/base/legacy_checks/db2_sort_overflow.py +++ b/cmk/base/legacy_checks/db2_sort_overflow.py @@ -33,9 +33,9 @@ def check_db2_sort_overflow(item, params, parsed): overflow_perc = 0.0 warn, crit = params.get("levels_perc") if overflow_perc >= crit: - yield 2, f"{overflow_perc:.1f}% sort overflow (leves at {warn:.1f}%/{crit:.1f}%)" + yield 2, f"{overflow_perc:.1f}% sort overflow (levels at {warn:.1f}%/{crit:.1f}%)" elif overflow_perc >= warn: - yield 1, f"{overflow_perc:.1f}% sort overflow (leves at {warn:.1f}%/{crit:.1f}%)" + yield 1, f"{overflow_perc:.1f}% sort overflow (levels at {warn:.1f}%/{crit:.1f}%)" else: yield 0, "%.1f%% sort overflow" % overflow_perc @@ -44,6 +44,7 @@ def check_db2_sort_overflow(item, params, parsed): check_info["db2_sort_overflow"] = LegacyCheckDefinition( + name="db2_sort_overflow", parse_function=parse_db2_dbs, service_name="DB2 Sort Overflow %s", discovery_function=inventory_db2_sort_overflow, diff --git a/cmk/base/legacy_checks/db2_tablespaces.py b/cmk/base/legacy_checks/db2_tablespaces.py index 8cc2de8a1a5..20c9636d2f8 100644 --- a/cmk/base/legacy_checks/db2_tablespaces.py +++ b/cmk/base/legacy_checks/db2_tablespaces.py @@ -102,6 +102,7 @@ def check_db2_tablespaces(item, params, parsed): check_info["db2_tablespaces"] = LegacyCheckDefinition( + name="db2_tablespaces", parse_function=parse_db2_dbs, service_name="DB2 Tablespace %s", discovery_function=inventory_db2_tablespaces, diff --git a/cmk/base/legacy_checks/ddn_s2a_errors.py b/cmk/base/legacy_checks/ddn_s2a_errors.py index a69f3178b9f..26d104cdee5 100644 --- a/cmk/base/legacy_checks/ddn_s2a_errors.py +++ b/cmk/base/legacy_checks/ddn_s2a_errors.py @@ -100,6 +100,7 @@ def check_errors(value, levels, infotext_formatstring): check_info["ddn_s2a_errors"] = LegacyCheckDefinition( + name="ddn_s2a_errors", parse_function=parse_ddn_s2a_errors, service_name="DDN S2A Port Errors %s", discovery_function=inventory_ddn_s2a_errors, diff --git a/cmk/base/legacy_checks/ddn_s2a_faultsbasic.py b/cmk/base/legacy_checks/ddn_s2a_faultsbasic.py index 28f58f687d6..2da2aff04b6 100644 --- a/cmk/base/legacy_checks/ddn_s2a_faultsbasic.py +++ b/cmk/base/legacy_checks/ddn_s2a_faultsbasic.py @@ -62,6 +62,7 @@ def check_ddn_s2a_faultsbasic_disks(_no_item, params, parsed): check_info["ddn_s2a_faultsbasic.disks"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_disks", service_name="DDN S2A Disks", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_disks, @@ -114,6 +115,7 @@ def check_ddn_s2a_faultsbasic_temp(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.temp"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_temp", service_name="DDN S2A Temperature", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_temp, @@ -147,6 +149,7 @@ def check_ddn_s2a_faultsbasic_ps(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.ps"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_ps", service_name="DDN S2A Power Supplies", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_ps, @@ -185,6 +188,7 @@ def check_ddn_s2a_faultsbasic_fans(_no_item, params, parsed): check_info["ddn_s2a_faultsbasic.fans"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_fans", service_name="DDN S2A Fans", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_fans, @@ -221,6 +225,7 @@ def check_ddn_s2a_faultsbasic_pingfault(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.pingfault"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_pingfault", service_name="DDN S2A Ping Fault Status", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_pingfault, @@ -251,6 +256,7 @@ def check_ddn_s2a_faultsbasic_bootstatus(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.bootstatus"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_bootstatus", service_name="DDN S2A Boot Status", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_bootstatus, @@ -297,6 +303,7 @@ def check_ddn_s2a_faultsbasic_cachecoh(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.cachecoh"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_cachecoh", service_name="DDN S2A Cache Coherency", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_cachecoh, @@ -333,6 +340,7 @@ def check_ddn_s2a_faultsbasic_dualcomm(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.dualcomm"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_dualcomm", service_name="DDN S2A Dual Communication", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_dualcomm, @@ -368,6 +376,7 @@ def check_ddn_s2a_faultsbasic_ethernet(_no_item, _no_params, parsed): check_info["ddn_s2a_faultsbasic.ethernet"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic_ethernet", service_name="DDN S2A Ethernet", sections=["ddn_s2a_faultsbasic"], discovery_function=inventory_ddn_s2a_faultsbasic_ethernet, @@ -405,6 +414,7 @@ def check_ddn_s2a_faultsbasic(item, _no_params, parsed): check_info["ddn_s2a_faultsbasic"] = LegacyCheckDefinition( + name="ddn_s2a_faultsbasic", parse_function=parse_ddn_s2a_faultsbasic, service_name="DDN S2A Unit %s", discovery_function=inventory_ddn_s2a_faultsbasic, diff --git a/cmk/base/legacy_checks/ddn_s2a_stats.py b/cmk/base/legacy_checks/ddn_s2a_stats.py index b0497a417b2..177482c3a61 100644 --- a/cmk/base/legacy_checks/ddn_s2a_stats.py +++ b/cmk/base/legacy_checks/ddn_s2a_stats.py @@ -52,6 +52,7 @@ def check_ddn_s2a_stats_readhits(item, params, parsed): check_info["ddn_s2a_stats.readhits"] = LegacyCheckDefinition( + name="ddn_s2a_stats_readhits", service_name="DDN S2A Read Hits %s", sections=["ddn_s2a_stats"], discovery_function=inventory_ddn_s2a_stats_readhits, @@ -123,6 +124,7 @@ def check_io_levels(value, levels, infotext_formatstring, perfname=None): check_info["ddn_s2a_stats.io"] = LegacyCheckDefinition( + name="ddn_s2a_stats_io", service_name="DDN S2A IO %s", sections=["ddn_s2a_stats"], discovery_function=inventory_ddn_s2a_stats_io, @@ -196,6 +198,7 @@ def check_datarate_levels(value, value_mb, levels, infotext_formatstring, perfna check_info["ddn_s2a_stats"] = LegacyCheckDefinition( + name="ddn_s2a_stats", parse_function=parse_ddn_s2a_stats, service_name="DDN S2A Data Rate %s", discovery_function=inventory_ddn_s2a_stats, diff --git a/cmk/base/legacy_checks/ddn_s2a_statsdelay.py b/cmk/base/legacy_checks/ddn_s2a_statsdelay.py index f0bbf58cd2e..2a5e894d219 100644 --- a/cmk/base/legacy_checks/ddn_s2a_statsdelay.py +++ b/cmk/base/legacy_checks/ddn_s2a_statsdelay.py @@ -155,6 +155,7 @@ def _check_levels(infotext_formatstring, value, levels, perfname): check_info["ddn_s2a_statsdelay"] = LegacyCheckDefinition( + name="ddn_s2a_statsdelay", parse_function=parse_ddn_s2a_statsdelay, service_name="DDN S2A Delay %s", discovery_function=inventory_ddn_s2a_statsdelay, diff --git a/cmk/base/legacy_checks/ddn_s2a_uptime.py b/cmk/base/legacy_checks/ddn_s2a_uptime.py index d7885ed0cc9..1d4c8a862a0 100644 --- a/cmk/base/legacy_checks/ddn_s2a_uptime.py +++ b/cmk/base/legacy_checks/ddn_s2a_uptime.py @@ -31,6 +31,7 @@ def check_ddn_s2a_uptime(_no_item, params, parsed): check_info["ddn_s2a_uptime"] = LegacyCheckDefinition( + name="ddn_s2a_uptime", parse_function=parse_ddn_s2a_uptime, service_name="DDN S2A Power-On Time", # We don't use "Uptime" as a service name here, # because this value is different from the uptime value diff --git a/cmk/base/legacy_checks/ddn_s2a_version.py b/cmk/base/legacy_checks/ddn_s2a_version.py index 83a8871e521..cdf652e05ab 100644 --- a/cmk/base/legacy_checks/ddn_s2a_version.py +++ b/cmk/base/legacy_checks/ddn_s2a_version.py @@ -24,6 +24,7 @@ def check_ddn_s2a_version(_no_item, _no_params, parsed): check_info["ddn_s2a_version"] = LegacyCheckDefinition( + name="ddn_s2a_version", parse_function=parse_ddn_s2a_version, service_name="DDN S2A Version", discovery_function=inventory_ddn_s2a_version, diff --git a/cmk/base/legacy_checks/decru_fans.py b/cmk/base/legacy_checks/decru_fans.py index 21f5d0d2c31..d0e7729c438 100644 --- a/cmk/base/legacy_checks/decru_fans.py +++ b/cmk/base/legacy_checks/decru_fans.py @@ -36,6 +36,7 @@ def check_decru_fans( check_info["decru_fans"] = LegacyCheckDefinition( + name="decru_fans", detect=DETECT_DECRU, fetch=SNMPTree( base=".1.3.6.1.4.1.12962.1.2.3.1", diff --git a/cmk/base/legacy_checks/decru_perf.py b/cmk/base/legacy_checks/decru_perf.py index e37685633a8..c4d647eb604 100644 --- a/cmk/base/legacy_checks/decru_perf.py +++ b/cmk/base/legacy_checks/decru_perf.py @@ -50,6 +50,7 @@ def parse_decru_perf(string_table: StringTable) -> StringTable: check_info["decru_perf"] = LegacyCheckDefinition( + name="decru_perf", parse_function=parse_decru_perf, detect=DETECT_DECRU, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/decru_temps.py b/cmk/base/legacy_checks/decru_temps.py index 2b9208ee305..03b3237818d 100644 --- a/cmk/base/legacy_checks/decru_temps.py +++ b/cmk/base/legacy_checks/decru_temps.py @@ -32,6 +32,7 @@ def parse_decru_temps(string_table: StringTable) -> StringTable: check_info["decru_temps"] = LegacyCheckDefinition( + name="decru_temps", parse_function=parse_decru_temps, detect=DETECT_DECRU, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_chassis_temp.py b/cmk/base/legacy_checks/dell_chassis_temp.py index 69a6ef16f12..877cc94b35a 100644 --- a/cmk/base/legacy_checks/dell_chassis_temp.py +++ b/cmk/base/legacy_checks/dell_chassis_temp.py @@ -40,6 +40,7 @@ def parse_dell_chassis_temp(string_table: StringTable) -> StringTable: check_info["dell_chassis_temp"] = LegacyCheckDefinition( + name="dell_chassis_temp", parse_function=parse_dell_chassis_temp, detect=DETECT_CHASSIS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_compellent_controller.py b/cmk/base/legacy_checks/dell_compellent_controller.py index 302c8e6865f..78e64b0243e 100644 --- a/cmk/base/legacy_checks/dell_compellent_controller.py +++ b/cmk/base/legacy_checks/dell_compellent_controller.py @@ -37,6 +37,7 @@ def parse_dell_compellent_controller(string_table: StringTable) -> StringTable: check_info["dell_compellent_controller"] = LegacyCheckDefinition( + name="dell_compellent_controller", parse_function=parse_dell_compellent_controller, detect=DETECT_DELL_COMPELLENT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_compellent_disks.py b/cmk/base/legacy_checks/dell_compellent_disks.py index 09159e7ad12..9b886d82f91 100644 --- a/cmk/base/legacy_checks/dell_compellent_disks.py +++ b/cmk/base/legacy_checks/dell_compellent_disks.py @@ -62,6 +62,7 @@ def discover_dell_compellent_disks(section): check_info["dell_compellent_disks"] = LegacyCheckDefinition( + name="dell_compellent_disks", detect=DETECT_DELL_COMPELLENT, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/dell_compellent_enclosure.py b/cmk/base/legacy_checks/dell_compellent_enclosure.py index 2b7790f0c73..a11367fc398 100644 --- a/cmk/base/legacy_checks/dell_compellent_enclosure.py +++ b/cmk/base/legacy_checks/dell_compellent_enclosure.py @@ -36,6 +36,7 @@ def parse_dell_compellent_enclosure(string_table: StringTable) -> StringTable: check_info["dell_compellent_enclosure"] = LegacyCheckDefinition( + name="dell_compellent_enclosure", parse_function=parse_dell_compellent_enclosure, detect=DETECT_DELL_COMPELLENT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_compellent_folder.py b/cmk/base/legacy_checks/dell_compellent_folder.py index 37e3e2ce725..9950dde3d0e 100644 --- a/cmk/base/legacy_checks/dell_compellent_folder.py +++ b/cmk/base/legacy_checks/dell_compellent_folder.py @@ -32,6 +32,7 @@ def parse_dell_compellent_folder(string_table: StringTable) -> StringTable: check_info["dell_compellent_folder"] = LegacyCheckDefinition( + name="dell_compellent_folder", parse_function=parse_dell_compellent_folder, detect=DETECT_DELL_COMPELLENT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_idrac_fans.py b/cmk/base/legacy_checks/dell_idrac_fans.py index f4083a2a573..6a7167db8e2 100644 --- a/cmk/base/legacy_checks/dell_idrac_fans.py +++ b/cmk/base/legacy_checks/dell_idrac_fans.py @@ -53,6 +53,7 @@ def parse_dell_idrac_fans(string_table: StringTable) -> StringTable: check_info["dell_idrac_fans"] = LegacyCheckDefinition( + name="dell_idrac_fans", parse_function=parse_dell_idrac_fans, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.674.10892.5"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_om_fans.py b/cmk/base/legacy_checks/dell_om_fans.py index 7ac09bb5a85..2440c65cf59 100644 --- a/cmk/base/legacy_checks/dell_om_fans.py +++ b/cmk/base/legacy_checks/dell_om_fans.py @@ -73,6 +73,7 @@ def parse_dell_om_fans(string_table: StringTable) -> StringTable: check_info["dell_om_fans"] = LegacyCheckDefinition( + name="dell_om_fans", parse_function=parse_dell_om_fans, detect=DETECT_OPENMANAGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_om_sensors.py b/cmk/base/legacy_checks/dell_om_sensors.py index cf1f2f6d872..83ab9ea4a42 100644 --- a/cmk/base/legacy_checks/dell_om_sensors.py +++ b/cmk/base/legacy_checks/dell_om_sensors.py @@ -69,6 +69,7 @@ def parse_dell_om_sensors(string_table: StringTable) -> StringTable: check_info["dell_om_sensors"] = LegacyCheckDefinition( + name="dell_om_sensors", parse_function=parse_dell_om_sensors, detect=DETECT_OPENMANAGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_om_vdisks.py b/cmk/base/legacy_checks/dell_om_vdisks.py index 3294f714447..4b1a20d2443 100644 --- a/cmk/base/legacy_checks/dell_om_vdisks.py +++ b/cmk/base/legacy_checks/dell_om_vdisks.py @@ -51,6 +51,7 @@ def check_dell_om_vdisks(item, params, parsed): check_info["dell_om_vdisks"] = LegacyCheckDefinition( + name="dell_om_vdisks", parse_function=parse_omreport, service_name="Virtual Disk %s", discovery_function=inventory_dell_om_vdisks, diff --git a/cmk/base/legacy_checks/dell_powerconnect_cpu.py b/cmk/base/legacy_checks/dell_powerconnect_cpu.py index 48560f0a18a..4b9d11dc980 100644 --- a/cmk/base/legacy_checks/dell_powerconnect_cpu.py +++ b/cmk/base/legacy_checks/dell_powerconnect_cpu.py @@ -69,6 +69,7 @@ def parse_dell_powerconnect_cpu(string_table: StringTable) -> StringTable: check_info["dell_powerconnect_cpu"] = LegacyCheckDefinition( + name="dell_powerconnect_cpu", parse_function=parse_dell_powerconnect_cpu, detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.674.10895"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_powerconnect_temp.py b/cmk/base/legacy_checks/dell_powerconnect_temp.py index 7760dc8e180..25b9f72ee9a 100644 --- a/cmk/base/legacy_checks/dell_powerconnect_temp.py +++ b/cmk/base/legacy_checks/dell_powerconnect_temp.py @@ -65,6 +65,7 @@ def check_dell_powerconnect_temp(_no_item, params, parsed): check_info["dell_powerconnect_temp"] = LegacyCheckDefinition( + name="dell_powerconnect_temp", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.674.10895"), fetch=SNMPTree( base=".1.3.6.1.4.1.89.53.15.1", diff --git a/cmk/base/legacy_checks/dell_poweredge_amperage.py b/cmk/base/legacy_checks/dell_poweredge_amperage.py index 2d9e59dbf18..66d888405b9 100644 --- a/cmk/base/legacy_checks/dell_poweredge_amperage.py +++ b/cmk/base/legacy_checks/dell_poweredge_amperage.py @@ -33,6 +33,7 @@ def parse_dell_poweredge_amperage(string_table: StringTable) -> StringTable: check_info["dell_poweredge_amperage"] = LegacyCheckDefinition( + name="dell_poweredge_amperage", parse_function=parse_dell_poweredge_amperage, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( @@ -42,6 +43,7 @@ def parse_dell_poweredge_amperage(string_table: StringTable) -> StringTable: ) check_info["dell_poweredge_amperage.power"] = LegacyCheckDefinition( + name="dell_poweredge_amperage_power", service_name="%s", sections=["dell_poweredge_amperage"], discovery_function=inventory_dell_poweredge_amperage_power, @@ -49,6 +51,7 @@ def parse_dell_poweredge_amperage(string_table: StringTable) -> StringTable: ) check_info["dell_poweredge_amperage.current"] = LegacyCheckDefinition( + name="dell_poweredge_amperage_current", service_name="%s", sections=["dell_poweredge_amperage"], discovery_function=inventory_dell_poweredge_amperage_current, diff --git a/cmk/base/legacy_checks/dell_poweredge_cpu.py b/cmk/base/legacy_checks/dell_poweredge_cpu.py index 0a5bf4cdebb..4fd54acc73a 100644 --- a/cmk/base/legacy_checks/dell_poweredge_cpu.py +++ b/cmk/base/legacy_checks/dell_poweredge_cpu.py @@ -25,6 +25,7 @@ def parse_dell_poweredge_cpu(string_table: Sequence[StringTable]) -> Sequence[St check_info["dell_poweredge_cpu"] = LegacyCheckDefinition( + name="dell_poweredge_cpu", parse_function=parse_dell_poweredge_cpu, detect=DETECT_IDRAC_POWEREDGE, fetch=[ diff --git a/cmk/base/legacy_checks/dell_poweredge_mem.py b/cmk/base/legacy_checks/dell_poweredge_mem.py index 20d32d47f2f..f51e98743d7 100644 --- a/cmk/base/legacy_checks/dell_poweredge_mem.py +++ b/cmk/base/legacy_checks/dell_poweredge_mem.py @@ -26,6 +26,7 @@ def parse_dell_poweredge_mem(string_table: StringTable) -> StringTable: check_info["dell_poweredge_mem"] = LegacyCheckDefinition( + name="dell_poweredge_mem", parse_function=parse_dell_poweredge_mem, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_poweredge_netdev.py b/cmk/base/legacy_checks/dell_poweredge_netdev.py index 04a4b1ece85..f7e011e18da 100644 --- a/cmk/base/legacy_checks/dell_poweredge_netdev.py +++ b/cmk/base/legacy_checks/dell_poweredge_netdev.py @@ -25,6 +25,7 @@ def parse_dell_poweredge_netdev(string_table: StringTable) -> StringTable: check_info["dell_poweredge_netdev"] = LegacyCheckDefinition( + name="dell_poweredge_netdev", parse_function=parse_dell_poweredge_netdev, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_poweredge_pci.py b/cmk/base/legacy_checks/dell_poweredge_pci.py index d7cdc82bc0d..01205841660 100644 --- a/cmk/base/legacy_checks/dell_poweredge_pci.py +++ b/cmk/base/legacy_checks/dell_poweredge_pci.py @@ -26,6 +26,7 @@ def parse_dell_poweredge_pci(string_table: StringTable) -> StringTable: check_info["dell_poweredge_pci"] = LegacyCheckDefinition( + name="dell_poweredge_pci", parse_function=parse_dell_poweredge_pci, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_poweredge_status.py b/cmk/base/legacy_checks/dell_poweredge_status.py index 4095b276198..f6c4c2e26dc 100644 --- a/cmk/base/legacy_checks/dell_poweredge_status.py +++ b/cmk/base/legacy_checks/dell_poweredge_status.py @@ -23,6 +23,7 @@ def parse_dell_poweredge_status(string_table: StringTable) -> StringTable: check_info["dell_poweredge_status"] = LegacyCheckDefinition( + name="dell_poweredge_status", parse_function=parse_dell_poweredge_status, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dell_poweredge_temp.py b/cmk/base/legacy_checks/dell_poweredge_temp.py index 835b9d8a321..32da077a5bc 100644 --- a/cmk/base/legacy_checks/dell_poweredge_temp.py +++ b/cmk/base/legacy_checks/dell_poweredge_temp.py @@ -27,6 +27,7 @@ def parse_dell_poweredge_temp(string_table: StringTable) -> StringTable: check_info["dell_poweredge_temp"] = LegacyCheckDefinition( + name="dell_poweredge_temp", parse_function=parse_dell_poweredge_temp, detect=DETECT_IDRAC_POWEREDGE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/didactum_can_sensors_analog.py b/cmk/base/legacy_checks/didactum_can_sensors_analog.py index b67864b9353..85ae24f4b29 100644 --- a/cmk/base/legacy_checks/didactum_can_sensors_analog.py +++ b/cmk/base/legacy_checks/didactum_can_sensors_analog.py @@ -37,6 +37,7 @@ def inventory_didactum_can_sensors_analog_temp(parsed): check_info["didactum_can_sensors_analog"] = LegacyCheckDefinition( + name="didactum_can_sensors_analog", detect=DETECT_DIDACTUM, fetch=SNMPTree( base=".1.3.6.1.4.1.46501.6.2.1", @@ -65,6 +66,7 @@ def inventory_didactum_can_sensors_analog_humid(parsed): check_info["didactum_can_sensors_analog.humidity"] = LegacyCheckDefinition( + name="didactum_can_sensors_analog_humidity", service_name="Humidity CAN %s", sections=["didactum_can_sensors_analog"], discovery_function=inventory_didactum_can_sensors_analog_humid, @@ -88,6 +90,7 @@ def inventory_didactum_can_sensors_analog_volt(parsed): check_info["didactum_can_sensors_analog.voltage"] = LegacyCheckDefinition( + name="didactum_can_sensors_analog_voltage", service_name="Phase CAN %s", sections=["didactum_can_sensors_analog"], discovery_function=inventory_didactum_can_sensors_analog_volt, diff --git a/cmk/base/legacy_checks/didactum_sensors_analog.py b/cmk/base/legacy_checks/didactum_sensors_analog.py index 0c8a6f81321..1c38da88834 100644 --- a/cmk/base/legacy_checks/didactum_sensors_analog.py +++ b/cmk/base/legacy_checks/didactum_sensors_analog.py @@ -62,6 +62,7 @@ def inventory_didactum_sensors_analog_temp(parsed): check_info["didactum_sensors_analog"] = LegacyCheckDefinition( + name="didactum_sensors_analog", detect=DETECT_DIDACTUM, fetch=SNMPTree( base=".1.3.6.1.4.1.46501.5.2.1", @@ -90,6 +91,7 @@ def inventory_didactum_sensors_analog_humid(parsed): check_info["didactum_sensors_analog.humidity"] = LegacyCheckDefinition( + name="didactum_sensors_analog_humidity", service_name="Humidity %s", sections=["didactum_sensors_analog"], discovery_function=inventory_didactum_sensors_analog_humid, @@ -113,6 +115,7 @@ def inventory_didactum_sensors_analog_volt(parsed): check_info["didactum_sensors_analog.voltage"] = LegacyCheckDefinition( + name="didactum_sensors_analog_voltage", service_name="Phase %s", sections=["didactum_sensors_analog"], discovery_function=inventory_didactum_sensors_analog_volt, diff --git a/cmk/base/legacy_checks/didactum_sensors_discrete.py b/cmk/base/legacy_checks/didactum_sensors_discrete.py index 241cdc0ed08..490d599abe6 100644 --- a/cmk/base/legacy_checks/didactum_sensors_discrete.py +++ b/cmk/base/legacy_checks/didactum_sensors_discrete.py @@ -48,6 +48,7 @@ def check_didactum_sensors_discrete_dry(item, params, parsed): check_info["didactum_sensors_discrete"] = LegacyCheckDefinition( + name="didactum_sensors_discrete", detect=DETECT_DIDACTUM, fetch=SNMPTree( base=".1.3.6.1.4.1.46501.5.1.1", diff --git a/cmk/base/legacy_checks/didactum_sensors_outlet.py b/cmk/base/legacy_checks/didactum_sensors_outlet.py index d2d823f1bab..f95b27311e3 100644 --- a/cmk/base/legacy_checks/didactum_sensors_outlet.py +++ b/cmk/base/legacy_checks/didactum_sensors_outlet.py @@ -27,6 +27,7 @@ def check_didactum_sensors_outlet_relay(item, params, parsed): check_info["didactum_sensors_outlet"] = LegacyCheckDefinition( + name="didactum_sensors_outlet", detect=DETECT_DIDACTUM, fetch=SNMPTree( base=".1.3.6.1.4.1.46501.5.3.1", diff --git a/cmk/base/legacy_checks/docker_node_disk_usage.py b/cmk/base/legacy_checks/docker_node_disk_usage.py index 13f0f9c992b..fec5d1a08ed 100644 --- a/cmk/base/legacy_checks/docker_node_disk_usage.py +++ b/cmk/base/legacy_checks/docker_node_disk_usage.py @@ -48,6 +48,7 @@ def discover_docker_node_disk_usage(section): check_info["docker_node_disk_usage"] = LegacyCheckDefinition( + name="docker_node_disk_usage", parse_function=parse_docker_node_disk_usage, service_name="Docker disk usage - %s", discovery_function=discover_docker_node_disk_usage, diff --git a/cmk/base/legacy_checks/docker_node_info.py b/cmk/base/legacy_checks/docker_node_info.py index 36ae995155d..8c933db222e 100644 --- a/cmk/base/legacy_checks/docker_node_info.py +++ b/cmk/base/legacy_checks/docker_node_info.py @@ -27,6 +27,7 @@ def check_docker_node_info(_no_item, _no_params, parsed): check_info["docker_node_info"] = LegacyCheckDefinition( + name="docker_node_info", service_name="Docker node info", discovery_function=discover_docker_node_info, check_function=check_docker_node_info, @@ -61,6 +62,7 @@ def check_docker_node_containers(_no_item, params, parsed): check_info["docker_node_info.containers"] = LegacyCheckDefinition( + name="docker_node_info_containers", service_name="Docker containers", sections=["docker_node_info"], discovery_function=discover_docker_node_info, diff --git a/cmk/base/legacy_checks/docsis_channels_downstream.py b/cmk/base/legacy_checks/docsis_channels_downstream.py index 5af4f0e01ff..54192ca47ba 100644 --- a/cmk/base/legacy_checks/docsis_channels_downstream.py +++ b/cmk/base/legacy_checks/docsis_channels_downstream.py @@ -60,6 +60,7 @@ def parse_docsis_channels_downstream(string_table: StringTable) -> StringTable: check_info["docsis_channels_downstream"] = LegacyCheckDefinition( + name="docsis_channels_downstream", parse_function=parse_docsis_channels_downstream, detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4115.820.1.0.0.0.0.0"), diff --git a/cmk/base/legacy_checks/docsis_channels_upstream.py b/cmk/base/legacy_checks/docsis_channels_upstream.py index 95ddf05164b..18454a92e07 100644 --- a/cmk/base/legacy_checks/docsis_channels_upstream.py +++ b/cmk/base/legacy_checks/docsis_channels_upstream.py @@ -161,6 +161,7 @@ def check_docsis_channels_upstream(item, params, parsed): check_info["docsis_channels_upstream"] = LegacyCheckDefinition( + name="docsis_channels_upstream", detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4115.820.1.0.0.0.0.0"), equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4115.900.2.0.0.0.0.0"), diff --git a/cmk/base/legacy_checks/docsis_cm_status.py b/cmk/base/legacy_checks/docsis_cm_status.py index 52d628ce3d5..eb9213e2cb0 100644 --- a/cmk/base/legacy_checks/docsis_cm_status.py +++ b/cmk/base/legacy_checks/docsis_cm_status.py @@ -83,6 +83,7 @@ def parse_docsis_cm_status(string_table: StringTable) -> StringTable: check_info["docsis_cm_status"] = LegacyCheckDefinition( + name="docsis_cm_status", parse_function=parse_docsis_cm_status, detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.4115.820.1.0.0.0.0.0"), diff --git a/cmk/base/legacy_checks/domino_mailqueues.py b/cmk/base/legacy_checks/domino_mailqueues.py index afd5c8497e2..17ef8f1c0c5 100644 --- a/cmk/base/legacy_checks/domino_mailqueues.py +++ b/cmk/base/legacy_checks/domino_mailqueues.py @@ -47,6 +47,7 @@ def discover_domino_mailqueues(section): check_info["domino_mailqueues"] = LegacyCheckDefinition( + name="domino_mailqueues", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.334.72.1.1.4", diff --git a/cmk/base/legacy_checks/domino_transactions.py b/cmk/base/legacy_checks/domino_transactions.py index 63dccc170a9..ef9c254ce57 100644 --- a/cmk/base/legacy_checks/domino_transactions.py +++ b/cmk/base/legacy_checks/domino_transactions.py @@ -32,6 +32,7 @@ def parse_domino_transactions(string_table: StringTable) -> StringTable: check_info["domino_transactions"] = LegacyCheckDefinition( + name="domino_transactions", parse_function=parse_domino_transactions, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/domino_users.py b/cmk/base/legacy_checks/domino_users.py index 1cbc6ea1d4c..f942357a20f 100644 --- a/cmk/base/legacy_checks/domino_users.py +++ b/cmk/base/legacy_checks/domino_users.py @@ -32,6 +32,7 @@ def parse_domino_users(string_table: StringTable) -> StringTable: check_info["domino_users"] = LegacyCheckDefinition( + name="domino_users", parse_function=parse_domino_users, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/dotnet_clrmemory.py b/cmk/base/legacy_checks/dotnet_clrmemory.py index 2dd8c9fe255..799f1e881d6 100644 --- a/cmk/base/legacy_checks/dotnet_clrmemory.py +++ b/cmk/base/legacy_checks/dotnet_clrmemory.py @@ -33,6 +33,7 @@ def discover_dotnet_clrmemory(parsed): check_info["dotnet_clrmemory"] = LegacyCheckDefinition( + name="dotnet_clrmemory", parse_function=parse_wmi_table, service_name="DotNet Memory Management %s", discovery_function=discover_dotnet_clrmemory, diff --git a/cmk/base/legacy_checks/drbd.py b/cmk/base/legacy_checks/drbd.py index 0225468c93f..c2e11865dfa 100644 --- a/cmk/base/legacy_checks/drbd.py +++ b/cmk/base/legacy_checks/drbd.py @@ -346,6 +346,7 @@ def discover_drbd(info): check_info["drbd"] = LegacyCheckDefinition( + name="drbd", parse_function=parse_drbd, service_name="DRBD %s status", discovery_function=discover_drbd, @@ -389,6 +390,7 @@ def discover_drbd_net(info): check_info["drbd.net"] = LegacyCheckDefinition( + name="drbd_net", service_name="DRBD %s net", sections=["drbd"], discovery_function=discover_drbd_net, @@ -418,6 +420,7 @@ def discover_drbd_disk(info): check_info["drbd.disk"] = LegacyCheckDefinition( + name="drbd_disk", service_name="DRBD %s disk", sections=["drbd"], discovery_function=discover_drbd_disk, @@ -459,6 +462,7 @@ def discover_drbd_stats(info): check_info["drbd.stats"] = LegacyCheckDefinition( + name="drbd_stats", service_name="DRBD %s stats", sections=["drbd"], discovery_function=discover_drbd_stats, diff --git a/cmk/base/legacy_checks/elasticsearch_cluster_health.py b/cmk/base/legacy_checks/elasticsearch_cluster_health.py index 197b5a01412..69a91b6a842 100644 --- a/cmk/base/legacy_checks/elasticsearch_cluster_health.py +++ b/cmk/base/legacy_checks/elasticsearch_cluster_health.py @@ -116,6 +116,7 @@ def check_elasticsearch_cluster_health(_no_item, params, parsed): check_info["elasticsearch_cluster_health"] = LegacyCheckDefinition( + name="elasticsearch_cluster_health", parse_function=parse_elasticsearch_cluster_health, service_name="Elasticsearch Cluster Health", discovery_function=inventory_elasticsearch_cluster_health, @@ -160,6 +161,7 @@ def check_elasticsearch_cluster_health_shards(_no_item, params, parsed): check_info["elasticsearch_cluster_health.shards"] = LegacyCheckDefinition( + name="elasticsearch_cluster_health_shards", service_name="Elasticsearch Cluster Shards", sections=["elasticsearch_cluster_health"], discovery_function=inventory_elasticsearch_cluster_health, @@ -189,6 +191,7 @@ def check_elasticsearch_cluster_health_tasks(_no_item, params, parsed): check_info["elasticsearch_cluster_health.tasks"] = LegacyCheckDefinition( + name="elasticsearch_cluster_health_tasks", service_name="Elasticsearch Cluster Tasks", sections=["elasticsearch_cluster_health"], discovery_function=inventory_elasticsearch_cluster_health, diff --git a/cmk/base/legacy_checks/elasticsearch_nodes.py b/cmk/base/legacy_checks/elasticsearch_nodes.py index 5a47d97d294..8f03e2cb8ae 100644 --- a/cmk/base/legacy_checks/elasticsearch_nodes.py +++ b/cmk/base/legacy_checks/elasticsearch_nodes.py @@ -73,6 +73,7 @@ def discover_elasticsearch_nodes(section): check_info["elasticsearch_nodes"] = LegacyCheckDefinition( + name="elasticsearch_nodes", parse_function=parse_elasticsearch_nodes, service_name="Elasticsearch Node %s", discovery_function=discover_elasticsearch_nodes, diff --git a/cmk/base/legacy_checks/eltek_battery.py b/cmk/base/legacy_checks/eltek_battery.py index cac10c06060..3780fe66e46 100644 --- a/cmk/base/legacy_checks/eltek_battery.py +++ b/cmk/base/legacy_checks/eltek_battery.py @@ -63,6 +63,7 @@ def check_eltek_battery(_no_item, _no_params, parsed): check_info["eltek_battery"] = LegacyCheckDefinition( + name="eltek_battery", detect=DETECT_ELTEK, fetch=SNMPTree( base=".1.3.6.1.4.1.12148.9.3", @@ -101,6 +102,7 @@ def check_eltek_battery_temp(item, params, parsed): check_info["eltek_battery.temp"] = LegacyCheckDefinition( + name="eltek_battery_temp", service_name="Temperature %s", sections=["eltek_battery"], discovery_function=inventory_eltek_battery_temp, @@ -131,6 +133,7 @@ def check_eltek_battery_supply(item, params, parsed): check_info["eltek_battery.supply"] = LegacyCheckDefinition( + name="eltek_battery_supply", service_name="Battery %s", sections=["eltek_battery"], discovery_function=discover_eltek_battery_supply, diff --git a/cmk/base/legacy_checks/eltek_fans.py b/cmk/base/legacy_checks/eltek_fans.py index dfd699f407a..f2e64133f8d 100644 --- a/cmk/base/legacy_checks/eltek_fans.py +++ b/cmk/base/legacy_checks/eltek_fans.py @@ -100,6 +100,7 @@ def parse_eltek_fans(string_table: StringTable) -> StringTable: check_info["eltek_fans"] = LegacyCheckDefinition( + name="eltek_fans", parse_function=parse_eltek_fans, detect=DETECT_ELTEK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/eltek_outdoor_temp.py b/cmk/base/legacy_checks/eltek_outdoor_temp.py index 364c863fd1a..3d102c789da 100644 --- a/cmk/base/legacy_checks/eltek_outdoor_temp.py +++ b/cmk/base/legacy_checks/eltek_outdoor_temp.py @@ -82,6 +82,7 @@ def parse_eltek_outdoor_temp(string_table: StringTable) -> StringTable: check_info["eltek_outdoor_temp"] = LegacyCheckDefinition( + name="eltek_outdoor_temp", parse_function=parse_eltek_outdoor_temp, detect=DETECT_ELTEK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/eltek_systemstatus.py b/cmk/base/legacy_checks/eltek_systemstatus.py index e5720d1df0a..7e5c4075dbd 100644 --- a/cmk/base/legacy_checks/eltek_systemstatus.py +++ b/cmk/base/legacy_checks/eltek_systemstatus.py @@ -33,6 +33,7 @@ def parse_eltek_systemstatus(string_table: StringTable) -> StringTable | None: check_info["eltek_systemstatus"] = LegacyCheckDefinition( + name="eltek_systemstatus", parse_function=parse_eltek_systemstatus, detect=DETECT_ELTEK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_datadomain_disks.py b/cmk/base/legacy_checks/emc_datadomain_disks.py index b58e05d27df..8d077400278 100644 --- a/cmk/base/legacy_checks/emc_datadomain_disks.py +++ b/cmk/base/legacy_checks/emc_datadomain_disks.py @@ -62,6 +62,7 @@ def parse_emc_datadomain_disks(string_table: Sequence[StringTable]) -> Sequence[ check_info["emc_datadomain_disks"] = LegacyCheckDefinition( + name="emc_datadomain_disks", parse_function=parse_emc_datadomain_disks, detect=DETECT_DATADOMAIN, fetch=[ diff --git a/cmk/base/legacy_checks/emc_datadomain_fans.py b/cmk/base/legacy_checks/emc_datadomain_fans.py index dab91fc45ad..9be8ceeb0c3 100644 --- a/cmk/base/legacy_checks/emc_datadomain_fans.py +++ b/cmk/base/legacy_checks/emc_datadomain_fans.py @@ -44,6 +44,7 @@ def parse_emc_datadomain_fans(string_table: StringTable) -> StringTable: check_info["emc_datadomain_fans"] = LegacyCheckDefinition( + name="emc_datadomain_fans", parse_function=parse_emc_datadomain_fans, detect=DETECT_DATADOMAIN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_datadomain_fs.py b/cmk/base/legacy_checks/emc_datadomain_fs.py index 756990bce6a..b6db6d1620f 100644 --- a/cmk/base/legacy_checks/emc_datadomain_fs.py +++ b/cmk/base/legacy_checks/emc_datadomain_fs.py @@ -37,6 +37,7 @@ def parse_emc_datadomain_fs(string_table: StringTable) -> StringTable: check_info["emc_datadomain_fs"] = LegacyCheckDefinition( + name="emc_datadomain_fs", parse_function=parse_emc_datadomain_fs, detect=DETECT_DATADOMAIN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_datadomain_mtree.py b/cmk/base/legacy_checks/emc_datadomain_mtree.py index 0251f4c7f4d..11962a90372 100644 --- a/cmk/base/legacy_checks/emc_datadomain_mtree.py +++ b/cmk/base/legacy_checks/emc_datadomain_mtree.py @@ -47,6 +47,7 @@ def discover_emc_datadomain_mtree(section): check_info["emc_datadomain_mtree"] = LegacyCheckDefinition( + name="emc_datadomain_mtree", detect=DETECT_DATADOMAIN, fetch=SNMPTree( base=".1.3.6.1.4.1.19746.1.15.2.1.1", diff --git a/cmk/base/legacy_checks/emc_datadomain_nvbat.py b/cmk/base/legacy_checks/emc_datadomain_nvbat.py index a111b438aa3..a072219eacb 100644 --- a/cmk/base/legacy_checks/emc_datadomain_nvbat.py +++ b/cmk/base/legacy_checks/emc_datadomain_nvbat.py @@ -43,6 +43,7 @@ def parse_emc_datadomain_nvbat(string_table: StringTable) -> StringTable: check_info["emc_datadomain_nvbat"] = LegacyCheckDefinition( + name="emc_datadomain_nvbat", parse_function=parse_emc_datadomain_nvbat, detect=DETECT_DATADOMAIN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_datadomain_power.py b/cmk/base/legacy_checks/emc_datadomain_power.py index 1917b881a19..43f13fd96a0 100644 --- a/cmk/base/legacy_checks/emc_datadomain_power.py +++ b/cmk/base/legacy_checks/emc_datadomain_power.py @@ -44,6 +44,7 @@ def parse_emc_datadomain_power(string_table: StringTable) -> StringTable: check_info["emc_datadomain_power"] = LegacyCheckDefinition( + name="emc_datadomain_power", parse_function=parse_emc_datadomain_power, detect=DETECT_DATADOMAIN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_datadomain_temps.py b/cmk/base/legacy_checks/emc_datadomain_temps.py index c9eda6dffd9..ae3c2057f61 100644 --- a/cmk/base/legacy_checks/emc_datadomain_temps.py +++ b/cmk/base/legacy_checks/emc_datadomain_temps.py @@ -51,6 +51,7 @@ def parse_emc_datadomain_temps(string_table: StringTable) -> StringTable: check_info["emc_datadomain_temps"] = LegacyCheckDefinition( + name="emc_datadomain_temps", parse_function=parse_emc_datadomain_temps, detect=DETECT_DATADOMAIN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_isilon.py b/cmk/base/legacy_checks/emc_isilon.py index fe74c016a69..3ecefb5b2b2 100644 --- a/cmk/base/legacy_checks/emc_isilon.py +++ b/cmk/base/legacy_checks/emc_isilon.py @@ -18,6 +18,7 @@ def parse_emc_isilon(string_table: Sequence[StringTable]) -> Sequence[StringTabl check_info["emc_isilon"] = LegacyCheckDefinition( + name="emc_isilon", parse_function=parse_emc_isilon, detect=DETECT_ISILON, fetch=[ @@ -54,6 +55,7 @@ def check_emc_isilon_clusterhealth(item, _no_params, info): check_info["emc_isilon.clusterhealth"] = LegacyCheckDefinition( + name="emc_isilon_clusterhealth", service_name="Cluster Health", sections=["emc_isilon"], discovery_function=inventory_emc_isilon_clusterhealth, @@ -83,6 +85,7 @@ def check_emc_isilon_nodehealth(item, _no_params, info): check_info["emc_isilon.nodehealth"] = LegacyCheckDefinition( + name="emc_isilon_nodehealth", service_name="Node Health", sections=["emc_isilon"], discovery_function=inventory_emc_isilon_nodehealth, @@ -107,6 +110,7 @@ def check_emc_isilon_nodes(item, _no_params, info): check_info["emc_isilon.nodes"] = LegacyCheckDefinition( + name="emc_isilon_nodes", service_name="Nodes", sections=["emc_isilon"], discovery_function=inventory_emc_isilon_nodes, @@ -126,6 +130,7 @@ def check_emc_isilon_names(item, _no_params, info): check_info["emc_isilon.names"] = LegacyCheckDefinition( + name="emc_isilon_names", service_name="Isilon Info", sections=["emc_isilon"], discovery_function=inventory_emc_isilon_names, diff --git a/cmk/base/legacy_checks/emc_isilon_cpu.py b/cmk/base/legacy_checks/emc_isilon_cpu.py index ca24bbdab87..b8f234e05f7 100644 --- a/cmk/base/legacy_checks/emc_isilon_cpu.py +++ b/cmk/base/legacy_checks/emc_isilon_cpu.py @@ -54,6 +54,7 @@ def parse_emc_isilon_cpu(string_table: StringTable) -> StringTable | None: check_info["emc_isilon_cpu"] = LegacyCheckDefinition( + name="emc_isilon_cpu", parse_function=parse_emc_isilon_cpu, detect=DETECT_ISILON, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_isilon_diskstatus.py b/cmk/base/legacy_checks/emc_isilon_diskstatus.py index 396a08b987c..1bcb367799b 100644 --- a/cmk/base/legacy_checks/emc_isilon_diskstatus.py +++ b/cmk/base/legacy_checks/emc_isilon_diskstatus.py @@ -33,6 +33,7 @@ def parse_emc_isilon_diskstatus(string_table: StringTable) -> StringTable: check_info["emc_isilon_diskstatus"] = LegacyCheckDefinition( + name="emc_isilon_diskstatus", parse_function=parse_emc_isilon_diskstatus, detect=DETECT_ISILON, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_isilon_fans.py b/cmk/base/legacy_checks/emc_isilon_fans.py index 136c7458d56..4882fe1c5c5 100644 --- a/cmk/base/legacy_checks/emc_isilon_fans.py +++ b/cmk/base/legacy_checks/emc_isilon_fans.py @@ -39,6 +39,7 @@ def parse_emc_isilon_fans(string_table: StringTable) -> StringTable: check_info["emc_isilon_fans"] = LegacyCheckDefinition( + name="emc_isilon_fans", parse_function=parse_emc_isilon_fans, detect=DETECT_ISILON, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_isilon_ifs.py b/cmk/base/legacy_checks/emc_isilon_ifs.py index c049af23df8..797f3abe4e3 100644 --- a/cmk/base/legacy_checks/emc_isilon_ifs.py +++ b/cmk/base/legacy_checks/emc_isilon_ifs.py @@ -22,6 +22,7 @@ def check_emc_isilon_ifs(item: str, params: Mapping[str, Any], section: FSBlock) check_info["emc_isilon_ifs"] = LegacyCheckDefinition( + name="emc_isilon_ifs", service_name="Filesystem %s", # section already migrated discovery_function=inventory_emc_isilon_ifs, diff --git a/cmk/base/legacy_checks/emc_isilon_power.py b/cmk/base/legacy_checks/emc_isilon_power.py index 7aa44c3f267..6036108f697 100644 --- a/cmk/base/legacy_checks/emc_isilon_power.py +++ b/cmk/base/legacy_checks/emc_isilon_power.py @@ -52,6 +52,7 @@ def parse_emc_isilon_power(string_table: StringTable) -> StringTable: check_info["emc_isilon_power"] = LegacyCheckDefinition( + name="emc_isilon_power", parse_function=parse_emc_isilon_power, detect=DETECT_ISILON, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emc_isilon_temp.py b/cmk/base/legacy_checks/emc_isilon_temp.py index 2ed6b9ee8ab..29a3f4838db 100644 --- a/cmk/base/legacy_checks/emc_isilon_temp.py +++ b/cmk/base/legacy_checks/emc_isilon_temp.py @@ -65,6 +65,7 @@ def discover_emc_isilon_temp(info): check_info["emc_isilon_temp"] = LegacyCheckDefinition( + name="emc_isilon_temp", parse_function=parse_emc_isilon_temp, detect=DETECT_ISILON, fetch=SNMPTree( @@ -102,6 +103,7 @@ def discover_emc_isilon_temp_cpu(info): # '----------------------------------------------------------------------' check_info["emc_isilon_temp.cpu"] = LegacyCheckDefinition( + name="emc_isilon_temp_cpu", service_name="Temperature %s", sections=["emc_isilon_temp"], discovery_function=discover_emc_isilon_temp_cpu, diff --git a/cmk/base/legacy_checks/emc_vplex_cpu.py b/cmk/base/legacy_checks/emc_vplex_cpu.py index f8567f3d6f9..284112a7e3e 100644 --- a/cmk/base/legacy_checks/emc_vplex_cpu.py +++ b/cmk/base/legacy_checks/emc_vplex_cpu.py @@ -30,6 +30,7 @@ def check_emc_vplex_cpu( check_info["emc_vplex_cpu"] = LegacyCheckDefinition( + name="emc_vplex_cpu", detect=DETECT_VPLEX, fetch=SNMPTree( base=".1.3.6.1.4.1.1139.21.2.2", diff --git a/cmk/base/legacy_checks/emcvnx_agent.py b/cmk/base/legacy_checks/emcvnx_agent.py index 4773bf0d903..cf98f1daec1 100644 --- a/cmk/base/legacy_checks/emcvnx_agent.py +++ b/cmk/base/legacy_checks/emcvnx_agent.py @@ -33,6 +33,7 @@ def check_emcvnx_agent(item, _no_params, parsed): check_info["emcvnx_agent"] = LegacyCheckDefinition( + name="emcvnx_agent", parse_function=parse_emcvnx_agent, service_name="EMC VNX Agent", discovery_function=inventory_emcvnx_agent, diff --git a/cmk/base/legacy_checks/emcvnx_disks.py b/cmk/base/legacy_checks/emcvnx_disks.py index b49975d1a94..edbe6140312 100644 --- a/cmk/base/legacy_checks/emcvnx_disks.py +++ b/cmk/base/legacy_checks/emcvnx_disks.py @@ -196,6 +196,7 @@ def check_emcvnx_disks(item, params, parsed): check_info["emcvnx_disks"] = LegacyCheckDefinition( + name="emcvnx_disks", parse_function=parse_emcvnx_disks, service_name="Enclosure %s", discovery_function=inventory_emcvnx_disks, diff --git a/cmk/base/legacy_checks/emcvnx_hba.py b/cmk/base/legacy_checks/emcvnx_hba.py index d853ff1a2ff..1d11720e92d 100644 --- a/cmk/base/legacy_checks/emcvnx_hba.py +++ b/cmk/base/legacy_checks/emcvnx_hba.py @@ -132,6 +132,7 @@ def check_emcvnx_hba(item, _no_params, parsed): check_info["emcvnx_hba"] = LegacyCheckDefinition( + name="emcvnx_hba", parse_function=parse_emcvnx_hba, service_name="HBA %s", discovery_function=inventory_emcvnx_hba, diff --git a/cmk/base/legacy_checks/emcvnx_hwstatus.py b/cmk/base/legacy_checks/emcvnx_hwstatus.py index 2c64b17340a..4607d59290d 100644 --- a/cmk/base/legacy_checks/emcvnx_hwstatus.py +++ b/cmk/base/legacy_checks/emcvnx_hwstatus.py @@ -126,6 +126,7 @@ def check_emcvnx_hwstatus(item, _no_params, section): check_info["emcvnx_hwstatus"] = LegacyCheckDefinition( + name="emcvnx_hwstatus", service_name="Enclosure %s", # Example for Item: "0/1 Power A", parse_function=parse_emcvnx_hwstatus, discovery_function=inventory_emcvnx_hwstatus, diff --git a/cmk/base/legacy_checks/emcvnx_info.py b/cmk/base/legacy_checks/emcvnx_info.py index e1161f2a93d..6ec894b28e8 100644 --- a/cmk/base/legacy_checks/emcvnx_info.py +++ b/cmk/base/legacy_checks/emcvnx_info.py @@ -148,6 +148,7 @@ def discover_emcvnx_info(x): check_info["emcvnx_info"] = LegacyCheckDefinition( + name="emcvnx_info", parse_function=parse_emcvnx_info, service_name="EMC VNX Info", discovery_function=discover_emcvnx_info, @@ -175,6 +176,7 @@ def discover_emcvnx_info_storage(x): check_info["emcvnx_info.storage"] = LegacyCheckDefinition( + name="emcvnx_info_storage", service_name="EMC VNX Storage Processor", sections=["emcvnx_info"], discovery_function=discover_emcvnx_info_storage, @@ -205,6 +207,7 @@ def discover_emcvnx_info_link(x): check_info["emcvnx_info.link"] = LegacyCheckDefinition( + name="emcvnx_info_link", service_name="EMC VNX Link", sections=["emcvnx_info"], discovery_function=discover_emcvnx_info_link, @@ -232,6 +235,7 @@ def discover_emcvnx_info_config(x): check_info["emcvnx_info.config"] = LegacyCheckDefinition( + name="emcvnx_info_config", service_name="EMC VNX Config", sections=["emcvnx_info"], discovery_function=discover_emcvnx_info_config, @@ -262,6 +266,7 @@ def discover_emcvnx_info_io(x): check_info["emcvnx_info.io"] = LegacyCheckDefinition( + name="emcvnx_info_io", service_name="EMC VNX IO", sections=["emcvnx_info"], discovery_function=discover_emcvnx_info_io, diff --git a/cmk/base/legacy_checks/emcvnx_mirrorview.py b/cmk/base/legacy_checks/emcvnx_mirrorview.py index 140d7430300..b3485f219fd 100644 --- a/cmk/base/legacy_checks/emcvnx_mirrorview.py +++ b/cmk/base/legacy_checks/emcvnx_mirrorview.py @@ -135,6 +135,7 @@ def check_emcvnx_mirrorview(item, params, parsed): check_info["emcvnx_mirrorview"] = LegacyCheckDefinition( + name="emcvnx_mirrorview", parse_function=parse_emcvnx_mirrorview, service_name="Mirror view %s", discovery_function=inventory_emcvnx_mirrorview, diff --git a/cmk/base/legacy_checks/emcvnx_raidgroups.py b/cmk/base/legacy_checks/emcvnx_raidgroups.py index ddb833e5fcc..9dc2d110f88 100644 --- a/cmk/base/legacy_checks/emcvnx_raidgroups.py +++ b/cmk/base/legacy_checks/emcvnx_raidgroups.py @@ -112,6 +112,7 @@ def parse_emcvnx_raidgroups(info): check_info["emcvnx_raidgroups"] = LegacyCheckDefinition( + name="emcvnx_raidgroups", parse_function=parse_emcvnx_raidgroups, ) @@ -140,6 +141,7 @@ def check_emcvnx_raidgroups_list_luns(item, _no_params, section): check_info["emcvnx_raidgroups.list_luns"] = LegacyCheckDefinition( + name="emcvnx_raidgroups_list_luns", service_name="RAID Group %s LUNs", sections=["emcvnx_raidgroups"], discovery_function=inventory_emcvnx_raidgroups, @@ -177,6 +179,7 @@ def check_emcvnx_raidgroups_list_disks(item, _no_params, section): check_info["emcvnx_raidgroups.list_disks"] = LegacyCheckDefinition( + name="emcvnx_raidgroups_list_disks", service_name="RAID Group %s Disks", sections=["emcvnx_raidgroups"], discovery_function=inventory_emcvnx_raidgroups, @@ -230,6 +233,7 @@ def check_emcvnx_raidgroups_capacity(item, params, section): check_info["emcvnx_raidgroups.capacity"] = LegacyCheckDefinition( + name="emcvnx_raidgroups_capacity", service_name="RAID Group %s Capacity", sections=["emcvnx_raidgroups"], discovery_function=inventory_emcvnx_raidgroups_capacity, @@ -283,6 +287,7 @@ def check_emcvnx_raidgroups_capacity_contiguous(item, params, section): check_info["emcvnx_raidgroups.capacity_contiguous"] = LegacyCheckDefinition( + name="emcvnx_raidgroups_capacity_contiguous", service_name="RAID Group %s Capacity Contiguous", sections=["emcvnx_raidgroups"], discovery_function=inventory_emcvnx_raidgroups_capacity_contiguous, diff --git a/cmk/base/legacy_checks/emcvnx_sp_util.py b/cmk/base/legacy_checks/emcvnx_sp_util.py index 4a94df21a4e..79abc28dfc9 100644 --- a/cmk/base/legacy_checks/emcvnx_sp_util.py +++ b/cmk/base/legacy_checks/emcvnx_sp_util.py @@ -63,6 +63,7 @@ def check_emcvnx_sp_util(item, params, parsed): check_info["emcvnx_sp_util"] = LegacyCheckDefinition( + name="emcvnx_sp_util", parse_function=parse_emcvnx_sp_util, service_name="Storage Processor Utilization", discovery_function=inventory_emcvnx_sp_util, diff --git a/cmk/base/legacy_checks/emcvnx_storage_pools.py b/cmk/base/legacy_checks/emcvnx_storage_pools.py index 4c829b757a7..730ee495b6c 100644 --- a/cmk/base/legacy_checks/emcvnx_storage_pools.py +++ b/cmk/base/legacy_checks/emcvnx_storage_pools.py @@ -142,6 +142,7 @@ def check_emcvnx_storage_pools(item, params, parsed): check_info["emcvnx_storage_pools"] = LegacyCheckDefinition( + name="emcvnx_storage_pools", parse_function=parse_emcvnx_storage_pools, service_name="Pool %s General", discovery_function=inventory_emcvnx_storage_pools, @@ -234,6 +235,7 @@ def check_emcvnx_storage_pools_tiering(item, params, parsed): check_info["emcvnx_storage_pools.tiering"] = LegacyCheckDefinition( + name="emcvnx_storage_pools_tiering", service_name="Pool %s Tiering Status", sections=["emcvnx_storage_pools"], discovery_function=inventory_emcvnx_storage_pools_tiering, @@ -323,6 +325,7 @@ def check_emcvnx_storage_pools_tieringtypes(item, params, parsed): check_info["emcvnx_storage_pools.tieringtypes"] = LegacyCheckDefinition( + name="emcvnx_storage_pools_tieringtypes", service_name="Pool %s tiering", sections=["emcvnx_storage_pools"], discovery_function=inventory_emcvnx_storage_pools_tieringtypes, @@ -382,6 +385,7 @@ def check_emcvnx_storage_pools_deduplication(item, _no_params, parsed): check_info["emcvnx_storage_pools.deduplication"] = LegacyCheckDefinition( + name="emcvnx_storage_pools_deduplication", service_name="Pool %s Deduplication", sections=["emcvnx_storage_pools"], discovery_function=inventory_emcvnx_storage_pools, diff --git a/cmk/base/legacy_checks/emcvnx_writecache.py b/cmk/base/legacy_checks/emcvnx_writecache.py index 156c3d27bbd..b79a68c1c93 100644 --- a/cmk/base/legacy_checks/emcvnx_writecache.py +++ b/cmk/base/legacy_checks/emcvnx_writecache.py @@ -40,6 +40,7 @@ def parse_emcvnx_writecache(string_table: StringTable) -> StringTable: check_info["emcvnx_writecache"] = LegacyCheckDefinition( + name="emcvnx_writecache", parse_function=parse_emcvnx_writecache, service_name="Write Cache State %s", discovery_function=inventory_emcvnx_writecache, diff --git a/cmk/base/legacy_checks/emerson_stat.py b/cmk/base/legacy_checks/emerson_stat.py index 042b5a9cff3..4fceb9f390b 100644 --- a/cmk/base/legacy_checks/emerson_stat.py +++ b/cmk/base/legacy_checks/emerson_stat.py @@ -76,6 +76,7 @@ def parse_emerson_stat(string_table: StringTable) -> StringTable: check_info["emerson_stat"] = LegacyCheckDefinition( + name="emerson_stat", parse_function=parse_emerson_stat, detect=startswith(".1.3.6.1.4.1.6302.2.1.1.1.0", "Emerson Network Power"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emerson_temp.py b/cmk/base/legacy_checks/emerson_temp.py index cf00e560087..70548aeb1f1 100644 --- a/cmk/base/legacy_checks/emerson_temp.py +++ b/cmk/base/legacy_checks/emerson_temp.py @@ -43,6 +43,7 @@ def parse_emerson_temp(string_table: StringTable) -> StringTable: check_info["emerson_temp"] = LegacyCheckDefinition( + name="emerson_temp", parse_function=parse_emerson_temp, detect=startswith(".1.3.6.1.4.1.6302.2.1.1.1.0", "Emerson Network Power"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/emka_modules.py b/cmk/base/legacy_checks/emka_modules.py index 7b4ef35d24c..5660e987476 100644 --- a/cmk/base/legacy_checks/emka_modules.py +++ b/cmk/base/legacy_checks/emka_modules.py @@ -16,7 +16,7 @@ def parse_emka_modules(string_table): # pylint: disable=too-many-branches - if not all(string_table): + if not any(string_table): return None # basModuleCoIx == 0 @@ -86,7 +86,7 @@ def parse_emka_modules(string_table): # pylint: disable=too-many-branches if mode: attrs["mode"] = mode - for oidend, threshold in string_table[6]: + for oidend, threshold in string_table[5]: location, threshold_ty = oidend.split(".") if threshold_ty == "1": ty = "levels_lower" @@ -109,7 +109,7 @@ def parse_emka_modules(string_table): # pylint: disable=too-many-branches # 0.02 => 2/100 [multiplicator]/[divisor] # -30.0 [offset] # Notice, may also "=#\xb0C0.0230.0" - for oidend, equation_bin in string_table[7]: + for oidend, equation_bin in string_table[6]: equation = [] part = [] for entry in equation_bin: @@ -202,6 +202,7 @@ def check_emka_modules(item, params, parsed): check_info["emka_modules"] = LegacyCheckDefinition( + name="emka_modules", detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "emka"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13595"), @@ -269,6 +270,7 @@ def check_emka_modules_alarm(item, params, parsed): check_info["emka_modules.alarm"] = LegacyCheckDefinition( + name="emka_modules_alarm", service_name="Alarm %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_alarm, @@ -308,6 +310,7 @@ def check_emka_modules_handle(item, params, parsed): check_info["emka_modules.handle"] = LegacyCheckDefinition( + name="emka_modules_handle", service_name="Handle %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_handle, @@ -339,6 +342,7 @@ def check_emka_modules_sensor_volt(item, params, parsed): check_info["emka_modules.sensor_volt"] = LegacyCheckDefinition( + name="emka_modules_sensor_volt", service_name="Phase %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_sensor_volt, @@ -377,6 +381,7 @@ def check_emka_modules_sensor_temp(item, params, parsed): check_info["emka_modules.sensor_temp"] = LegacyCheckDefinition( + name="emka_modules_sensor_temp", service_name="Temperature %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_sensor_temp, @@ -409,6 +414,7 @@ def check_emka_modules_sensor_humid(item, params, parsed): check_info["emka_modules.sensor_humid"] = LegacyCheckDefinition( + name="emka_modules_sensor_humid", service_name="Humidity %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_sensor_humid, @@ -446,6 +452,7 @@ def check_emka_modules_relay(item, params, parsed): check_info["emka_modules.relay"] = LegacyCheckDefinition( + name="emka_modules_relay", service_name="Relay %s", sections=["emka_modules"], discovery_function=inventory_emka_modules_relay, diff --git a/cmk/base/legacy_checks/enterasys_cpu_util.py b/cmk/base/legacy_checks/enterasys_cpu_util.py index d8aecf5ece9..382887c36f2 100644 --- a/cmk/base/legacy_checks/enterasys_cpu_util.py +++ b/cmk/base/legacy_checks/enterasys_cpu_util.py @@ -30,6 +30,7 @@ def parse_enterasys_cpu_util(string_table: StringTable) -> StringTable: check_info["enterasys_cpu_util"] = LegacyCheckDefinition( + name="enterasys_cpu_util", parse_function=parse_enterasys_cpu_util, detect=DETECT_ENTERASYS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/enterasys_fans.py b/cmk/base/legacy_checks/enterasys_fans.py index ec60fe73d3c..6ecb3d0e578 100644 --- a/cmk/base/legacy_checks/enterasys_fans.py +++ b/cmk/base/legacy_checks/enterasys_fans.py @@ -38,6 +38,7 @@ def parse_enterasys_fans(string_table: StringTable) -> StringTable: check_info["enterasys_fans"] = LegacyCheckDefinition( + name="enterasys_fans", parse_function=parse_enterasys_fans, detect=DETECT_ENTERASYS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/enterasys_lsnat.py b/cmk/base/legacy_checks/enterasys_lsnat.py index a37aa03aaca..244e563f421 100644 --- a/cmk/base/legacy_checks/enterasys_lsnat.py +++ b/cmk/base/legacy_checks/enterasys_lsnat.py @@ -47,6 +47,7 @@ def parse_enterasys_lsnat(string_table: StringTable) -> StringTable | None: check_info["enterasys_lsnat"] = LegacyCheckDefinition( + name="enterasys_lsnat", parse_function=parse_enterasys_lsnat, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.5624.2.1"), diff --git a/cmk/base/legacy_checks/enterasys_powersupply.py b/cmk/base/legacy_checks/enterasys_powersupply.py index adbed7c3f8e..7f3de6b7daa 100644 --- a/cmk/base/legacy_checks/enterasys_powersupply.py +++ b/cmk/base/legacy_checks/enterasys_powersupply.py @@ -60,6 +60,7 @@ def parse_enterasys_powersupply(string_table: StringTable) -> StringTable: check_info["enterasys_powersupply"] = LegacyCheckDefinition( + name="enterasys_powersupply", parse_function=parse_enterasys_powersupply, detect=DETECT_ENTERASYS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/enterasys_temp.py b/cmk/base/legacy_checks/enterasys_temp.py index 96c60630be5..3d565ba9910 100644 --- a/cmk/base/legacy_checks/enterasys_temp.py +++ b/cmk/base/legacy_checks/enterasys_temp.py @@ -36,6 +36,7 @@ def parse_enterasys_temp(string_table: StringTable) -> StringTable: check_info["enterasys_temp"] = LegacyCheckDefinition( + name="enterasys_temp", parse_function=parse_enterasys_temp, detect=DETECT_ENTERASYS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/entersekt.py b/cmk/base/legacy_checks/entersekt.py index f181bde82b3..54c97f18c0e 100644 --- a/cmk/base/legacy_checks/entersekt.py +++ b/cmk/base/legacy_checks/entersekt.py @@ -44,6 +44,7 @@ def parse_entersekt(string_table: StringTable) -> StringTable: check_info["entersekt"] = LegacyCheckDefinition( + name="entersekt", parse_function=parse_entersekt, detect=all_of(contains(".1.3.6.1.2.1.1.1.0", "linux"), exists(".1.3.6.1.4.1.38235.2.3.1.0")), fetch=SNMPTree( @@ -99,6 +100,7 @@ def check_entersekt_emrerrors(item, params, info): check_info["entersekt.emrerrors"] = LegacyCheckDefinition( + name="entersekt_emrerrors", service_name="Entersekt http EMR Errors", sections=["entersekt"], discovery_function=inventory_entersekt_emrerrors, @@ -151,6 +153,7 @@ def check_entersekt_ecerterrors(item, params, info): check_info["entersekt.ecerterrors"] = LegacyCheckDefinition( + name="entersekt_ecerterrors", service_name="Entersekt http Ecert Errors", sections=["entersekt"], discovery_function=inventory_entersekt_ecerterrors, @@ -202,6 +205,7 @@ def check_entersekt_soaperrors(item, params, info): check_info["entersekt.soaperrors"] = LegacyCheckDefinition( + name="entersekt_soaperrors", service_name="Entersekt Soap Service Errors", sections=["entersekt"], discovery_function=inventory_entersekt_soaperrors, @@ -266,6 +270,7 @@ def check_entersekt_certexpiry(item, params, info): check_info["entersekt.certexpiry"] = LegacyCheckDefinition( + name="entersekt_certexpiry", service_name="Entersekt Certificate Expiration", sections=["entersekt"], discovery_function=inventory_entersekt_certexpiry, diff --git a/cmk/base/legacy_checks/epson_beamer_lamp.py b/cmk/base/legacy_checks/epson_beamer_lamp.py index 778b243637f..0e2115daecc 100644 --- a/cmk/base/legacy_checks/epson_beamer_lamp.py +++ b/cmk/base/legacy_checks/epson_beamer_lamp.py @@ -31,6 +31,7 @@ def parse_epson_beamer_lamp(string_table: StringTable) -> StringTable: check_info["epson_beamer_lamp"] = LegacyCheckDefinition( + name="epson_beamer_lamp", parse_function=parse_epson_beamer_lamp, detect=contains(".1.3.6.1.2.1.1.2.0", "1248"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/esx_vsphere_counters.py b/cmk/base/legacy_checks/esx_vsphere_counters.py index 2fff360f80c..fccd55256d3 100644 --- a/cmk/base/legacy_checks/esx_vsphere_counters.py +++ b/cmk/base/legacy_checks/esx_vsphere_counters.py @@ -66,6 +66,7 @@ def check_esx_vsphere_counters_uptime(_no_item, params, parsed): check_info["esx_vsphere_counters.uptime"] = LegacyCheckDefinition( + name="esx_vsphere_counters_uptime", service_name="Uptime", sections=["esx_vsphere_counters"], discovery_function=inventory_esx_vsphere_counters_uptime, @@ -117,6 +118,7 @@ def check_esx_vsphere_counters_swap(item, params, parsed): check_info["esx_vsphere_counters.swap"] = LegacyCheckDefinition( + name="esx_vsphere_counters_swap", service_name="VMKernel Swap", sections=["esx_vsphere_counters"], discovery_function=inventory_esx_vsphere_counters_swap, diff --git a/cmk/base/legacy_checks/esx_vsphere_datastores.py b/cmk/base/legacy_checks/esx_vsphere_datastores.py index 036814e08ab..0747d79b622 100644 --- a/cmk/base/legacy_checks/esx_vsphere_datastores.py +++ b/cmk/base/legacy_checks/esx_vsphere_datastores.py @@ -101,6 +101,7 @@ def discover_esx_vsphere_datastores(section): check_info["esx_vsphere_datastores"] = LegacyCheckDefinition( + name="esx_vsphere_datastores", parse_function=parse_esx_vsphere_datastores, service_name="Filesystem %s", discovery_function=discover_esx_vsphere_datastores, diff --git a/cmk/base/legacy_checks/esx_vsphere_hostsystem.py b/cmk/base/legacy_checks/esx_vsphere_hostsystem.py index 66866f441f4..e9edd8a7da3 100644 --- a/cmk/base/legacy_checks/esx_vsphere_hostsystem.py +++ b/cmk/base/legacy_checks/esx_vsphere_hostsystem.py @@ -50,6 +50,7 @@ def check_esx_vsphere_hostsystem_state(_no_item, _no_params, parsed): check_info["esx_vsphere_hostsystem.state"] = LegacyCheckDefinition( + name="esx_vsphere_hostsystem_state", service_name="Overall state", sections=["esx_vsphere_hostsystem"], discovery_function=inventory_esx_vsphere_hostsystem_state, @@ -92,6 +93,7 @@ def check_esx_vsphere_hostsystem_maintenance(_no_item, params, parsed): check_info["esx_vsphere_hostsystem.maintenance"] = LegacyCheckDefinition( + name="esx_vsphere_hostsystem_maintenance", service_name="Maintenance Mode", sections=["esx_vsphere_hostsystem"], discovery_function=inventory_esx_vsphere_hostsystem_maintenance, @@ -220,6 +222,7 @@ def check_esx_vsphere_hostsystem_multipath( # pylint: disable=too-many-branches check_info["esx_vsphere_hostsystem.multipath"] = LegacyCheckDefinition( + name="esx_vsphere_hostsystem_multipath", service_name="Multipath %s", sections=["esx_vsphere_hostsystem"], discovery_function=inventory_esx_vsphere_hostsystem_multipath, diff --git a/cmk/base/legacy_checks/esx_vsphere_licenses.py b/cmk/base/legacy_checks/esx_vsphere_licenses.py index bb91d04a243..406948936a2 100644 --- a/cmk/base/legacy_checks/esx_vsphere_licenses.py +++ b/cmk/base/legacy_checks/esx_vsphere_licenses.py @@ -47,6 +47,7 @@ def check_esx_vsphere_licenses(item, params, parsed): check_info["esx_vsphere_licenses"] = LegacyCheckDefinition( + name="esx_vsphere_licenses", parse_function=parse_esx_vsphere_licenses, service_name="License %s", discovery_function=inventory_esx_vsphere_licenses, diff --git a/cmk/base/legacy_checks/esx_vsphere_objects.py b/cmk/base/legacy_checks/esx_vsphere_objects.py index d5cb7ef7bfb..a34a3395aab 100644 --- a/cmk/base/legacy_checks/esx_vsphere_objects.py +++ b/cmk/base/legacy_checks/esx_vsphere_objects.py @@ -91,6 +91,7 @@ def check_esx_vsphere_objects(item, params, parsed): check_info["esx_vsphere_objects"] = LegacyCheckDefinition( + name="esx_vsphere_objects", parse_function=parse_esx_vsphere_objects, service_name="%s", discovery_function=inventory_esx_vsphere_objects, @@ -140,6 +141,7 @@ def check_esx_vsphere_objects_count(_no_item, params, parsed): check_info["esx_vsphere_objects.count"] = LegacyCheckDefinition( + name="esx_vsphere_objects_count", service_name="Object count", sections=["esx_vsphere_objects"], discovery_function=inventory_esx_vsphere_objects_count, diff --git a/cmk/base/legacy_checks/esx_vsphere_sensors.py b/cmk/base/legacy_checks/esx_vsphere_sensors.py index 6d1cf824a9d..9794d872f5c 100644 --- a/cmk/base/legacy_checks/esx_vsphere_sensors.py +++ b/cmk/base/legacy_checks/esx_vsphere_sensors.py @@ -62,6 +62,7 @@ def parse_esx_vsphere_sensors(string_table: StringTable) -> StringTable: check_info["esx_vsphere_sensors"] = LegacyCheckDefinition( + name="esx_vsphere_sensors", parse_function=parse_esx_vsphere_sensors, service_name="Hardware Sensors", discovery_function=inventory_esx_vsphere_sensors, diff --git a/cmk/base/legacy_checks/esx_vsphere_vm.py b/cmk/base/legacy_checks/esx_vsphere_vm.py index 44c6d7b7211..b8a4340c71d 100644 --- a/cmk/base/legacy_checks/esx_vsphere_vm.py +++ b/cmk/base/legacy_checks/esx_vsphere_vm.py @@ -55,6 +55,7 @@ def check_esx_vsphere_vm_mounted_devices(item, params, section): check_info["esx_vsphere_vm.mounted_devices"] = LegacyCheckDefinition( + name="esx_vsphere_vm_mounted_devices", service_name="ESX Mounted Devices", sections=["esx_vsphere_vm"], discovery_function=inventory_esx_vsphere_vm_mounted_devices, diff --git a/cmk/base/legacy_checks/etherbox2_temp.py b/cmk/base/legacy_checks/etherbox2_temp.py index a9ee3d65c17..a4ae5569643 100644 --- a/cmk/base/legacy_checks/etherbox2_temp.py +++ b/cmk/base/legacy_checks/etherbox2_temp.py @@ -60,6 +60,7 @@ def check_etherbox2_temp(item, params, parsed): check_info["etherbox2_temp"] = LegacyCheckDefinition( + name="etherbox2_temp", detect=all_of( equals(".1.3.6.1.2.1.1.1.0", ""), contains(".1.3.6.1.4.1.14848.2.1.1.1.0", "Version 1.2") ), diff --git a/cmk/base/legacy_checks/f5_bigip_apm.py b/cmk/base/legacy_checks/f5_bigip_apm.py index 7d1b9f99f8d..ce3d9b1ee6d 100644 --- a/cmk/base/legacy_checks/f5_bigip_apm.py +++ b/cmk/base/legacy_checks/f5_bigip_apm.py @@ -27,6 +27,7 @@ def parse_f5_bigip_apm(string_table: StringTable) -> StringTable: check_info["f5_bigip_apm"] = LegacyCheckDefinition( + name="f5_bigip_apm", parse_function=parse_f5_bigip_apm, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_chassis_temp.py b/cmk/base/legacy_checks/f5_bigip_chassis_temp.py index b13cdc27466..543a0176810 100644 --- a/cmk/base/legacy_checks/f5_bigip_chassis_temp.py +++ b/cmk/base/legacy_checks/f5_bigip_chassis_temp.py @@ -29,6 +29,7 @@ def parse_f5_bigip_chassis_temp(string_table: StringTable) -> StringTable: check_info["f5_bigip_chassis_temp"] = LegacyCheckDefinition( + name="f5_bigip_chassis_temp", parse_function=parse_f5_bigip_chassis_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_conns.py b/cmk/base/legacy_checks/f5_bigip_conns.py index 256ec08d192..5860c6f4c29 100644 --- a/cmk/base/legacy_checks/f5_bigip_conns.py +++ b/cmk/base/legacy_checks/f5_bigip_conns.py @@ -89,6 +89,7 @@ def parse_f5_bigip_conns(string_table: StringTable) -> StringTable: check_info["f5_bigip_conns"] = LegacyCheckDefinition( + name="f5_bigip_conns", parse_function=parse_f5_bigip_conns, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_cpu_temp.py b/cmk/base/legacy_checks/f5_bigip_cpu_temp.py index f384329b26b..912458f7d90 100644 --- a/cmk/base/legacy_checks/f5_bigip_cpu_temp.py +++ b/cmk/base/legacy_checks/f5_bigip_cpu_temp.py @@ -29,6 +29,7 @@ def parse_f5_bigip_cpu_temp(string_table: StringTable) -> StringTable: check_info["f5_bigip_cpu_temp"] = LegacyCheckDefinition( + name="f5_bigip_cpu_temp", parse_function=parse_f5_bigip_cpu_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_fans.py b/cmk/base/legacy_checks/f5_bigip_fans.py index 9505ca705e2..017b380077a 100644 --- a/cmk/base/legacy_checks/f5_bigip_fans.py +++ b/cmk/base/legacy_checks/f5_bigip_fans.py @@ -76,6 +76,7 @@ def check_f5_bigip_fans(item, params, parsed): # Get ID and Speed from the CPU and chassis fan tables check_info["f5_bigip_fans"] = LegacyCheckDefinition( + name="f5_bigip_fans", detect=DETECT, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_interfaces.py b/cmk/base/legacy_checks/f5_bigip_interfaces.py index 3599f4de3c9..63a4275d55f 100644 --- a/cmk/base/legacy_checks/f5_bigip_interfaces.py +++ b/cmk/base/legacy_checks/f5_bigip_interfaces.py @@ -96,6 +96,7 @@ def check_f5_bigip_interfaces(item, _no_params, section): check_info["f5_bigip_interfaces"] = LegacyCheckDefinition( + name="f5_bigip_interfaces", detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3375.2.1.3.4.10"), equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3375.2.1.3.4.20"), diff --git a/cmk/base/legacy_checks/f5_bigip_mem.py b/cmk/base/legacy_checks/f5_bigip_mem.py index d5f3c50ff83..03a8546f0ae 100644 --- a/cmk/base/legacy_checks/f5_bigip_mem.py +++ b/cmk/base/legacy_checks/f5_bigip_mem.py @@ -60,6 +60,7 @@ def check_f5_bigip_mem(item, params, parsed): check_info["f5_bigip_mem"] = LegacyCheckDefinition( + name="f5_bigip_mem", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3375"), fetch=SNMPTree( base=".1.3.6.1.4.1.3375.2.1", diff --git a/cmk/base/legacy_checks/f5_bigip_pool.py b/cmk/base/legacy_checks/f5_bigip_pool.py index 00314a9fb29..1c95e2ae9f1 100644 --- a/cmk/base/legacy_checks/f5_bigip_pool.py +++ b/cmk/base/legacy_checks/f5_bigip_pool.py @@ -95,6 +95,7 @@ def check_f5_bigip_pool(item, params, parsed): check_info["f5_bigip_pool"] = LegacyCheckDefinition( + name="f5_bigip_pool", detect=DETECT, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_psu.py b/cmk/base/legacy_checks/f5_bigip_psu.py index ff08ed7263b..ea2eb127264 100644 --- a/cmk/base/legacy_checks/f5_bigip_psu.py +++ b/cmk/base/legacy_checks/f5_bigip_psu.py @@ -55,6 +55,7 @@ def parse_f5_bigip_psu(string_table: StringTable) -> StringTable: check_info["f5_bigip_psu"] = LegacyCheckDefinition( + name="f5_bigip_psu", parse_function=parse_f5_bigip_psu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/f5_bigip_snat.py b/cmk/base/legacy_checks/f5_bigip_snat.py index 032e4d8c313..17efcfec7ab 100644 --- a/cmk/base/legacy_checks/f5_bigip_snat.py +++ b/cmk/base/legacy_checks/f5_bigip_snat.py @@ -108,6 +108,7 @@ def check_f5_bigip_snat(item, params, parsed): check_info["f5_bigip_snat"] = LegacyCheckDefinition( + name="f5_bigip_snat", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.3375.2.2.9.2.3.1", diff --git a/cmk/base/legacy_checks/f5_bigip_vserver.py b/cmk/base/legacy_checks/f5_bigip_vserver.py index c756956bd4f..646d2cdd6b1 100644 --- a/cmk/base/legacy_checks/f5_bigip_vserver.py +++ b/cmk/base/legacy_checks/f5_bigip_vserver.py @@ -215,6 +215,7 @@ def check_f5_bigip_vserver(item, params, parsed): check_info["f5_bigip_vserver"] = LegacyCheckDefinition( + name="f5_bigip_vserver", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.3375.2.2.10", diff --git a/cmk/base/legacy_checks/fast_lta_headunit.py b/cmk/base/legacy_checks/fast_lta_headunit.py index d0ee62cd20a..2ae415e6f87 100644 --- a/cmk/base/legacy_checks/fast_lta_headunit.py +++ b/cmk/base/legacy_checks/fast_lta_headunit.py @@ -17,6 +17,7 @@ def parse_fast_lta_headunit(string_table: Sequence[StringTable]) -> Sequence[Str check_info["fast_lta_headunit"] = LegacyCheckDefinition( + name="fast_lta_headunit", parse_function=parse_fast_lta_headunit, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"), @@ -88,6 +89,7 @@ def check_fast_lta_headunit_status(item, _no_params, info): check_info["fast_lta_headunit.status"] = LegacyCheckDefinition( + name="fast_lta_headunit_status", service_name="Fast LTA Headunit Status", sections=["fast_lta_headunit"], discovery_function=inventory_fast_lta_headunit_status, @@ -139,6 +141,7 @@ def check_fast_lta_headunit_replication(item, _no_params, info): check_info["fast_lta_headunit.replication"] = LegacyCheckDefinition( + name="fast_lta_headunit_replication", service_name="Fast LTA Replication", sections=["fast_lta_headunit"], discovery_function=inventory_fast_lta_headunit_replication, diff --git a/cmk/base/legacy_checks/fast_lta_silent_cubes.py b/cmk/base/legacy_checks/fast_lta_silent_cubes.py index b1b77663c59..2a11f2db62b 100644 --- a/cmk/base/legacy_checks/fast_lta_silent_cubes.py +++ b/cmk/base/legacy_checks/fast_lta_silent_cubes.py @@ -32,6 +32,7 @@ def parse_fast_lta_silent_cubes(string_table: StringTable) -> StringTable: check_info["fast_lta_silent_cubes"] = LegacyCheckDefinition( + name="fast_lta_silent_cubes", parse_function=parse_fast_lta_silent_cubes, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"), @@ -48,6 +49,7 @@ def parse_fast_lta_silent_cubes(string_table: StringTable) -> StringTable: check_info["fast_lta_silent_cubes.capacity"] = LegacyCheckDefinition( + name="fast_lta_silent_cubes_capacity", service_name="Fast LTA SC Capacity %s", sections=["fast_lta_silent_cubes"], discovery_function=inventory_fast_lta_silent_cubes_status, diff --git a/cmk/base/legacy_checks/fast_lta_volumes.py b/cmk/base/legacy_checks/fast_lta_volumes.py index aab33ff8097..8cc4c424523 100644 --- a/cmk/base/legacy_checks/fast_lta_volumes.py +++ b/cmk/base/legacy_checks/fast_lta_volumes.py @@ -37,6 +37,7 @@ def discover_fast_lta_volumes(section): check_info["fast_lta_volumes"] = LegacyCheckDefinition( + name="fast_lta_volumes", detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"), any_of(exists(".1.3.6.1.4.1.27417.5.1.1.2"), exists(".1.3.6.1.4.1.27417.5.1.1.2.0")), diff --git a/cmk/base/legacy_checks/fc_port.py b/cmk/base/legacy_checks/fc_port.py index 2f46351be09..866cb7bdd18 100644 --- a/cmk/base/legacy_checks/fc_port.py +++ b/cmk/base/legacy_checks/fc_port.py @@ -332,6 +332,7 @@ def parse_fc_port(string_table: StringTable) -> StringTable: check_info["fc_port"] = LegacyCheckDefinition( + name="fc_port", parse_function=parse_fc_port, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1588.2.1.1"), diff --git a/cmk/base/legacy_checks/filehandler.py b/cmk/base/legacy_checks/filehandler.py index f05935e5bf9..b6ef5351f30 100644 --- a/cmk/base/legacy_checks/filehandler.py +++ b/cmk/base/legacy_checks/filehandler.py @@ -47,6 +47,7 @@ def parse_filehandler(string_table: StringTable) -> StringTable: check_info["filehandler"] = LegacyCheckDefinition( + name="filehandler", parse_function=parse_filehandler, service_name="Filehandler", discovery_function=inventory_filehandler, diff --git a/cmk/base/legacy_checks/filestats.py b/cmk/base/legacy_checks/filestats.py index 47a8100e158..0d61c07d47b 100644 --- a/cmk/base/legacy_checks/filestats.py +++ b/cmk/base/legacy_checks/filestats.py @@ -298,6 +298,7 @@ def discover_filestats_single(section): check_info["filestats.single"] = LegacyCheckDefinition( + name="filestats_single", service_name="File %s", sections=["filestats"], discovery_function=discover_filestats_single, @@ -306,6 +307,7 @@ def discover_filestats_single(section): ) check_info["filestats"] = LegacyCheckDefinition( + name="filestats", parse_function=parse_filestats, service_name="File group %s", discovery_function=discover_filestats, diff --git a/cmk/base/legacy_checks/fireeye_active_vms.py b/cmk/base/legacy_checks/fireeye_active_vms.py index 55dd552267e..27ccc7225ca 100644 --- a/cmk/base/legacy_checks/fireeye_active_vms.py +++ b/cmk/base/legacy_checks/fireeye_active_vms.py @@ -32,6 +32,7 @@ def parse_fireeye_active_vms(string_table: StringTable) -> StringTable: check_info["fireeye_active_vms"] = LegacyCheckDefinition( + name="fireeye_active_vms", parse_function=parse_fireeye_active_vms, detect=fireeye.DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_bypass.py b/cmk/base/legacy_checks/fireeye_bypass.py index 0de590a589e..14088f48c48 100644 --- a/cmk/base/legacy_checks/fireeye_bypass.py +++ b/cmk/base/legacy_checks/fireeye_bypass.py @@ -34,6 +34,7 @@ def parse_fireeye_bypass(string_table: StringTable) -> StringTable: check_info["fireeye_bypass"] = LegacyCheckDefinition( + name="fireeye_bypass", parse_function=parse_fireeye_bypass, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_content.py b/cmk/base/legacy_checks/fireeye_content.py index 63b6dff81ca..526eb166078 100644 --- a/cmk/base/legacy_checks/fireeye_content.py +++ b/cmk/base/legacy_checks/fireeye_content.py @@ -71,6 +71,7 @@ def check_fireeye_content(_no_item, params, parsed): check_info["fireeye_content"] = LegacyCheckDefinition( + name="fireeye_content", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.25597.11.5.1", diff --git a/cmk/base/legacy_checks/fireeye_fans.py b/cmk/base/legacy_checks/fireeye_fans.py index 28e5ae1c083..ffb9afb0203 100644 --- a/cmk/base/legacy_checks/fireeye_fans.py +++ b/cmk/base/legacy_checks/fireeye_fans.py @@ -65,6 +65,7 @@ def discover_fireeye_fans(info): check_info["fireeye_fans"] = LegacyCheckDefinition( + name="fireeye_fans", parse_function=parse_fireeye_fans, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_lic_active.py b/cmk/base/legacy_checks/fireeye_lic_active.py index bbbf8e03b5b..5763ba91109 100644 --- a/cmk/base/legacy_checks/fireeye_lic_active.py +++ b/cmk/base/legacy_checks/fireeye_lic_active.py @@ -34,6 +34,7 @@ def discover_fireeye_lic_active(info): check_info["fireeye_lic_active"] = LegacyCheckDefinition( + name="fireeye_lic_active", parse_function=parse_fireeye_lic_active, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_lic_expiration.py b/cmk/base/legacy_checks/fireeye_lic_expiration.py index d3a4685132b..883bb5a4274 100644 --- a/cmk/base/legacy_checks/fireeye_lic_expiration.py +++ b/cmk/base/legacy_checks/fireeye_lic_expiration.py @@ -37,6 +37,7 @@ def parse_fireeye_lic_expiration(string_table: StringTable) -> StringTable: check_info["fireeye_lic_expiration"] = LegacyCheckDefinition( + name="fireeye_lic_expiration", parse_function=parse_fireeye_lic_expiration, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_mail.py b/cmk/base/legacy_checks/fireeye_mail.py index 1438e0f6599..7050de55ea0 100644 --- a/cmk/base/legacy_checks/fireeye_mail.py +++ b/cmk/base/legacy_checks/fireeye_mail.py @@ -72,6 +72,7 @@ def discover_fireeye_mail(info): check_info["fireeye_mail"] = LegacyCheckDefinition( + name="fireeye_mail", parse_function=parse_fireeye_mail, detect=DETECT, fetch=SNMPTree( @@ -137,6 +138,7 @@ def discover_fireeye_mail_attachment(info): check_info["fireeye_mail.attachment"] = LegacyCheckDefinition( + name="fireeye_mail_attachment", service_name="Mails Containing Attachment", sections=["fireeye_mail"], discovery_function=discover_fireeye_mail_attachment, @@ -177,6 +179,7 @@ def discover_fireeye_mail_url(info): check_info["fireeye_mail.url"] = LegacyCheckDefinition( + name="fireeye_mail_url", service_name="Mails Containing URL", sections=["fireeye_mail"], discovery_function=discover_fireeye_mail_url, @@ -247,6 +250,7 @@ def discover_fireeye_mail_statistics(info): check_info["fireeye_mail.statistics"] = LegacyCheckDefinition( + name="fireeye_mail_statistics", service_name="Mail Processing Statistics", sections=["fireeye_mail"], discovery_function=discover_fireeye_mail_statistics, @@ -283,6 +287,7 @@ def discover_fireeye_mail_received(info): check_info["fireeye_mail.received"] = LegacyCheckDefinition( + name="fireeye_mail_received", service_name="Mails Received", sections=["fireeye_mail"], discovery_function=discover_fireeye_mail_received, diff --git a/cmk/base/legacy_checks/fireeye_mailq.py b/cmk/base/legacy_checks/fireeye_mailq.py index 3311ee53884..c99f11148e4 100644 --- a/cmk/base/legacy_checks/fireeye_mailq.py +++ b/cmk/base/legacy_checks/fireeye_mailq.py @@ -40,6 +40,7 @@ def check_fireeye_mailq(_no_item, params, parsed): check_info["fireeye_mailq"] = LegacyCheckDefinition( + name="fireeye_mailq", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.25597.13.1", diff --git a/cmk/base/legacy_checks/fireeye_powersupplies.py b/cmk/base/legacy_checks/fireeye_powersupplies.py index 11f1b580ef4..1c5f4dd113d 100644 --- a/cmk/base/legacy_checks/fireeye_powersupplies.py +++ b/cmk/base/legacy_checks/fireeye_powersupplies.py @@ -32,6 +32,7 @@ def discover_fireeye_powersupplies(info): check_info["fireeye_powersupplies"] = LegacyCheckDefinition( + name="fireeye_powersupplies", parse_function=parse_fireeye_powersupplies, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_quarantine.py b/cmk/base/legacy_checks/fireeye_quarantine.py index 8ddced99ffd..283b958e458 100644 --- a/cmk/base/legacy_checks/fireeye_quarantine.py +++ b/cmk/base/legacy_checks/fireeye_quarantine.py @@ -34,6 +34,7 @@ def parse_fireeye_quarantine(string_table: StringTable) -> StringTable: check_info["fireeye_quarantine"] = LegacyCheckDefinition( + name="fireeye_quarantine", parse_function=parse_fireeye_quarantine, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_raid.py b/cmk/base/legacy_checks/fireeye_raid.py index 491dc08abba..34365de2f1d 100644 --- a/cmk/base/legacy_checks/fireeye_raid.py +++ b/cmk/base/legacy_checks/fireeye_raid.py @@ -59,6 +59,7 @@ def discover_fireeye_raid(parsed): check_info["fireeye_raid"] = LegacyCheckDefinition( + name="fireeye_raid", detect=DETECT, fetch=[ SNMPTree( @@ -101,6 +102,7 @@ def discover_fireeye_raid_disks(parsed): check_info["fireeye_raid.disks"] = LegacyCheckDefinition( + name="fireeye_raid_disks", service_name="Disk status %s", sections=["fireeye_raid"], discovery_function=discover_fireeye_raid_disks, diff --git a/cmk/base/legacy_checks/fireeye_smtp_conn.py b/cmk/base/legacy_checks/fireeye_smtp_conn.py index 7cdfe3a84cf..af3533a5884 100644 --- a/cmk/base/legacy_checks/fireeye_smtp_conn.py +++ b/cmk/base/legacy_checks/fireeye_smtp_conn.py @@ -28,6 +28,7 @@ def discover_fireeye_smtp_conn(info): check_info["fireeye_smtp_conn"] = LegacyCheckDefinition( + name="fireeye_smtp_conn", parse_function=parse_fireeye_smtp_conn, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_sys_image.py b/cmk/base/legacy_checks/fireeye_sys_image.py index 96bc6142e53..39dda75c017 100644 --- a/cmk/base/legacy_checks/fireeye_sys_image.py +++ b/cmk/base/legacy_checks/fireeye_sys_image.py @@ -38,6 +38,7 @@ def discover_fireeye_sys_image(info): check_info["fireeye_sys_image"] = LegacyCheckDefinition( + name="fireeye_sys_image", parse_function=parse_fireeye_sys_image, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fireeye_temp.py b/cmk/base/legacy_checks/fireeye_temp.py index 7ce0535a69e..7285cc03faa 100644 --- a/cmk/base/legacy_checks/fireeye_temp.py +++ b/cmk/base/legacy_checks/fireeye_temp.py @@ -47,6 +47,7 @@ def parse_fireeye_temp(string_table: StringTable) -> StringTable: check_info["fireeye_temp"] = LegacyCheckDefinition( + name="fireeye_temp", parse_function=parse_fireeye_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fortigate_cpu.py b/cmk/base/legacy_checks/fortigate_cpu.py index 0f15b078e3b..68ed3a148be 100644 --- a/cmk/base/legacy_checks/fortigate_cpu.py +++ b/cmk/base/legacy_checks/fortigate_cpu.py @@ -41,6 +41,7 @@ def check_fortigate_cpu(item, params, info): check_info["fortigate_cpu_base"] = LegacyCheckDefinition( + name="fortigate_cpu_base", parse_function=parse_fortigate_cpu, detect=all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.101.1"), @@ -59,6 +60,7 @@ def check_fortigate_cpu(item, params, info): ) check_info["fortigate_cpu"] = LegacyCheckDefinition( + name="fortigate_cpu", parse_function=parse_fortigate_cpu, detect=all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.101.1"), diff --git a/cmk/base/legacy_checks/fortigate_ipsecvpn.py b/cmk/base/legacy_checks/fortigate_ipsecvpn.py index 924292feb94..87145069ec3 100644 --- a/cmk/base/legacy_checks/fortigate_ipsecvpn.py +++ b/cmk/base/legacy_checks/fortigate_ipsecvpn.py @@ -71,6 +71,7 @@ def parse_fortigate_ipsecvpn(string_table: StringTable) -> StringTable: check_info["fortigate_ipsecvpn"] = LegacyCheckDefinition( + name="fortigate_ipsecvpn", parse_function=parse_fortigate_ipsecvpn, detect=DETECT_FORTIGATE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fortigate_memory.py b/cmk/base/legacy_checks/fortigate_memory.py index 96404d99faa..5794ab04e2d 100644 --- a/cmk/base/legacy_checks/fortigate_memory.py +++ b/cmk/base/legacy_checks/fortigate_memory.py @@ -48,6 +48,7 @@ def check_fortigate_memory(item, params, current_reading): check_info["fortigate_memory"] = LegacyCheckDefinition( + name="fortigate_memory", detect=all_of(contains(".1.3.6.1.2.1.1.1.0", "fortigate"), exists(".1.3.6.1.4.1.12356.1.9.0")), fetch=SNMPTree( base=".1.3.6.1.4.1.12356.1", diff --git a/cmk/base/legacy_checks/fortigate_memory_base.py b/cmk/base/legacy_checks/fortigate_memory_base.py index 6f5d80485db..20fa4591991 100644 --- a/cmk/base/legacy_checks/fortigate_memory_base.py +++ b/cmk/base/legacy_checks/fortigate_memory_base.py @@ -45,6 +45,7 @@ def check_fortigate_memory_base(_item, params, parsed): check_info["fortigate_memory_base"] = LegacyCheckDefinition( + name="fortigate_memory_base", detect=DETECT_FORTIGATE, fetch=SNMPTree( base=".1.3.6.1.4.1.12356.101.4.1", diff --git a/cmk/base/legacy_checks/fortigate_node.py b/cmk/base/legacy_checks/fortigate_node.py index ac7dae96981..b1e90ecd89c 100644 --- a/cmk/base/legacy_checks/fortigate_node.py +++ b/cmk/base/legacy_checks/fortigate_node.py @@ -90,6 +90,7 @@ def check_fortigate_cluster(_no_item, _no_params, parsed): check_info["fortigate_node"] = LegacyCheckDefinition( + name="fortigate_node", detect=all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.101.1"), not_equals(".1.3.6.1.4.1.12356.101.13.1.1.0", "1"), @@ -133,6 +134,7 @@ def check_fortigate_node_cpu(item, params, parsed): check_info["fortigate_node.cpu"] = LegacyCheckDefinition( + name="fortigate_node_cpu", service_name="CPU utilization %s", sections=["fortigate_node"], discovery_function=inventory_fortigate_node_cpu, @@ -166,6 +168,7 @@ def check_fortigate_node_ses(item, params, parsed): check_info["fortigate_node.sessions"] = LegacyCheckDefinition( + name="fortigate_node_sessions", service_name="Sessions %s", sections=["fortigate_node"], discovery_function=inventory_fortigate_node_ses, diff --git a/cmk/base/legacy_checks/fortigate_sessions.py b/cmk/base/legacy_checks/fortigate_sessions.py index 9cf530ce5e2..aab00f2ca78 100644 --- a/cmk/base/legacy_checks/fortigate_sessions.py +++ b/cmk/base/legacy_checks/fortigate_sessions.py @@ -30,6 +30,7 @@ def parse_fortigate_sessions(string_table: StringTable) -> StringTable | None: check_info["fortigate_sessions"] = LegacyCheckDefinition( + name="fortigate_sessions", parse_function=parse_fortigate_sessions, detect=all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.101.1"), diff --git a/cmk/base/legacy_checks/fortigate_sessions_base.py b/cmk/base/legacy_checks/fortigate_sessions_base.py index b8280b188d3..a0271715371 100644 --- a/cmk/base/legacy_checks/fortigate_sessions_base.py +++ b/cmk/base/legacy_checks/fortigate_sessions_base.py @@ -26,6 +26,7 @@ def parse_fortigate_sessions_base(string_table: StringTable) -> StringTable | No check_info["fortigate_sessions_base"] = LegacyCheckDefinition( + name="fortigate_sessions_base", parse_function=parse_fortigate_sessions_base, detect=all_of( contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.101.1"), diff --git a/cmk/base/legacy_checks/fortigate_sslvpn.py b/cmk/base/legacy_checks/fortigate_sslvpn.py index 778568ff390..0866a8eec9f 100644 --- a/cmk/base/legacy_checks/fortigate_sslvpn.py +++ b/cmk/base/legacy_checks/fortigate_sslvpn.py @@ -60,6 +60,7 @@ def discover_fortigate_sslvpn(section): check_info["fortigate_sslvpn"] = LegacyCheckDefinition( + name="fortigate_sslvpn", detect=DETECT_FORTIGATE, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/fortinet_controller_aps.py b/cmk/base/legacy_checks/fortinet_controller_aps.py index acde00d117a..38cacaa2426 100644 --- a/cmk/base/legacy_checks/fortinet_controller_aps.py +++ b/cmk/base/legacy_checks/fortinet_controller_aps.py @@ -121,6 +121,7 @@ def check_fortinet_controller_aps(item, params, parsed): check_info["fortinet_controller_aps"] = LegacyCheckDefinition( + name="fortinet_controller_aps", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.15983"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/fortisandbox_cpu_util.py b/cmk/base/legacy_checks/fortisandbox_cpu_util.py index 9fca0c443b7..153924310df 100644 --- a/cmk/base/legacy_checks/fortisandbox_cpu_util.py +++ b/cmk/base/legacy_checks/fortisandbox_cpu_util.py @@ -38,6 +38,7 @@ def parse_fortisandbox_cpu_util(string_table: StringTable) -> StringTable: check_info["fortisandbox_cpu_util"] = LegacyCheckDefinition( + name="fortisandbox_cpu_util", parse_function=parse_fortisandbox_cpu_util, detect=DETECT_FORTISANDBOX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fortisandbox_queues.py b/cmk/base/legacy_checks/fortisandbox_queues.py index 139d6e15147..c6cc4bf1c9d 100644 --- a/cmk/base/legacy_checks/fortisandbox_queues.py +++ b/cmk/base/legacy_checks/fortisandbox_queues.py @@ -67,6 +67,7 @@ def check_fortisandbox_queues(item, params, parsed): check_info["fortisandbox_queues"] = LegacyCheckDefinition( + name="fortisandbox_queues", detect=DETECT_FORTISANDBOX, fetch=SNMPTree( base=".1.3.6.1.4.1.12356.118.5.1", diff --git a/cmk/base/legacy_checks/fsc_fans.py b/cmk/base/legacy_checks/fsc_fans.py index 5a89f99c12f..92d6a799f17 100644 --- a/cmk/base/legacy_checks/fsc_fans.py +++ b/cmk/base/legacy_checks/fsc_fans.py @@ -37,6 +37,7 @@ def check_fsc_fans(item, params, parsed): check_info["fsc_fans"] = LegacyCheckDefinition( + name="fsc_fans", detect=all_of( all_of( any_of( diff --git a/cmk/base/legacy_checks/fsc_ipmi_mem_status.py b/cmk/base/legacy_checks/fsc_ipmi_mem_status.py index f2174eba64b..87c24edb236 100644 --- a/cmk/base/legacy_checks/fsc_ipmi_mem_status.py +++ b/cmk/base/legacy_checks/fsc_ipmi_mem_status.py @@ -60,6 +60,7 @@ def parse_fsc_ipmi_mem_status(string_table: StringTable) -> StringTable: check_info["fsc_ipmi_mem_status"] = LegacyCheckDefinition( + name="fsc_ipmi_mem_status", parse_function=parse_fsc_ipmi_mem_status, service_name="IPMI Memory status %s", discovery_function=inventory_fsc_ipmi_mem_status, diff --git a/cmk/base/legacy_checks/fsc_sc2_cpu_status.py b/cmk/base/legacy_checks/fsc_sc2_cpu_status.py index 1673a20931a..96f9051d53f 100644 --- a/cmk/base/legacy_checks/fsc_sc2_cpu_status.py +++ b/cmk/base/legacy_checks/fsc_sc2_cpu_status.py @@ -53,6 +53,7 @@ def get_cpu_status(status): check_info["fsc_sc2_cpu_status"] = LegacyCheckDefinition( + name="fsc_sc2_cpu_status", parse_function=parse_fsc_sc2_cpu_status, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_fans.py b/cmk/base/legacy_checks/fsc_sc2_fans.py index 8fc7f88bcd6..962af9aff9e 100644 --- a/cmk/base/legacy_checks/fsc_sc2_fans.py +++ b/cmk/base/legacy_checks/fsc_sc2_fans.py @@ -70,6 +70,7 @@ def check_fsc_sc2_fans(item, params, info): check_info["fsc_sc2_fans"] = LegacyCheckDefinition( + name="fsc_sc2_fans", parse_function=parse_fsc_sc2_fans, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_info.py b/cmk/base/legacy_checks/fsc_sc2_info.py index 8885a7b53e3..277d5d578f2 100644 --- a/cmk/base/legacy_checks/fsc_sc2_info.py +++ b/cmk/base/legacy_checks/fsc_sc2_info.py @@ -35,6 +35,7 @@ def check_fsc_sc2_info(_no_item, _no_params, info): check_info["fsc_sc2_info"] = LegacyCheckDefinition( + name="fsc_sc2_info", parse_function=parse_fsc_sc2_info, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_mem_status.py b/cmk/base/legacy_checks/fsc_sc2_mem_status.py index 576a2d85302..3494b9712bf 100644 --- a/cmk/base/legacy_checks/fsc_sc2_mem_status.py +++ b/cmk/base/legacy_checks/fsc_sc2_mem_status.py @@ -70,6 +70,7 @@ def get_mem_status(status): check_info["fsc_sc2_mem_status"] = LegacyCheckDefinition( + name="fsc_sc2_mem_status", parse_function=parse_fsc_sc2_mem_status, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_power_consumption.py b/cmk/base/legacy_checks/fsc_sc2_power_consumption.py index c5421e424cf..4a7c0f5b2ca 100644 --- a/cmk/base/legacy_checks/fsc_sc2_power_consumption.py +++ b/cmk/base/legacy_checks/fsc_sc2_power_consumption.py @@ -47,6 +47,7 @@ def discover_fsc_sc2_power_consumption(section): check_info["fsc_sc2_power_consumption"] = LegacyCheckDefinition( + name="fsc_sc2_power_consumption", detect=DETECT_FSC_SC2, fetch=SNMPTree( base=".1.3.6.1.4.1.231.2.10.2.2.10.6.7.1", diff --git a/cmk/base/legacy_checks/fsc_sc2_psu.py b/cmk/base/legacy_checks/fsc_sc2_psu.py index b41d90dca11..8138109dfba 100644 --- a/cmk/base/legacy_checks/fsc_sc2_psu.py +++ b/cmk/base/legacy_checks/fsc_sc2_psu.py @@ -60,6 +60,7 @@ def parse_fsc_sc2_psu(string_table: StringTable) -> StringTable: check_info["fsc_sc2_psu"] = LegacyCheckDefinition( + name="fsc_sc2_psu", parse_function=parse_fsc_sc2_psu, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_temp.py b/cmk/base/legacy_checks/fsc_sc2_temp.py index ec459c094b9..a6e9ae46fcc 100644 --- a/cmk/base/legacy_checks/fsc_sc2_temp.py +++ b/cmk/base/legacy_checks/fsc_sc2_temp.py @@ -107,6 +107,7 @@ def check_fsc_sc2_temp(item, params, info): check_info["fsc_sc2_temp"] = LegacyCheckDefinition( + name="fsc_sc2_temp", parse_function=parse_fsc_sc2_temp, detect=DETECT_FSC_SC2, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/fsc_sc2_voltage.py b/cmk/base/legacy_checks/fsc_sc2_voltage.py index 0a9ee599aec..23dc5183f08 100644 --- a/cmk/base/legacy_checks/fsc_sc2_voltage.py +++ b/cmk/base/legacy_checks/fsc_sc2_voltage.py @@ -104,6 +104,7 @@ def discover_fsc_sc2_voltage(section): check_info["fsc_sc2_voltage"] = LegacyCheckDefinition( + name="fsc_sc2_voltage", detect=DETECT_FSC_SC2, fetch=SNMPTree( base=".1.3.6.1.4.1.231.2.10.2.2.10.6.3.1", diff --git a/cmk/base/legacy_checks/fsc_subsystems.py b/cmk/base/legacy_checks/fsc_subsystems.py index 89dc3490877..a145aba0448 100644 --- a/cmk/base/legacy_checks/fsc_subsystems.py +++ b/cmk/base/legacy_checks/fsc_subsystems.py @@ -46,6 +46,7 @@ def parse_fsc_subsystems(string_table: StringTable) -> StringTable: check_info["fsc_subsystems"] = LegacyCheckDefinition( + name="fsc_subsystems", parse_function=parse_fsc_subsystems, detect=all_of( any_of( diff --git a/cmk/base/legacy_checks/fsc_temp.py b/cmk/base/legacy_checks/fsc_temp.py index 3c37d0b1728..16091c33ef2 100644 --- a/cmk/base/legacy_checks/fsc_temp.py +++ b/cmk/base/legacy_checks/fsc_temp.py @@ -50,6 +50,7 @@ def parse_fsc_temp(string_table: StringTable) -> StringTable: check_info["fsc_temp"] = LegacyCheckDefinition( + name="fsc_temp", parse_function=parse_fsc_temp, detect=all_of( all_of( diff --git a/cmk/base/legacy_checks/genua_carp.py b/cmk/base/legacy_checks/genua_carp.py index f4974476c62..b9f4c3ebe8a 100644 --- a/cmk/base/legacy_checks/genua_carp.py +++ b/cmk/base/legacy_checks/genua_carp.py @@ -129,6 +129,7 @@ def parse_genua_carp(string_table: Sequence[StringTable]) -> Sequence[StringTabl check_info["genua_carp"] = LegacyCheckDefinition( + name="genua_carp", parse_function=parse_genua_carp, detect=DETECT_GENUA, fetch=[ diff --git a/cmk/base/legacy_checks/genua_fan.py b/cmk/base/legacy_checks/genua_fan.py index 57e0b271a7b..6dba4a6a92d 100644 --- a/cmk/base/legacy_checks/genua_fan.py +++ b/cmk/base/legacy_checks/genua_fan.py @@ -64,6 +64,7 @@ def parse_genua_fan(string_table: Sequence[StringTable]) -> Sequence[StringTable check_info["genua_fan"] = LegacyCheckDefinition( + name="genua_fan", parse_function=parse_genua_fan, detect=DETECT_GENUA, fetch=[ diff --git a/cmk/base/legacy_checks/genua_pfstate.py b/cmk/base/legacy_checks/genua_pfstate.py index e0adfe0eb95..eb52cbe11e2 100644 --- a/cmk/base/legacy_checks/genua_pfstate.py +++ b/cmk/base/legacy_checks/genua_pfstate.py @@ -83,6 +83,7 @@ def parse_genua_pfstate(string_table: Sequence[StringTable]) -> Sequence[StringT check_info["genua_pfstate"] = LegacyCheckDefinition( + name="genua_pfstate", parse_function=parse_genua_pfstate, detect=DETECT_GENUA, fetch=[ diff --git a/cmk/base/legacy_checks/genua_state_correlation.py b/cmk/base/legacy_checks/genua_state_correlation.py index ca9c9e0cc6c..efd31c463e4 100644 --- a/cmk/base/legacy_checks/genua_state_correlation.py +++ b/cmk/base/legacy_checks/genua_state_correlation.py @@ -82,6 +82,7 @@ def parse_genua_state_correlation(string_table: Sequence[StringTable]) -> Sequen check_info["genua_state_correlation"] = LegacyCheckDefinition( + name="genua_state_correlation", parse_function=parse_genua_state_correlation, detect=DETECT_GENUA, fetch=[ diff --git a/cmk/base/legacy_checks/genua_vpn.py b/cmk/base/legacy_checks/genua_vpn.py index 53e3bcd820c..db3a6e4d2c8 100644 --- a/cmk/base/legacy_checks/genua_vpn.py +++ b/cmk/base/legacy_checks/genua_vpn.py @@ -64,6 +64,7 @@ def parse_genua_vpn(string_table: StringTable) -> StringTable: check_info["genua_vpn"] = LegacyCheckDefinition( + name="genua_vpn", parse_function=parse_genua_vpn, detect=DETECT_GENUA, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/graylog_cluster_stats.py b/cmk/base/legacy_checks/graylog_cluster_stats.py index 1bb8d9571b0..4d8a87bf983 100644 --- a/cmk/base/legacy_checks/graylog_cluster_stats.py +++ b/cmk/base/legacy_checks/graylog_cluster_stats.py @@ -81,6 +81,7 @@ def check_graylog_cluster_stats(_no_item, params, parsed): check_info["graylog_cluster_stats"] = LegacyCheckDefinition( + name="graylog_cluster_stats", parse_function=deserialize_and_merge_json, service_name="Graylog Cluster Stats", discovery_function=discover_graylog_cluster_stats, @@ -184,6 +185,7 @@ def check_graylog_cluster_stats_elastic( # pylint: disable=too-many-branches check_info["graylog_cluster_stats.elastic"] = LegacyCheckDefinition( + name="graylog_cluster_stats_elastic", service_name="Graylog Cluster Elasticsearch Stats", sections=["graylog_cluster_stats"], discovery_function=inventory_graylog_cluster_stats_elastic, @@ -258,6 +260,7 @@ def check_graylog_cluster_stats_mongodb(_no_item, params, parsed): check_info["graylog_cluster_stats.mongodb"] = LegacyCheckDefinition( + name="graylog_cluster_stats_mongodb", service_name="Graylog Cluster MongoDB Stats", sections=["graylog_cluster_stats"], discovery_function=inventory_graylog_cluster_stats_mongodb, diff --git a/cmk/base/legacy_checks/graylog_cluster_traffic.py b/cmk/base/legacy_checks/graylog_cluster_traffic.py index e3b517e33e3..98cb6a1b8f5 100644 --- a/cmk/base/legacy_checks/graylog_cluster_traffic.py +++ b/cmk/base/legacy_checks/graylog_cluster_traffic.py @@ -62,6 +62,7 @@ def check_graylog_cluster_traffic(_no_item, params, parsed): check_info["graylog_cluster_traffic"] = LegacyCheckDefinition( + name="graylog_cluster_traffic", parse_function=deserialize_and_merge_json, service_name="Graylog Cluster Traffic", discovery_function=discover_graylog_cluster_traffic, diff --git a/cmk/base/legacy_checks/graylog_jvm.py b/cmk/base/legacy_checks/graylog_jvm.py index 0d575ae2106..d5bbc9773d0 100644 --- a/cmk/base/legacy_checks/graylog_jvm.py +++ b/cmk/base/legacy_checks/graylog_jvm.py @@ -49,6 +49,7 @@ def check_graylog_jvm(_no_item, params, parsed): check_info["graylog_jvm"] = LegacyCheckDefinition( + name="graylog_jvm", parse_function=deserialize_and_merge_json, service_name="Graylog JVM", discovery_function=discover_graylog_jvm, diff --git a/cmk/base/legacy_checks/graylog_license.py b/cmk/base/legacy_checks/graylog_license.py index eae04aae166..5371a701ac7 100644 --- a/cmk/base/legacy_checks/graylog_license.py +++ b/cmk/base/legacy_checks/graylog_license.py @@ -108,6 +108,7 @@ def _handle_readable_output(value): check_info["graylog_license"] = LegacyCheckDefinition( + name="graylog_license", parse_function=parse_graylog_agent_data, service_name="Graylog License", discovery_function=inventory_graylog_license, diff --git a/cmk/base/legacy_checks/graylog_messages.py b/cmk/base/legacy_checks/graylog_messages.py index 50114e00571..9e48e8b3881 100644 --- a/cmk/base/legacy_checks/graylog_messages.py +++ b/cmk/base/legacy_checks/graylog_messages.py @@ -28,6 +28,7 @@ def check_graylog_messages(_no_item, params, parsed): check_info["graylog_messages"] = LegacyCheckDefinition( + name="graylog_messages", parse_function=parse_graylog_agent_data, service_name="Graylog Messages", discovery_function=inventory_graylog_messages, diff --git a/cmk/base/legacy_checks/graylog_nodes.py b/cmk/base/legacy_checks/graylog_nodes.py index abd37d45141..72917365002 100644 --- a/cmk/base/legacy_checks/graylog_nodes.py +++ b/cmk/base/legacy_checks/graylog_nodes.py @@ -140,6 +140,7 @@ def check_graylog_nodes(item, params, parsed): # pylint: disable=too-many-branc check_info["graylog_nodes"] = LegacyCheckDefinition( + name="graylog_nodes", parse_function=parse_graylog_nodes, service_name="Graylog Node %s", discovery_function=inventory_graylog_nodes, diff --git a/cmk/base/legacy_checks/graylog_sidecars.py b/cmk/base/legacy_checks/graylog_sidecars.py index 9a8523e469e..f16840f797f 100644 --- a/cmk/base/legacy_checks/graylog_sidecars.py +++ b/cmk/base/legacy_checks/graylog_sidecars.py @@ -160,6 +160,7 @@ def discover_graylog_sidecars(section): check_info["graylog_sidecars"] = LegacyCheckDefinition( + name="graylog_sidecars", parse_function=parse_graylog_sidecars, service_name="Graylog Sidecar %s", discovery_function=discover_graylog_sidecars, diff --git a/cmk/base/legacy_checks/graylog_sources.py b/cmk/base/legacy_checks/graylog_sources.py index e989d83cd81..6885e9d1488 100644 --- a/cmk/base/legacy_checks/graylog_sources.py +++ b/cmk/base/legacy_checks/graylog_sources.py @@ -96,6 +96,7 @@ def discover_graylog_sources(section): check_info["graylog_sources"] = LegacyCheckDefinition( + name="graylog_sources", parse_function=parse_graylog_sources, service_name="Graylog Source %s", discovery_function=discover_graylog_sources, diff --git a/cmk/base/legacy_checks/gude_humidity.py b/cmk/base/legacy_checks/gude_humidity.py index 8eb52ffa4ec..365a80d2f98 100644 --- a/cmk/base/legacy_checks/gude_humidity.py +++ b/cmk/base/legacy_checks/gude_humidity.py @@ -47,6 +47,7 @@ def check_gude_humidity( check_info["gude_humidity"] = LegacyCheckDefinition( + name="gude_humidity", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.19"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.38"), diff --git a/cmk/base/legacy_checks/gude_powerbanks.py b/cmk/base/legacy_checks/gude_powerbanks.py index 0427ae9a17f..2ec662f4100 100644 --- a/cmk/base/legacy_checks/gude_powerbanks.py +++ b/cmk/base/legacy_checks/gude_powerbanks.py @@ -76,6 +76,7 @@ def inventory_gude_powerbanks(parsed): _TABLES = (19, 38) check_info["gude_powerbanks"] = LegacyCheckDefinition( + name="gude_powerbanks", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.19"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.38"), diff --git a/cmk/base/legacy_checks/gude_relayport.py b/cmk/base/legacy_checks/gude_relayport.py index 0ce4f6d00cc..17f35e48431 100644 --- a/cmk/base/legacy_checks/gude_relayport.py +++ b/cmk/base/legacy_checks/gude_relayport.py @@ -56,6 +56,7 @@ def discover_gude_relayport(section): check_info["gude_relayport"] = LegacyCheckDefinition( + name="gude_relayport", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.38"), fetch=SNMPTree( base=".1.3.6.1.4.1.28507.38.1", diff --git a/cmk/base/legacy_checks/gude_temp.py b/cmk/base/legacy_checks/gude_temp.py index 36b6e519ed7..6c8f372a947 100644 --- a/cmk/base/legacy_checks/gude_temp.py +++ b/cmk/base/legacy_checks/gude_temp.py @@ -39,6 +39,7 @@ def check_gude_temp( check_info["gude_temp"] = LegacyCheckDefinition( + name="gude_temp", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.19"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.28507.38"), diff --git a/cmk/base/legacy_checks/h3c_lanswitch_cpu.py b/cmk/base/legacy_checks/h3c_lanswitch_cpu.py index f41d05e4fa7..61ba1d3ab0d 100644 --- a/cmk/base/legacy_checks/h3c_lanswitch_cpu.py +++ b/cmk/base/legacy_checks/h3c_lanswitch_cpu.py @@ -73,6 +73,7 @@ def parse_h3c_lanswitch_cpu(string_table: StringTable) -> StringTable: check_info["h3c_lanswitch_cpu"] = LegacyCheckDefinition( + name="h3c_lanswitch_cpu", parse_function=parse_h3c_lanswitch_cpu, detect=contains(".1.3.6.1.2.1.1.1.0", "3com s"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/h3c_lanswitch_sensors.py b/cmk/base/legacy_checks/h3c_lanswitch_sensors.py index 4ecfcc4098e..a00a63e9f65 100644 --- a/cmk/base/legacy_checks/h3c_lanswitch_sensors.py +++ b/cmk/base/legacy_checks/h3c_lanswitch_sensors.py @@ -42,6 +42,7 @@ def check_h3c_lanswitch_sensors( check_info["h3c_lanswitch_sensors"] = LegacyCheckDefinition( + name="h3c_lanswitch_sensors", detect=contains(".1.3.6.1.2.1.1.1.0", "3com s"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/heartbeat_nodes.py b/cmk/base/legacy_checks/heartbeat_nodes.py index 65fb1f5a9a0..e1c6b867330 100644 --- a/cmk/base/legacy_checks/heartbeat_nodes.py +++ b/cmk/base/legacy_checks/heartbeat_nodes.py @@ -59,6 +59,7 @@ def parse_heartbeat_nodes(string_table: StringTable) -> StringTable: check_info["heartbeat_nodes"] = LegacyCheckDefinition( + name="heartbeat_nodes", parse_function=parse_heartbeat_nodes, service_name="Heartbeat Node %s", discovery_function=inventory_heartbeat_nodes, diff --git a/cmk/base/legacy_checks/heartbeat_rscstatus.py b/cmk/base/legacy_checks/heartbeat_rscstatus.py index 14ee4ac7b6a..cc5de1c4344 100644 --- a/cmk/base/legacy_checks/heartbeat_rscstatus.py +++ b/cmk/base/legacy_checks/heartbeat_rscstatus.py @@ -44,6 +44,7 @@ def check_heartbeat_rscstatus(_no_item, params, heartbeat_rsc_status): check_info["heartbeat_rscstatus"] = LegacyCheckDefinition( + name="heartbeat_rscstatus", parse_function=parse_heartbeat_rscstatus, service_name="Heartbeat Ressource Status", discovery_function=inventory_heartbeat_rscstatus, diff --git a/cmk/base/legacy_checks/hepta.py b/cmk/base/legacy_checks/hepta.py index 88613376f90..a1b0ce547cf 100644 --- a/cmk/base/legacy_checks/hepta.py +++ b/cmk/base/legacy_checks/hepta.py @@ -85,6 +85,7 @@ def check_hepta(item, params, parsed): check_info["hepta"] = LegacyCheckDefinition( + name="hepta", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12527"), fetch=[ SNMPTree( @@ -139,6 +140,7 @@ def check_hepta_time_sync(item, params, parsed): check_info["hepta.syncmoduletimesyncstate"] = LegacyCheckDefinition( + name="hepta_syncmoduletimesyncstate", service_name="%s", sections=["hepta"], discovery_function=inventory_hepta_time_sync, @@ -179,6 +181,7 @@ def check_hepta_ntpsysstratum(item, params, parsed): check_info["hepta.ntpsysstratum"] = LegacyCheckDefinition( + name="hepta_ntpsysstratum", service_name="%s", sections=["hepta"], discovery_function=inventory_hepta_ntpsysstratum, @@ -212,6 +215,7 @@ def check_hepta_syncmoduletimelocal(item, params, parsed): check_info["hepta.syncmoduletimelocal"] = LegacyCheckDefinition( + name="hepta_syncmoduletimelocal", service_name="%s", sections=["hepta"], discovery_function=inventory_hepta_syncmoduletimelocal, diff --git a/cmk/base/legacy_checks/hitachi_hnas_bossock.py b/cmk/base/legacy_checks/hitachi_hnas_bossock.py index 38cc85b29df..8221156696c 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_bossock.py +++ b/cmk/base/legacy_checks/hitachi_hnas_bossock.py @@ -37,6 +37,7 @@ def check_hitachi_hnas_bossock( check_info["hitachi_hnas_bossock"] = LegacyCheckDefinition( + name="hitachi_hnas_bossock", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.11096.6.1.1.6.7.4.1", diff --git a/cmk/base/legacy_checks/hitachi_hnas_cifs.py b/cmk/base/legacy_checks/hitachi_hnas_cifs.py index 2b757810def..46051b2edea 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_cifs.py +++ b/cmk/base/legacy_checks/hitachi_hnas_cifs.py @@ -31,6 +31,7 @@ def parse_hitachi_hnas_cifs(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_cifs"] = LegacyCheckDefinition( + name="hitachi_hnas_cifs", parse_function=parse_hitachi_hnas_cifs, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_cpu.py b/cmk/base/legacy_checks/hitachi_hnas_cpu.py index 043d606f1f6..7f4e74808f2 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_cpu.py +++ b/cmk/base/legacy_checks/hitachi_hnas_cpu.py @@ -38,6 +38,7 @@ def parse_hitachi_hnas_cpu(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_cpu"] = LegacyCheckDefinition( + name="hitachi_hnas_cpu", parse_function=parse_hitachi_hnas_cpu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_drives.py b/cmk/base/legacy_checks/hitachi_hnas_drives.py index a342aa8209e..7d2b5d122a5 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_drives.py +++ b/cmk/base/legacy_checks/hitachi_hnas_drives.py @@ -45,6 +45,7 @@ def check_hitachi_hnas_drives(_no_item, params, info): check_info["hitachi_hnas_drives"] = LegacyCheckDefinition( + name="hitachi_hnas_drives", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.11096.6.1.1.1.3.4.2.1", diff --git a/cmk/base/legacy_checks/hitachi_hnas_fan.py b/cmk/base/legacy_checks/hitachi_hnas_fan.py index b75709e47ae..692239656cd 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_fan.py +++ b/cmk/base/legacy_checks/hitachi_hnas_fan.py @@ -66,6 +66,7 @@ def parse_hitachi_hnas_fan(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_fan"] = LegacyCheckDefinition( + name="hitachi_hnas_fan", parse_function=parse_hitachi_hnas_fan, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_fpga.py b/cmk/base/legacy_checks/hitachi_hnas_fpga.py index d0407f7e47b..fa1edb037e4 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_fpga.py +++ b/cmk/base/legacy_checks/hitachi_hnas_fpga.py @@ -42,6 +42,7 @@ def parse_hitachi_hnas_fpga(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_fpga"] = LegacyCheckDefinition( + name="hitachi_hnas_fpga", parse_function=parse_hitachi_hnas_fpga, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_pnode.py b/cmk/base/legacy_checks/hitachi_hnas_pnode.py index fe0088014e9..bf8423a7405 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_pnode.py +++ b/cmk/base/legacy_checks/hitachi_hnas_pnode.py @@ -51,6 +51,7 @@ def parse_hitachi_hnas_pnode(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_pnode"] = LegacyCheckDefinition( + name="hitachi_hnas_pnode", parse_function=parse_hitachi_hnas_pnode, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_psu.py b/cmk/base/legacy_checks/hitachi_hnas_psu.py index 0e7ec1d7195..159b4f8cd8b 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_psu.py +++ b/cmk/base/legacy_checks/hitachi_hnas_psu.py @@ -50,6 +50,7 @@ def parse_hitachi_hnas_psu(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_psu"] = LegacyCheckDefinition( + name="hitachi_hnas_psu", parse_function=parse_hitachi_hnas_psu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_quorumdevice.py b/cmk/base/legacy_checks/hitachi_hnas_quorumdevice.py index 5fad973ac03..e0b0030b334 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_quorumdevice.py +++ b/cmk/base/legacy_checks/hitachi_hnas_quorumdevice.py @@ -42,6 +42,7 @@ def parse_hitachi_hnas_quorumdevice(string_table: StringTable) -> StringTable | check_info["hitachi_hnas_quorumdevice"] = LegacyCheckDefinition( + name="hitachi_hnas_quorumdevice", parse_function=parse_hitachi_hnas_quorumdevice, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_temp.py b/cmk/base/legacy_checks/hitachi_hnas_temp.py index 57d0a7b96fd..282eea63439 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_temp.py +++ b/cmk/base/legacy_checks/hitachi_hnas_temp.py @@ -59,6 +59,7 @@ def parse_hitachi_hnas_temp(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_temp"] = LegacyCheckDefinition( + name="hitachi_hnas_temp", parse_function=parse_hitachi_hnas_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hnas_vnode.py b/cmk/base/legacy_checks/hitachi_hnas_vnode.py index c403e24b5ce..3a7f01a73d8 100644 --- a/cmk/base/legacy_checks/hitachi_hnas_vnode.py +++ b/cmk/base/legacy_checks/hitachi_hnas_vnode.py @@ -57,6 +57,7 @@ def parse_hitachi_hnas_vnode(string_table: StringTable) -> StringTable: check_info["hitachi_hnas_vnode"] = LegacyCheckDefinition( + name="hitachi_hnas_vnode", parse_function=parse_hitachi_hnas_vnode, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hitachi_hus_status.py b/cmk/base/legacy_checks/hitachi_hus_status.py index e6682b70bcc..f57d4891c04 100644 --- a/cmk/base/legacy_checks/hitachi_hus_status.py +++ b/cmk/base/legacy_checks/hitachi_hus_status.py @@ -50,6 +50,7 @@ def parse_hitachi_hus_status(string_table: StringTable) -> StringTable | None: check_info["hitachi_hus_status"] = LegacyCheckDefinition( + name="hitachi_hus_status", parse_function=parse_hitachi_hus_status, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.116"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hivemanager_devices.py b/cmk/base/legacy_checks/hivemanager_devices.py index a9808d4e552..49b6f3ee234 100644 --- a/cmk/base/legacy_checks/hivemanager_devices.py +++ b/cmk/base/legacy_checks/hivemanager_devices.py @@ -97,6 +97,7 @@ def parse_hivemanager_devices(string_table: StringTable) -> StringTable: check_info["hivemanager_devices"] = LegacyCheckDefinition( + name="hivemanager_devices", parse_function=parse_hivemanager_devices, service_name="Client %s", discovery_function=inventory_hivemanager_devices, diff --git a/cmk/base/legacy_checks/hivemanager_ng_devices.py b/cmk/base/legacy_checks/hivemanager_ng_devices.py index 91493cbc3fe..f1061f59009 100644 --- a/cmk/base/legacy_checks/hivemanager_ng_devices.py +++ b/cmk/base/legacy_checks/hivemanager_ng_devices.py @@ -71,6 +71,7 @@ def check_hivemanager_ng_devices(item, params, parsed): check_info["hivemanager_ng_devices"] = LegacyCheckDefinition( + name="hivemanager_ng_devices", parse_function=parse_hivemanager_ng_devices, service_name="Client %s", discovery_function=inventory_hivemanager_ng_devices, diff --git a/cmk/base/legacy_checks/hp_blade.py b/cmk/base/legacy_checks/hp_blade.py index 5c09838b078..2e8d2ff7bd8 100644 --- a/cmk/base/legacy_checks/hp_blade.py +++ b/cmk/base/legacy_checks/hp_blade.py @@ -50,6 +50,7 @@ def parse_hp_blade(string_table: StringTable) -> StringTable: check_info["hp_blade"] = LegacyCheckDefinition( + name="hp_blade", parse_function=parse_hp_blade, detect=DETECT_HP_BLADE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_blade_blades.py b/cmk/base/legacy_checks/hp_blade_blades.py index 372f5dfbfa6..50732f0eb2f 100644 --- a/cmk/base/legacy_checks/hp_blade_blades.py +++ b/cmk/base/legacy_checks/hp_blade_blades.py @@ -92,6 +92,7 @@ def parse_hp_blade_blades(string_table: StringTable) -> StringTable: check_info["hp_blade_blades"] = LegacyCheckDefinition( + name="hp_blade_blades", parse_function=parse_hp_blade_blades, detect=DETECT_HP_BLADE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_blade_fan.py b/cmk/base/legacy_checks/hp_blade_fan.py index c6f60edcdf3..8f9ce9f775c 100644 --- a/cmk/base/legacy_checks/hp_blade_fan.py +++ b/cmk/base/legacy_checks/hp_blade_fan.py @@ -58,6 +58,7 @@ def parse_hp_blade_fan(string_table: StringTable) -> StringTable: check_info["hp_blade_fan"] = LegacyCheckDefinition( + name="hp_blade_fan", parse_function=parse_hp_blade_fan, detect=DETECT_HP_BLADE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_blade_manager.py b/cmk/base/legacy_checks/hp_blade_manager.py index a464581aa2a..62d4bc54413 100644 --- a/cmk/base/legacy_checks/hp_blade_manager.py +++ b/cmk/base/legacy_checks/hp_blade_manager.py @@ -73,6 +73,7 @@ def parse_hp_blade_manager(string_table: StringTable) -> StringTable: check_info["hp_blade_manager"] = LegacyCheckDefinition( + name="hp_blade_manager", parse_function=parse_hp_blade_manager, detect=DETECT_HP_BLADE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_blade_psu.py b/cmk/base/legacy_checks/hp_blade_psu.py index e72e44a7c3c..2c24fdacba3 100644 --- a/cmk/base/legacy_checks/hp_blade_psu.py +++ b/cmk/base/legacy_checks/hp_blade_psu.py @@ -109,6 +109,7 @@ def parse_hp_blade_psu(string_table: StringTable) -> StringTable: check_info["hp_blade_psu"] = LegacyCheckDefinition( + name="hp_blade_psu", parse_function=parse_hp_blade_psu, detect=DETECT_HP_BLADE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_eml_sum.py b/cmk/base/legacy_checks/hp_eml_sum.py index 0edf8837afc..0163ae410f4 100644 --- a/cmk/base/legacy_checks/hp_eml_sum.py +++ b/cmk/base/legacy_checks/hp_eml_sum.py @@ -45,6 +45,7 @@ def parse_hp_eml_sum(string_table: StringTable) -> StringTable: check_info["hp_eml_sum"] = LegacyCheckDefinition( + name="hp_eml_sum", parse_function=parse_hp_eml_sum, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.11.10.2.1.3.20"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_fan.py b/cmk/base/legacy_checks/hp_fan.py index 8ef11ddbfb7..61a7be57feb 100644 --- a/cmk/base/legacy_checks/hp_fan.py +++ b/cmk/base/legacy_checks/hp_fan.py @@ -35,6 +35,7 @@ def check_hp_fan(item, _no_params, parsed): check_info["hp_fan"] = LegacyCheckDefinition( + name="hp_fan", detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "hp"), any_of( diff --git a/cmk/base/legacy_checks/hp_hh3c_ext.py b/cmk/base/legacy_checks/hp_hh3c_ext.py index 1eb8e6162fc..039d998e4d7 100644 --- a/cmk/base/legacy_checks/hp_hh3c_ext.py +++ b/cmk/base/legacy_checks/hp_hh3c_ext.py @@ -66,6 +66,7 @@ def check_hp_hh3c_ext(item, params, parsed): check_info["hp_hh3c_ext"] = LegacyCheckDefinition( + name="hp_hh3c_ext", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.25506.11.1.239"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.25506.11.1.87"), @@ -140,6 +141,7 @@ def check_hp_hh3c_ext_states(item, params, parsed): check_info["hp_hh3c_ext.states"] = LegacyCheckDefinition( + name="hp_hh3c_ext_states", service_name="Status %s", sections=["hp_hh3c_ext"], discovery_function=inventory_hp_hh3c_ext_states, @@ -174,6 +176,7 @@ def check_hp_hh3c_ext_cpu(item, params, parsed): check_info["hp_hh3c_ext.cpu"] = LegacyCheckDefinition( + name="hp_hh3c_ext_cpu", service_name="CPU utilization %s", sections=["hp_hh3c_ext"], discovery_function=inventory_hp_hh3c_ext_cpu, @@ -216,6 +219,7 @@ def check_hp_hh3c_ext_mem(item, params, parsed): check_info["hp_hh3c_ext.mem"] = LegacyCheckDefinition( + name="hp_hh3c_ext_mem", service_name="Memory %s", sections=["hp_hh3c_ext"], discovery_function=inventory_hp_hh3c_ext_mem, diff --git a/cmk/base/legacy_checks/hp_mcs_sensors.py b/cmk/base/legacy_checks/hp_mcs_sensors.py index 248ed060e76..bf2df16dc51 100644 --- a/cmk/base/legacy_checks/hp_mcs_sensors.py +++ b/cmk/base/legacy_checks/hp_mcs_sensors.py @@ -62,6 +62,7 @@ def check_hp_mcs_sensors(item, params, parsed): check_info["hp_mcs_sensors"] = LegacyCheckDefinition( + name="hp_mcs_sensors", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.232.167"), fetch=SNMPTree( base=".1.3.6.1.4.1.232.167.2.4.5.2.1", @@ -89,6 +90,7 @@ def check_hp_mcs_sensors_fan(item, params, parsed): check_info["hp_mcs_sensors.fan"] = LegacyCheckDefinition( + name="hp_mcs_sensors_fan", service_name="Sensor %s", sections=["hp_mcs_sensors"], discovery_function=inventory_hp_mcs_sensors_fan, diff --git a/cmk/base/legacy_checks/hp_mcs_system.py b/cmk/base/legacy_checks/hp_mcs_system.py index ddb0ff6201b..c79f7a40cbd 100644 --- a/cmk/base/legacy_checks/hp_mcs_system.py +++ b/cmk/base/legacy_checks/hp_mcs_system.py @@ -37,6 +37,7 @@ def parse_hp_mcs_system(string_table: StringTable) -> StringTable: check_info["hp_mcs_system"] = LegacyCheckDefinition( + name="hp_mcs_system", parse_function=parse_hp_mcs_system, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.232.167"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_procurve_cpu.py b/cmk/base/legacy_checks/hp_procurve_cpu.py index ab4d5f1c026..bfa91c84806 100644 --- a/cmk/base/legacy_checks/hp_procurve_cpu.py +++ b/cmk/base/legacy_checks/hp_procurve_cpu.py @@ -32,6 +32,7 @@ def parse_hp_procurve_cpu(string_table: StringTable) -> StringTable: check_info["hp_procurve_cpu"] = LegacyCheckDefinition( + name="hp_procurve_cpu", parse_function=parse_hp_procurve_cpu, detect=any_of( contains(".1.3.6.1.2.1.1.2.0", ".11.2.3.7.11"), diff --git a/cmk/base/legacy_checks/hp_procurve_mem.py b/cmk/base/legacy_checks/hp_procurve_mem.py index af94751ae4e..90b8c4b1a56 100644 --- a/cmk/base/legacy_checks/hp_procurve_mem.py +++ b/cmk/base/legacy_checks/hp_procurve_mem.py @@ -50,6 +50,7 @@ def parse_hp_procurve_mem(string_table: StringTable) -> StringTable: check_info["hp_procurve_mem"] = LegacyCheckDefinition( + name="hp_procurve_mem", parse_function=parse_hp_procurve_mem, detect=any_of( contains(".1.3.6.1.2.1.1.2.0", ".11.2.3.7.11"), diff --git a/cmk/base/legacy_checks/hp_procurve_sensors.py b/cmk/base/legacy_checks/hp_procurve_sensors.py index 2e6e6245bc4..eb1f841f24d 100644 --- a/cmk/base/legacy_checks/hp_procurve_sensors.py +++ b/cmk/base/legacy_checks/hp_procurve_sensors.py @@ -99,6 +99,7 @@ def parse_hp_procurve_sensors(string_table: StringTable) -> StringTable: check_info["hp_procurve_sensors"] = LegacyCheckDefinition( + name="hp_procurve_sensors", parse_function=parse_hp_procurve_sensors, detect=any_of( contains(".1.3.6.1.2.1.1.2.0", ".11.2.3.7.11"), diff --git a/cmk/base/legacy_checks/hp_procurve_temp.py b/cmk/base/legacy_checks/hp_procurve_temp.py index 2fdc90d0f62..456c12f5f64 100644 --- a/cmk/base/legacy_checks/hp_procurve_temp.py +++ b/cmk/base/legacy_checks/hp_procurve_temp.py @@ -37,6 +37,7 @@ def parse_hp_procurve_temp(string_table: StringTable) -> StringTable: check_info["hp_procurve_temp"] = LegacyCheckDefinition( + name="hp_procurve_temp", parse_function=parse_hp_procurve_temp, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.11.2.3.7.11"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_proliant.py b/cmk/base/legacy_checks/hp_proliant.py index 3cbb9febe76..76d4587e5d7 100644 --- a/cmk/base/legacy_checks/hp_proliant.py +++ b/cmk/base/legacy_checks/hp_proliant.py @@ -40,6 +40,7 @@ def parse_hp_proliant(string_table: StringTable) -> StringTable: check_info["hp_proliant"] = LegacyCheckDefinition( + name="hp_proliant", parse_function=parse_hp_proliant, detect=any_of( contains(".1.3.6.1.2.1.1.2.0", "8072.3.2.10"), diff --git a/cmk/base/legacy_checks/hp_proliant_cpu.py b/cmk/base/legacy_checks/hp_proliant_cpu.py index 45b1a8fc0dd..0b7f8f0b020 100644 --- a/cmk/base/legacy_checks/hp_proliant_cpu.py +++ b/cmk/base/legacy_checks/hp_proliant_cpu.py @@ -44,6 +44,7 @@ def check_hp_proliant_cpu(item, params, info): check_info["hp_proliant_cpu"] = LegacyCheckDefinition( + name="hp_proliant_cpu", parse_function=parse_hp_proliant_cpu, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_proliant_da_cntlr.py b/cmk/base/legacy_checks/hp_proliant_da_cntlr.py index 18a9eb8e079..457e06ff4ef 100644 --- a/cmk/base/legacy_checks/hp_proliant_da_cntlr.py +++ b/cmk/base/legacy_checks/hp_proliant_da_cntlr.py @@ -90,6 +90,7 @@ def check_hp_proliant_da_cntlr(item, params, info): check_info["hp_proliant_da_cntlr"] = LegacyCheckDefinition( + name="hp_proliant_da_cntlr", parse_function=parse_hp_proliant_da_cntlr, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_proliant_raid.py b/cmk/base/legacy_checks/hp_proliant_raid.py index cf6387033c2..04d963c5dfc 100644 --- a/cmk/base/legacy_checks/hp_proliant_raid.py +++ b/cmk/base/legacy_checks/hp_proliant_raid.py @@ -86,6 +86,7 @@ def check_hp_proliant_raid(item, _no_params, parsed): check_info["hp_proliant_raid"] = LegacyCheckDefinition( + name="hp_proliant_raid", detect=DETECT, fetch=SNMPTree( base=".1.3.6.1.4.1.232.3.2.3.1.1", diff --git a/cmk/base/legacy_checks/hp_proliant_temp.py b/cmk/base/legacy_checks/hp_proliant_temp.py index dfa5becf6a3..15dd0647f8a 100644 --- a/cmk/base/legacy_checks/hp_proliant_temp.py +++ b/cmk/base/legacy_checks/hp_proliant_temp.py @@ -86,6 +86,7 @@ def check_hp_proliant_temp(item, params, info): check_info["hp_proliant_temp"] = LegacyCheckDefinition( + name="hp_proliant_temp", parse_function=parse_hp_proliant_temp, detect=DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_psu.py b/cmk/base/legacy_checks/hp_psu.py index c8204fc25b2..216ac537186 100644 --- a/cmk/base/legacy_checks/hp_psu.py +++ b/cmk/base/legacy_checks/hp_psu.py @@ -45,6 +45,7 @@ def check_hp_psu_temp(item, params, parsed): check_info["hp_psu.temp"] = LegacyCheckDefinition( + name="hp_psu_temp", service_name="Temperature Power Supply %s", sections=["hp_psu"], discovery_function=inventory_hp_psu_temp, @@ -87,6 +88,7 @@ def check_hp_psu(item, params, parsed): check_info["hp_psu"] = LegacyCheckDefinition( + name="hp_psu", detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "hp"), any_of( diff --git a/cmk/base/legacy_checks/hp_sts_drvbox.py b/cmk/base/legacy_checks/hp_sts_drvbox.py index 70ad4b5a400..60082a8db70 100644 --- a/cmk/base/legacy_checks/hp_sts_drvbox.py +++ b/cmk/base/legacy_checks/hp_sts_drvbox.py @@ -124,6 +124,7 @@ def parse_hp_sts_drvbox(string_table: StringTable) -> StringTable: check_info["hp_sts_drvbox"] = LegacyCheckDefinition( + name="hp_sts_drvbox", parse_function=parse_hp_sts_drvbox, detect=contains(".1.3.6.1.4.1.232.2.2.4.2.0", "proliant"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/hp_webmgmt_status.py b/cmk/base/legacy_checks/hp_webmgmt_status.py index 282137b0ca3..9d2d6ca6b50 100644 --- a/cmk/base/legacy_checks/hp_webmgmt_status.py +++ b/cmk/base/legacy_checks/hp_webmgmt_status.py @@ -44,6 +44,7 @@ def parse_hp_webmgmt_status(string_table: Sequence[StringTable]) -> Sequence[Str check_info["hp_webmgmt_status"] = LegacyCheckDefinition( + name="hp_webmgmt_status", parse_function=parse_hp_webmgmt_status, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.11"), diff --git a/cmk/base/legacy_checks/hpux_fchba.py b/cmk/base/legacy_checks/hpux_fchba.py index 34d006e22c2..d1f69923992 100644 --- a/cmk/base/legacy_checks/hpux_fchba.py +++ b/cmk/base/legacy_checks/hpux_fchba.py @@ -75,6 +75,7 @@ def check_hpux_fchba(item, _no_params, section): check_info["hpux_fchba"] = LegacyCheckDefinition( + name="hpux_fchba", service_name="FC HBA %s", parse_function=parse_hpux_fchba, discovery_function=inventory_hpux_fchba, diff --git a/cmk/base/legacy_checks/hpux_multipath.py b/cmk/base/legacy_checks/hpux_multipath.py index c40fd9a3037..d3ad20d1658 100644 --- a/cmk/base/legacy_checks/hpux_multipath.py +++ b/cmk/base/legacy_checks/hpux_multipath.py @@ -113,6 +113,7 @@ def check_hpux_multipath(item, params, parsed): check_info["hpux_multipath"] = LegacyCheckDefinition( + name="hpux_multipath", service_name="Multipath %s", parse_function=parse_hpux_multipath, discovery_function=inventory_hpux_multipath, diff --git a/cmk/base/legacy_checks/hpux_serviceguard.py b/cmk/base/legacy_checks/hpux_serviceguard.py index 4abe7fcbff7..b8b4268de87 100644 --- a/cmk/base/legacy_checks/hpux_serviceguard.py +++ b/cmk/base/legacy_checks/hpux_serviceguard.py @@ -58,6 +58,7 @@ def parse_hpux_serviceguard(string_table: StringTable) -> StringTable: check_info["hpux_serviceguard"] = LegacyCheckDefinition( + name="hpux_serviceguard", parse_function=parse_hpux_serviceguard, service_name="Serviceguard %s", discovery_function=inventory_hpux_serviceguard, diff --git a/cmk/base/legacy_checks/hpux_snmp_cs.py b/cmk/base/legacy_checks/hpux_snmp_cs.py index ccc2d8e2c33..3b9b965faeb 100644 --- a/cmk/base/legacy_checks/hpux_snmp_cs.py +++ b/cmk/base/legacy_checks/hpux_snmp_cs.py @@ -86,6 +86,7 @@ def parse_hpux_snmp_cs(string_table: StringTable) -> StringTable: check_info["hpux_snmp_cs"] = LegacyCheckDefinition( + name="hpux_snmp_cs", parse_function=parse_hpux_snmp_cs, detect=startswith(".1.3.6.1.2.1.1.1.0", "HP-UX"), fetch=SNMPTree( @@ -96,6 +97,7 @@ def parse_hpux_snmp_cs(string_table: StringTable) -> StringTable: check_info["hpux_snmp_cs.cpu"] = LegacyCheckDefinition( + name="hpux_snmp_cs_cpu", service_name="CPU utilization", sections=["hpux_snmp_cs"], discovery_function=inventory_hpux_snmp_cpu, diff --git a/cmk/base/legacy_checks/hpux_tunables.py b/cmk/base/legacy_checks/hpux_tunables.py index c08c6c06ab5..7a57b72161a 100644 --- a/cmk/base/legacy_checks/hpux_tunables.py +++ b/cmk/base/legacy_checks/hpux_tunables.py @@ -59,6 +59,7 @@ def parse_hpux_tunables(info): check_info["hpux_tunables"] = LegacyCheckDefinition( + name="hpux_tunables", parse_function=parse_hpux_tunables, ) @@ -127,6 +128,7 @@ def check_hpux_tunables_nkthread(_no_item, params, section): check_info["hpux_tunables.nkthread"] = LegacyCheckDefinition( + name="hpux_tunables_nkthread", service_name="Number of threads", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_nkthread, @@ -161,6 +163,7 @@ def check_hpux_tunables_nproc(_no_item, params, section): check_info["hpux_tunables.nproc"] = LegacyCheckDefinition( + name="hpux_tunables_nproc", service_name="Number of processes", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_nproc, @@ -193,6 +196,7 @@ def check_hpux_tunables_maxfiles_lim(_no_item, params, section): check_info["hpux_tunables.maxfiles_lim"] = LegacyCheckDefinition( + name="hpux_tunables_maxfiles_lim", service_name="Number of open files", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_maxfiles_lim, @@ -225,6 +229,7 @@ def check_hpux_tunables_semmni(_no_item, params, section): check_info["hpux_tunables.semmni"] = LegacyCheckDefinition( + name="hpux_tunables_semmni", service_name="Number of IPC Semaphore IDs", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_semmni, @@ -257,6 +262,7 @@ def check_hpux_tunables_shmseg(_no_item, params, section): check_info["hpux_tunables.shmseg"] = LegacyCheckDefinition( + name="hpux_tunables_shmseg", service_name="Number of shared memory segments", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_shmseg, @@ -289,6 +295,7 @@ def check_hpux_tunables_semmns(_no_item, params, section): check_info["hpux_tunables.semmns"] = LegacyCheckDefinition( + name="hpux_tunables_semmns", service_name="Number of IPC Semaphores", sections=["hpux_tunables"], discovery_function=inventory_hpux_tunables_semmns, diff --git a/cmk/base/legacy_checks/hr_cpu.py b/cmk/base/legacy_checks/hr_cpu.py index 694169bda80..e2bb2480ff6 100644 --- a/cmk/base/legacy_checks/hr_cpu.py +++ b/cmk/base/legacy_checks/hr_cpu.py @@ -45,6 +45,7 @@ def parse_hr_cpu(string_table: StringTable) -> StringTable: check_info["hr_cpu"] = LegacyCheckDefinition( + name="hr_cpu", parse_function=parse_hr_cpu, detect=ucd_hr_detection.HR, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_osn_fan.py b/cmk/base/legacy_checks/huawei_osn_fan.py index 6cb7307e4e2..11b8616d007 100644 --- a/cmk/base/legacy_checks/huawei_osn_fan.py +++ b/cmk/base/legacy_checks/huawei_osn_fan.py @@ -37,6 +37,7 @@ def parse_huawei_osn_fan(string_table: StringTable) -> StringTable: check_info["huawei_osn_fan"] = LegacyCheckDefinition( + name="huawei_osn_fan", parse_function=parse_huawei_osn_fan, detect=DETECT_HUAWEI_OSN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_osn_laser.py b/cmk/base/legacy_checks/huawei_osn_laser.py index 2fff2e98650..e9101dfd3e3 100644 --- a/cmk/base/legacy_checks/huawei_osn_laser.py +++ b/cmk/base/legacy_checks/huawei_osn_laser.py @@ -70,6 +70,7 @@ def parse_huawei_osn_laser(string_table: StringTable) -> StringTable: check_info["huawei_osn_laser"] = LegacyCheckDefinition( + name="huawei_osn_laser", parse_function=parse_huawei_osn_laser, detect=DETECT_HUAWEI_OSN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_osn_power.py b/cmk/base/legacy_checks/huawei_osn_power.py index b865a976a86..e278327dc34 100644 --- a/cmk/base/legacy_checks/huawei_osn_power.py +++ b/cmk/base/legacy_checks/huawei_osn_power.py @@ -40,6 +40,7 @@ def parse_huawei_osn_power(string_table: StringTable) -> StringTable: check_info["huawei_osn_power"] = LegacyCheckDefinition( + name="huawei_osn_power", parse_function=parse_huawei_osn_power, detect=DETECT_HUAWEI_OSN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_osn_temp.py b/cmk/base/legacy_checks/huawei_osn_temp.py index e59b2f2c79f..f9655a592bc 100644 --- a/cmk/base/legacy_checks/huawei_osn_temp.py +++ b/cmk/base/legacy_checks/huawei_osn_temp.py @@ -30,6 +30,7 @@ def parse_huawei_osn_temp(string_table: StringTable) -> StringTable: check_info["huawei_osn_temp"] = LegacyCheckDefinition( + name="huawei_osn_temp", parse_function=parse_huawei_osn_temp, detect=DETECT_HUAWEI_OSN, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_switch_cpu.py b/cmk/base/legacy_checks/huawei_switch_cpu.py index a35562e86fc..eb641d9ca8d 100644 --- a/cmk/base/legacy_checks/huawei_switch_cpu.py +++ b/cmk/base/legacy_checks/huawei_switch_cpu.py @@ -32,6 +32,7 @@ def discover_huawei_switch_cpu(section): check_info["huawei_switch_cpu"] = LegacyCheckDefinition( + name="huawei_switch_cpu", detect=DETECT_HUAWEI_SWITCH, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_switch_fan.py b/cmk/base/legacy_checks/huawei_switch_fan.py index d22546458f2..516c20ad955 100644 --- a/cmk/base/legacy_checks/huawei_switch_fan.py +++ b/cmk/base/legacy_checks/huawei_switch_fan.py @@ -51,6 +51,7 @@ def check_huawei_switch_fan(item, params, parsed): check_info["huawei_switch_fan"] = LegacyCheckDefinition( + name="huawei_switch_fan", detect=DETECT_HUAWEI_SWITCH, fetch=SNMPTree( base=".1.3.6.1.4.1.2011.5.25.31.1.1.10.1", diff --git a/cmk/base/legacy_checks/huawei_switch_mem.py b/cmk/base/legacy_checks/huawei_switch_mem.py index 17fd810ed77..14bebf4e718 100644 --- a/cmk/base/legacy_checks/huawei_switch_mem.py +++ b/cmk/base/legacy_checks/huawei_switch_mem.py @@ -38,6 +38,7 @@ def discover_huawei_switch_mem(section): check_info["huawei_switch_mem"] = LegacyCheckDefinition( + name="huawei_switch_mem", detect=DETECT_HUAWEI_SWITCH, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_switch_psu.py b/cmk/base/legacy_checks/huawei_switch_psu.py index a243090639b..e32f6579358 100644 --- a/cmk/base/legacy_checks/huawei_switch_psu.py +++ b/cmk/base/legacy_checks/huawei_switch_psu.py @@ -46,6 +46,7 @@ def check_huawei_switch_psu( check_info["huawei_switch_psu"] = LegacyCheckDefinition( + name="huawei_switch_psu", detect=DETECT_HUAWEI_SWITCH, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_switch_stack.py b/cmk/base/legacy_checks/huawei_switch_stack.py index 86ab7788454..35fbb0df0a7 100644 --- a/cmk/base/legacy_checks/huawei_switch_stack.py +++ b/cmk/base/legacy_checks/huawei_switch_stack.py @@ -53,6 +53,7 @@ def check_huawei_switch_stack(item, params, parsed): check_info["huawei_switch_stack"] = LegacyCheckDefinition( + name="huawei_switch_stack", detect=DETECT_HUAWEI_SWITCH, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_switch_temp.py b/cmk/base/legacy_checks/huawei_switch_temp.py index a64e61300bf..dceb330abef 100644 --- a/cmk/base/legacy_checks/huawei_switch_temp.py +++ b/cmk/base/legacy_checks/huawei_switch_temp.py @@ -38,6 +38,7 @@ def check_huawei_switch_temp( check_info["huawei_switch_temp"] = LegacyCheckDefinition( + name="huawei_switch_temp", detect=DETECT_HUAWEI_SWITCH, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/huawei_wlc_aps.py b/cmk/base/legacy_checks/huawei_wlc_aps.py index 30c17632ebf..bf20f2ab90b 100644 --- a/cmk/base/legacy_checks/huawei_wlc_aps.py +++ b/cmk/base/legacy_checks/huawei_wlc_aps.py @@ -90,6 +90,7 @@ def parse_huawei_wlc_aps(string_table): check_info["huawei_wlc_aps"] = LegacyCheckDefinition( + name="huawei_wlc_aps", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2011.2.240.17"), fetch=[ SNMPTree( @@ -150,6 +151,7 @@ def check_huawei_wlc_aps_status(item, params, parsed): check_info["huawei_wlc_aps.status"] = LegacyCheckDefinition( + name="huawei_wlc_aps_status", service_name="AP %s Status", sections=["huawei_wlc_aps"], discovery_function=discovery_huawei_wlc_aps_status, @@ -175,6 +177,7 @@ def check_huawei_wlc_aps_cpu(item, params, parsed): check_info["huawei_wlc_aps.cpu"] = LegacyCheckDefinition( + name="huawei_wlc_aps_cpu", service_name="AP %s CPU", sections=["huawei_wlc_aps"], discovery_function=discovery_huawei_wlc_aps_cpu, @@ -204,6 +207,7 @@ def check_huawei_wlc_aps_mem(item, params, parsed): check_info["huawei_wlc_aps.mem"] = LegacyCheckDefinition( + name="huawei_wlc_aps_mem", service_name="AP %s Memory", sections=["huawei_wlc_aps"], discovery_function=discovery_huawei_wlc_aps_mem, @@ -231,6 +235,7 @@ def check_huawei_wlc_aps_temp(item, params, parsed): check_info["huawei_wlc_aps.temp"] = LegacyCheckDefinition( + name="huawei_wlc_aps_temp", service_name="AP %s Temperature", sections=["huawei_wlc_aps"], discovery_function=discovery_huawei_wlc_aps_temp, diff --git a/cmk/base/legacy_checks/huawei_wlc_devs.py b/cmk/base/legacy_checks/huawei_wlc_devs.py index 1f05c043037..453f4d7b955 100644 --- a/cmk/base/legacy_checks/huawei_wlc_devs.py +++ b/cmk/base/legacy_checks/huawei_wlc_devs.py @@ -28,6 +28,7 @@ def parse_huawei_wlc_devs(string_table): check_info["huawei_wlc_devs"] = LegacyCheckDefinition( + name="huawei_wlc_devs", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2011.2.240.17"), fetch=SNMPTree( base=".1.3.6.1.4.1.2011.5.25.31.1.1", @@ -59,6 +60,7 @@ def check_huawei_wlc_devs_mem(item, params, parsed): check_info["huawei_wlc_devs.mem"] = LegacyCheckDefinition( + name="huawei_wlc_devs_mem", service_name="Device %s Memory", sections=["huawei_wlc_devs"], discovery_function=discovery_huawei_wlc_devs_mem, @@ -85,6 +87,7 @@ def check_huawei_wlc_devs_cpu(item, params, parsed): check_info["huawei_wlc_devs.cpu"] = LegacyCheckDefinition( + name="huawei_wlc_devs_cpu", service_name="Device %s CPU", sections=["huawei_wlc_devs"], discovery_function=discovery_huawei_wlc_devs_cpu, diff --git a/cmk/base/legacy_checks/hwg_humidity.py b/cmk/base/legacy_checks/hwg_humidity.py index 7b670823889..601b4efe5d0 100644 --- a/cmk/base/legacy_checks/hwg_humidity.py +++ b/cmk/base/legacy_checks/hwg_humidity.py @@ -30,6 +30,7 @@ def check_hwg_humidity(item, params, parsed): check_info["hwg_humidity"] = LegacyCheckDefinition( + name="hwg_humidity", detect=contains(".1.3.6.1.2.1.1.1.0", "hwg"), fetch=SNMPTree( base=".1.3.6.1.4.1.21796.4.1.3.1", @@ -44,6 +45,7 @@ def check_hwg_humidity(item, params, parsed): ) check_info["hwg_ste2.humidity"] = LegacyCheckDefinition( + name="hwg_ste2_humidity", service_name="Humidity %s", sections=["hwg_ste2"], discovery_function=inventory_hwg_humidity, diff --git a/cmk/base/legacy_checks/hwg_temp.py b/cmk/base/legacy_checks/hwg_temp.py index fa4c23c84fe..9877b6c5390 100644 --- a/cmk/base/legacy_checks/hwg_temp.py +++ b/cmk/base/legacy_checks/hwg_temp.py @@ -53,6 +53,7 @@ def check_hwg_temp(item, params, parsed): check_info["hwg_temp"] = LegacyCheckDefinition( + name="hwg_temp", detect=contains(".1.3.6.1.2.1.1.1.0", "hwg"), fetch=SNMPTree( base=".1.3.6.1.4.1.21796.4.1.3.1", @@ -67,6 +68,7 @@ def check_hwg_temp(item, params, parsed): ) check_info["hwg_ste2"] = LegacyCheckDefinition( + name="hwg_ste2", detect=contains(".1.3.6.1.2.1.1.1.0", "STE2"), fetch=SNMPTree( base=".1.3.6.1.4.1.21796.4.9.3.1", diff --git a/cmk/base/legacy_checks/hyperv_checkpoints.py b/cmk/base/legacy_checks/hyperv_checkpoints.py index 41a7d6aa9a7..4f918232320 100644 --- a/cmk/base/legacy_checks/hyperv_checkpoints.py +++ b/cmk/base/legacy_checks/hyperv_checkpoints.py @@ -52,6 +52,7 @@ def parse_hyperv_checkpoints(string_table: StringTable) -> StringTable: check_info["hyperv_checkpoints"] = LegacyCheckDefinition( + name="hyperv_checkpoints", parse_function=parse_hyperv_checkpoints, service_name="HyperV Checkpoints", discovery_function=inventory_hyperv_checkpoints, diff --git a/cmk/base/legacy_checks/hyperv_vms.py b/cmk/base/legacy_checks/hyperv_vms.py index 3fa268b27c2..f0e3964012b 100644 --- a/cmk/base/legacy_checks/hyperv_vms.py +++ b/cmk/base/legacy_checks/hyperv_vms.py @@ -170,6 +170,7 @@ def check_hyperv_vms(item, params, parsed): } check_info["hyperv_vms"] = LegacyCheckDefinition( + name="hyperv_vms", parse_function=parse_hyperv_vms, service_name="VM %s", discovery_function=inventory_hyperv_vms, diff --git a/cmk/base/legacy_checks/hyperv_vmstatus.py b/cmk/base/legacy_checks/hyperv_vmstatus.py index bd8e8c95cfc..e56a94f7806 100644 --- a/cmk/base/legacy_checks/hyperv_vmstatus.py +++ b/cmk/base/legacy_checks/hyperv_vmstatus.py @@ -36,6 +36,7 @@ def check_hyperv_vmstatus(_no_item, _no_params, parsed): check_info["hyperv_vmstatus"] = LegacyCheckDefinition( + name="hyperv_vmstatus", parse_function=parse_hyperv_vmstatus, service_name="HyperV Status", discovery_function=discover_hyperv_vmstatus, diff --git a/cmk/base/legacy_checks/ibm_imm_fan.py b/cmk/base/legacy_checks/ibm_imm_fan.py index 5dfd1b02cad..58e5c58da4c 100644 --- a/cmk/base/legacy_checks/ibm_imm_fan.py +++ b/cmk/base/legacy_checks/ibm_imm_fan.py @@ -57,6 +57,7 @@ def parse_ibm_imm_fan(string_table: StringTable) -> StringTable: check_info["ibm_imm_fan"] = LegacyCheckDefinition( + name="ibm_imm_fan", parse_function=parse_ibm_imm_fan, detect=DETECT_IBM_IMM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_imm_health.py b/cmk/base/legacy_checks/ibm_imm_health.py index 3ad2ef5cc76..5908de43ec2 100644 --- a/cmk/base/legacy_checks/ibm_imm_health.py +++ b/cmk/base/legacy_checks/ibm_imm_health.py @@ -47,6 +47,7 @@ def parse_ibm_imm_health(string_table: StringTable) -> StringTable: check_info["ibm_imm_health"] = LegacyCheckDefinition( + name="ibm_imm_health", parse_function=parse_ibm_imm_health, detect=DETECT_IBM_IMM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_imm_voltage.py b/cmk/base/legacy_checks/ibm_imm_voltage.py index d3ff436f551..70003118ca2 100644 --- a/cmk/base/legacy_checks/ibm_imm_voltage.py +++ b/cmk/base/legacy_checks/ibm_imm_voltage.py @@ -50,6 +50,7 @@ def parse_ibm_imm_voltage(string_table: StringTable) -> StringTable: check_info["ibm_imm_voltage"] = LegacyCheckDefinition( + name="ibm_imm_voltage", parse_function=parse_ibm_imm_voltage, detect=DETECT_IBM_IMM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_mq_channels.py b/cmk/base/legacy_checks/ibm_mq_channels.py index 01dd272fd95..d8c29797ce4 100644 --- a/cmk/base/legacy_checks/ibm_mq_channels.py +++ b/cmk/base/legacy_checks/ibm_mq_channels.py @@ -76,6 +76,7 @@ def check_ibm_mq_channels(item, params, parsed): check_info["ibm_mq_channels"] = LegacyCheckDefinition( + name="ibm_mq_channels", service_name="IBM MQ Channel %s", discovery_function=inventory_ibm_mq_channels, check_function=check_ibm_mq_channels, diff --git a/cmk/base/legacy_checks/ibm_mq_managers.py b/cmk/base/legacy_checks/ibm_mq_managers.py index 0d2168752e7..bedc5496a43 100644 --- a/cmk/base/legacy_checks/ibm_mq_managers.py +++ b/cmk/base/legacy_checks/ibm_mq_managers.py @@ -118,6 +118,7 @@ def check_ibm_mq_managers(item, params, parsed): # pylint: disable=too-many-bra check_info["ibm_mq_managers"] = LegacyCheckDefinition( + name="ibm_mq_managers", service_name="IBM MQ Manager %s", discovery_function=inventory_ibm_mq_managers, check_function=check_ibm_mq_managers, diff --git a/cmk/base/legacy_checks/ibm_mq_plugin.py b/cmk/base/legacy_checks/ibm_mq_plugin.py index 9c4608a6150..b9bc680348d 100644 --- a/cmk/base/legacy_checks/ibm_mq_plugin.py +++ b/cmk/base/legacy_checks/ibm_mq_plugin.py @@ -50,6 +50,7 @@ def check_ibm_mq_plugin(_no_item, params, parsed): check_info["ibm_mq_plugin"] = LegacyCheckDefinition( + name="ibm_mq_plugin", parse_function=parse_ibm_mq_plugin, service_name="IBM MQ Plugin", discovery_function=inventory_ibm_mq_plugin, diff --git a/cmk/base/legacy_checks/ibm_mq_queues.py b/cmk/base/legacy_checks/ibm_mq_queues.py index b79f103acf8..ba9f747558f 100644 --- a/cmk/base/legacy_checks/ibm_mq_queues.py +++ b/cmk/base/legacy_checks/ibm_mq_queues.py @@ -189,6 +189,7 @@ def ibm_mq_get_qtime(qtime, label, key): check_info["ibm_mq_queues"] = LegacyCheckDefinition( + name="ibm_mq_queues", service_name="IBM MQ Queue %s", discovery_function=inventory_ibm_mq_queues, check_function=check_ibm_mq_queues, diff --git a/cmk/base/legacy_checks/ibm_rsa_health.py b/cmk/base/legacy_checks/ibm_rsa_health.py index 9980611d4d7..f2d56833a0f 100644 --- a/cmk/base/legacy_checks/ibm_rsa_health.py +++ b/cmk/base/legacy_checks/ibm_rsa_health.py @@ -53,6 +53,7 @@ def parse_ibm_rsa_health(string_table: StringTable) -> StringTable: check_info["ibm_rsa_health"] = LegacyCheckDefinition( + name="ibm_rsa_health", parse_function=parse_ibm_rsa_health, detect=contains(".1.3.6.1.2.1.1.1.0", "Remote Supervisor Adapter"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_storage_ts.py b/cmk/base/legacy_checks/ibm_storage_ts.py index 50fd3f33af8..380141eadae 100644 --- a/cmk/base/legacy_checks/ibm_storage_ts.py +++ b/cmk/base/legacy_checks/ibm_storage_ts.py @@ -26,6 +26,7 @@ def parse_ibm_storage_ts(string_table: Sequence[StringTable]) -> Sequence[String check_info["ibm_storage_ts"] = LegacyCheckDefinition( + name="ibm_storage_ts", parse_function=parse_ibm_storage_ts, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2.6.210"), fetch=[ @@ -86,6 +87,7 @@ def check_ibm_storage_ts_status(_no_item, _no_params, info): check_info["ibm_storage_ts.status"] = LegacyCheckDefinition( + name="ibm_storage_ts_status", service_name="Status", sections=["ibm_storage_ts"], discovery_function=inventory_ibm_storage_ts_status, @@ -120,6 +122,7 @@ def worst_status(*args): check_info["ibm_storage_ts.library"] = LegacyCheckDefinition( + name="ibm_storage_ts_library", service_name="Library %s", sections=["ibm_storage_ts"], discovery_function=inventory_ibm_storage_ts_library, @@ -149,6 +152,7 @@ def check_ibm_storage_ts_drive(item, params, info): check_info["ibm_storage_ts.drive"] = LegacyCheckDefinition( + name="ibm_storage_ts_drive", service_name="Drive %s", sections=["ibm_storage_ts"], discovery_function=inventory_ibm_storage_ts_drive, diff --git a/cmk/base/legacy_checks/ibm_svc_array.py b/cmk/base/legacy_checks/ibm_svc_array.py index 8fce8d93784..ca10713cd8c 100644 --- a/cmk/base/legacy_checks/ibm_svc_array.py +++ b/cmk/base/legacy_checks/ibm_svc_array.py @@ -70,6 +70,7 @@ def discover_ibm_svc_array(section): check_info["ibm_svc_array"] = LegacyCheckDefinition( + name="ibm_svc_array", parse_function=parse_ibm_svc_array, service_name="RAID Array %s", discovery_function=discover_ibm_svc_array, diff --git a/cmk/base/legacy_checks/ibm_svc_disks.py b/cmk/base/legacy_checks/ibm_svc_disks.py index 5230f2446ae..3bd49da42a6 100644 --- a/cmk/base/legacy_checks/ibm_svc_disks.py +++ b/cmk/base/legacy_checks/ibm_svc_disks.py @@ -105,6 +105,7 @@ def check_ibm_svc_disks(_no_item, params, parsed): check_info["ibm_svc_disks"] = LegacyCheckDefinition( + name="ibm_svc_disks", parse_function=parse_ibm_svc_disks, service_name="Disk Summary", discovery_function=discover_ibm_svc_disks, diff --git a/cmk/base/legacy_checks/ibm_svc_enclosure.py b/cmk/base/legacy_checks/ibm_svc_enclosure.py index 93842df78f8..ac39afcd686 100644 --- a/cmk/base/legacy_checks/ibm_svc_enclosure.py +++ b/cmk/base/legacy_checks/ibm_svc_enclosure.py @@ -100,6 +100,7 @@ def discover_ibm_svc_enclosure(section): check_info["ibm_svc_enclosure"] = LegacyCheckDefinition( + name="ibm_svc_enclosure", parse_function=parse_ibm_svc_enclosure, service_name="Enclosure %s", discovery_function=discover_ibm_svc_enclosure, diff --git a/cmk/base/legacy_checks/ibm_svc_enclosurestats.py b/cmk/base/legacy_checks/ibm_svc_enclosurestats.py index 72cef16632b..c9b25ece668 100644 --- a/cmk/base/legacy_checks/ibm_svc_enclosurestats.py +++ b/cmk/base/legacy_checks/ibm_svc_enclosurestats.py @@ -47,6 +47,7 @@ def parse_ibm_svc_enclosurestats(info): check_info["ibm_svc_enclosurestats"] = LegacyCheckDefinition( + name="ibm_svc_enclosurestats", parse_function=parse_ibm_svc_enclosurestats, ) @@ -74,6 +75,7 @@ def check_ibm_svc_enclosurestats_temp(item, params, section): check_info["ibm_svc_enclosurestats.temp"] = LegacyCheckDefinition( + name="ibm_svc_enclosurestats_temp", service_name="Temperature Enclosure %s", sections=["ibm_svc_enclosurestats"], discovery_function=inventory_ibm_svc_enclosurestats_temp, @@ -108,6 +110,7 @@ def check_ibm_svc_enclosurestats_power(item, _no_params, section): check_info["ibm_svc_enclosurestats.power"] = LegacyCheckDefinition( + name="ibm_svc_enclosurestats_power", service_name="Power Enclosure %s", sections=["ibm_svc_enclosurestats"], discovery_function=inventory_ibm_svc_enclosurestats_power, diff --git a/cmk/base/legacy_checks/ibm_svc_eventlog.py b/cmk/base/legacy_checks/ibm_svc_eventlog.py index a4ba8e9ad99..9c03e57512b 100644 --- a/cmk/base/legacy_checks/ibm_svc_eventlog.py +++ b/cmk/base/legacy_checks/ibm_svc_eventlog.py @@ -60,6 +60,7 @@ def parse_ibm_svc_eventlog(string_table: StringTable) -> StringTable: check_info["ibm_svc_eventlog"] = LegacyCheckDefinition( + name="ibm_svc_eventlog", parse_function=parse_ibm_svc_eventlog, service_name="Eventlog", discovery_function=inventory_ibm_svc_eventlog, diff --git a/cmk/base/legacy_checks/ibm_svc_host.py b/cmk/base/legacy_checks/ibm_svc_host.py index b59278ac02e..0ec945bc8bd 100644 --- a/cmk/base/legacy_checks/ibm_svc_host.py +++ b/cmk/base/legacy_checks/ibm_svc_host.py @@ -111,6 +111,7 @@ def check_ibm_svc_host(item, params, parsed): # pylint: disable=too-many-branch check_info["ibm_svc_host"] = LegacyCheckDefinition( + name="ibm_svc_host", parse_function=parse_ibm_svc_host, service_name="Hosts", discovery_function=discover_ibm_svc_host, diff --git a/cmk/base/legacy_checks/ibm_svc_license.py b/cmk/base/legacy_checks/ibm_svc_license.py index 039fd71a4c4..126acdbec07 100644 --- a/cmk/base/legacy_checks/ibm_svc_license.py +++ b/cmk/base/legacy_checks/ibm_svc_license.py @@ -56,6 +56,7 @@ def check_ibm_svc_license(item, params, parsed): check_info["ibm_svc_license"] = LegacyCheckDefinition( + name="ibm_svc_license", parse_function=parse_ibm_svc_license, service_name="License %s", discovery_function=inventory_ibm_svc_license, diff --git a/cmk/base/legacy_checks/ibm_svc_mdisk.py b/cmk/base/legacy_checks/ibm_svc_mdisk.py index 339991a5992..fda1d17ab66 100644 --- a/cmk/base/legacy_checks/ibm_svc_mdisk.py +++ b/cmk/base/legacy_checks/ibm_svc_mdisk.py @@ -69,6 +69,7 @@ def check_ibm_svc_mdisk(item, params, parsed): check_info["ibm_svc_mdisk"] = LegacyCheckDefinition( + name="ibm_svc_mdisk", parse_function=parse_ibm_svc_mdisk, service_name="MDisk %s", discovery_function=inventory_ibm_svc_mdisk, diff --git a/cmk/base/legacy_checks/ibm_svc_mdiskgrp.py b/cmk/base/legacy_checks/ibm_svc_mdiskgrp.py index 2b0b21662df..56b61670dc3 100644 --- a/cmk/base/legacy_checks/ibm_svc_mdiskgrp.py +++ b/cmk/base/legacy_checks/ibm_svc_mdiskgrp.py @@ -158,6 +158,7 @@ def check_ibm_svc_mdiskgrp(item, params, parsed): check_info["ibm_svc_mdiskgrp"] = LegacyCheckDefinition( + name="ibm_svc_mdiskgrp", parse_function=parse_ibm_svc_mdiskgrp, service_name="Pool Capacity %s", discovery_function=inventory_ibm_svc_mdiskgrp, diff --git a/cmk/base/legacy_checks/ibm_svc_node.py b/cmk/base/legacy_checks/ibm_svc_node.py index 037d84e8830..7898e35bdd1 100644 --- a/cmk/base/legacy_checks/ibm_svc_node.py +++ b/cmk/base/legacy_checks/ibm_svc_node.py @@ -84,6 +84,7 @@ def discover_ibm_svc_node(section): check_info["ibm_svc_node"] = LegacyCheckDefinition( + name="ibm_svc_node", parse_function=parse_ibm_svc_node, service_name="IO Group %s", discovery_function=discover_ibm_svc_node, diff --git a/cmk/base/legacy_checks/ibm_svc_nodestats.py b/cmk/base/legacy_checks/ibm_svc_nodestats.py index 9493dca56d8..91d1ae0455e 100644 --- a/cmk/base/legacy_checks/ibm_svc_nodestats.py +++ b/cmk/base/legacy_checks/ibm_svc_nodestats.py @@ -159,6 +159,7 @@ def parse_ibm_svc_nodestats(info): check_info["ibm_svc_nodestats"] = LegacyCheckDefinition( + name="ibm_svc_nodestats", parse_function=parse_ibm_svc_nodestats, ) @@ -197,6 +198,7 @@ def check_ibm_svc_nodestats_diskio(item, _no_params, section): check_info["ibm_svc_nodestats.diskio"] = LegacyCheckDefinition( + name="ibm_svc_nodestats_diskio", service_name="Disk IO %s", sections=["ibm_svc_nodestats"], discovery_function=inventory_ibm_svc_nodestats_diskio, @@ -235,6 +237,7 @@ def check_ibm_svc_nodestats_iops(item, _no_params, section): check_info["ibm_svc_nodestats.iops"] = LegacyCheckDefinition( + name="ibm_svc_nodestats_iops", service_name="Disk IOPS %s", sections=["ibm_svc_nodestats"], discovery_function=inventory_ibm_svc_nodestats_iops, @@ -273,6 +276,7 @@ def check_ibm_svc_nodestats_disk_latency(item, _no_params, section): check_info["ibm_svc_nodestats.disk_latency"] = LegacyCheckDefinition( + name="ibm_svc_nodestats_disk_latency", service_name="Disk Latency %s", sections=["ibm_svc_nodestats"], discovery_function=inventory_ibm_svc_nodestats_disk_latency, @@ -303,6 +307,7 @@ def check_ibm_svc_nodestats_cpu(item, params, section): check_info["ibm_svc_nodestats.cpu_util"] = LegacyCheckDefinition( + name="ibm_svc_nodestats_cpu_util", service_name="CPU utilization %s", sections=["ibm_svc_nodestats"], discovery_function=inventory_ibm_svc_nodestats_cpu, @@ -350,6 +355,7 @@ def check_ibm_svc_nodestats_cache(item, _no_params, section): check_info["ibm_svc_nodestats.cache"] = LegacyCheckDefinition( + name="ibm_svc_nodestats_cache", service_name="Cache %s", sections=["ibm_svc_nodestats"], discovery_function=inventory_ibm_svc_nodestats_cache, diff --git a/cmk/base/legacy_checks/ibm_svc_portfc.py b/cmk/base/legacy_checks/ibm_svc_portfc.py index 3c35cf4be29..c7ae70a2a36 100644 --- a/cmk/base/legacy_checks/ibm_svc_portfc.py +++ b/cmk/base/legacy_checks/ibm_svc_portfc.py @@ -96,6 +96,7 @@ def check_ibm_svc_portfc(item, _no_params, parsed): check_info["ibm_svc_portfc"] = LegacyCheckDefinition( + name="ibm_svc_portfc", parse_function=parse_ibm_svc_portfc, service_name="FC %s", discovery_function=inventory_ibm_svc_portfc, diff --git a/cmk/base/legacy_checks/ibm_svc_portsas.py b/cmk/base/legacy_checks/ibm_svc_portsas.py index 2e9989829dc..0ad9bc7cfc7 100644 --- a/cmk/base/legacy_checks/ibm_svc_portsas.py +++ b/cmk/base/legacy_checks/ibm_svc_portsas.py @@ -91,6 +91,7 @@ def check_ibm_svc_portsas(item, params, parsed): check_info["ibm_svc_portsas"] = LegacyCheckDefinition( + name="ibm_svc_portsas", parse_function=parse_ibm_svc_portsas, service_name="SAS %s", discovery_function=inventory_ibm_svc_portsas, diff --git a/cmk/base/legacy_checks/ibm_svc_system.py b/cmk/base/legacy_checks/ibm_svc_system.py index 75068be99f7..c2b82c1aa3c 100644 --- a/cmk/base/legacy_checks/ibm_svc_system.py +++ b/cmk/base/legacy_checks/ibm_svc_system.py @@ -100,6 +100,7 @@ def parse_ibm_svc_system(string_table: StringTable) -> StringTable: check_info["ibm_svc_system"] = LegacyCheckDefinition( + name="ibm_svc_system", parse_function=parse_ibm_svc_system, service_name="Info", discovery_function=inventory_ibm_svc_system, diff --git a/cmk/base/legacy_checks/ibm_tl_changer_devices.py b/cmk/base/legacy_checks/ibm_tl_changer_devices.py index b5ff1b2352c..2fee16a2d76 100644 --- a/cmk/base/legacy_checks/ibm_tl_changer_devices.py +++ b/cmk/base/legacy_checks/ibm_tl_changer_devices.py @@ -34,6 +34,7 @@ def parse_ibm_tl_changer_devices(string_table: StringTable) -> StringTable: check_info["ibm_tl_changer_devices"] = LegacyCheckDefinition( + name="ibm_tl_changer_devices", parse_function=parse_ibm_tl_changer_devices, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.32925.1"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_tl_media_access_devices.py b/cmk/base/legacy_checks/ibm_tl_media_access_devices.py index 02f8bbce86b..3317af4e0e3 100644 --- a/cmk/base/legacy_checks/ibm_tl_media_access_devices.py +++ b/cmk/base/legacy_checks/ibm_tl_media_access_devices.py @@ -76,6 +76,7 @@ def check_ibm_tl_media_access_devices(item, params, parsed): check_info["ibm_tl_media_access_devices"] = LegacyCheckDefinition( + name="ibm_tl_media_access_devices", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.32925.1"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/ibm_xraid_pdisks.py b/cmk/base/legacy_checks/ibm_xraid_pdisks.py index 4440bbfff93..e8ce8918198 100644 --- a/cmk/base/legacy_checks/ibm_xraid_pdisks.py +++ b/cmk/base/legacy_checks/ibm_xraid_pdisks.py @@ -47,6 +47,7 @@ def check_ibm_xraid_pdisks(item, _no_params, section): check_info["ibm_xraid_pdisks"] = LegacyCheckDefinition( + name="ibm_xraid_pdisks", detect=all_of( any_of( equals(".1.3.6.1.2.1.1.1.0", "software: windows"), equals(".1.3.6.1.2.1.1.1.0", "linux") diff --git a/cmk/base/legacy_checks/icom_repeater.py b/cmk/base/legacy_checks/icom_repeater.py index 8e2a2c09c00..e9f83a93ade 100644 --- a/cmk/base/legacy_checks/icom_repeater.py +++ b/cmk/base/legacy_checks/icom_repeater.py @@ -107,6 +107,7 @@ def check_icom_repeater_ps_volt(_no_item, params, parsed): check_info["icom_repeater.ps_volt"] = LegacyCheckDefinition( + name="icom_repeater_ps_volt", service_name="Power Supply Voltage", sections=["icom_repeater"], discovery_function=inventory_icom_repeater_ps_volt, @@ -174,6 +175,7 @@ def check_icom_repeater_pll_volt(item, params, parsed): check_info["icom_repeater.pll_volt"] = LegacyCheckDefinition( + name="icom_repeater_pll_volt", service_name="%s PLL Lock Voltage", sections=["icom_repeater"], discovery_function=inventory_icom_repeater_pll_volt, @@ -211,6 +213,7 @@ def check_icom_repeater_temp(_no_item, params, parsed): check_info["icom_repeater.temp"] = LegacyCheckDefinition( + name="icom_repeater_temp", service_name="Temperature %s", sections=["icom_repeater"], discovery_function=inventory_icom_repeater_temp, @@ -254,6 +257,7 @@ def check_icom_repeater(_no_item, _no_params, parsed): check_info["icom_repeater"] = LegacyCheckDefinition( + name="icom_repeater", detect=contains(".1.3.6.1.2.1.1.1.0", "fr5000"), fetch=SNMPTree( base=".1.3.6.1.4.1.2021.8.1", diff --git a/cmk/base/legacy_checks/infoblox_dhcp_stats.py b/cmk/base/legacy_checks/infoblox_dhcp_stats.py index e2d722f7e4d..a793017e343 100644 --- a/cmk/base/legacy_checks/infoblox_dhcp_stats.py +++ b/cmk/base/legacy_checks/infoblox_dhcp_stats.py @@ -52,6 +52,7 @@ def parse_infoblox_dhcp_stats(string_table: StringTable) -> StringTable | None: check_info["infoblox_dhcp_stats"] = LegacyCheckDefinition( + name="infoblox_dhcp_stats", parse_function=parse_infoblox_dhcp_stats, detect=DETECT_INFOBLOX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/infoblox_dns_stats.py b/cmk/base/legacy_checks/infoblox_dns_stats.py index c9345b1dc80..0f90f0ee804 100644 --- a/cmk/base/legacy_checks/infoblox_dns_stats.py +++ b/cmk/base/legacy_checks/infoblox_dns_stats.py @@ -42,6 +42,7 @@ def parse_infoblox_dns_stats(string_table: StringTable) -> StringTable | None: check_info["infoblox_dns_stats"] = LegacyCheckDefinition( + name="infoblox_dns_stats", parse_function=parse_infoblox_dns_stats, detect=DETECT_INFOBLOX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/infoblox_grid_status.py b/cmk/base/legacy_checks/infoblox_grid_status.py index 6830d315ffb..6a97fb3b156 100644 --- a/cmk/base/legacy_checks/infoblox_grid_status.py +++ b/cmk/base/legacy_checks/infoblox_grid_status.py @@ -33,6 +33,7 @@ def parse_infoblox_grid_status(string_table: StringTable) -> StringTable | None: check_info["infoblox_grid_status"] = LegacyCheckDefinition( + name="infoblox_grid_status", parse_function=parse_infoblox_grid_status, detect=DETECT_INFOBLOX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/infoblox_replication_status.py b/cmk/base/legacy_checks/infoblox_replication_status.py index 54410d2f433..ebd2ca77d76 100644 --- a/cmk/base/legacy_checks/infoblox_replication_status.py +++ b/cmk/base/legacy_checks/infoblox_replication_status.py @@ -58,6 +58,7 @@ def parse_infoblox_replication_status(string_table: StringTable) -> StringTable: check_info["infoblox_replication_status"] = LegacyCheckDefinition( + name="infoblox_replication_status", parse_function=parse_infoblox_replication_status, detect=DETECT_INFOBLOX, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/informix_dbspaces.py b/cmk/base/legacy_checks/informix_dbspaces.py index 7549aa2ef11..d12d1426535 100644 --- a/cmk/base/legacy_checks/informix_dbspaces.py +++ b/cmk/base/legacy_checks/informix_dbspaces.py @@ -88,6 +88,7 @@ def check_informix_dbspaces(item, params, parsed): check_info["informix_dbspaces"] = LegacyCheckDefinition( + name="informix_dbspaces", parse_function=parse_informix_dbspaces, service_name="Informix Tablespace %s", discovery_function=inventory_informix_dbspaces, diff --git a/cmk/base/legacy_checks/informix_locks.py b/cmk/base/legacy_checks/informix_locks.py index 47360e78e09..d70b9f56e2f 100644 --- a/cmk/base/legacy_checks/informix_locks.py +++ b/cmk/base/legacy_checks/informix_locks.py @@ -45,6 +45,7 @@ def check_informix_locks(item, params, parsed): check_info["informix_locks"] = LegacyCheckDefinition( + name="informix_locks", parse_function=parse_informix_locks, service_name="Informix Locks %s", discovery_function=inventory_informix_locks, diff --git a/cmk/base/legacy_checks/informix_logusage.py b/cmk/base/legacy_checks/informix_logusage.py index 253571f917c..cf71fb72896 100644 --- a/cmk/base/legacy_checks/informix_logusage.py +++ b/cmk/base/legacy_checks/informix_logusage.py @@ -98,6 +98,7 @@ def check_informix_logusage(item, params, parsed): check_info["informix_logusage"] = LegacyCheckDefinition( + name="informix_logusage", parse_function=parse_informix_logusage, service_name="Informix Log Usage %s", discovery_function=inventory_informix_logusage, diff --git a/cmk/base/legacy_checks/informix_sessions.py b/cmk/base/legacy_checks/informix_sessions.py index 6706cc176f6..d97379f29d4 100644 --- a/cmk/base/legacy_checks/informix_sessions.py +++ b/cmk/base/legacy_checks/informix_sessions.py @@ -46,6 +46,7 @@ def check_informix_sessions(item, params, parsed): check_info["informix_sessions"] = LegacyCheckDefinition( + name="informix_sessions", parse_function=parse_informix_sessions, service_name="Informix Sessions %s", discovery_function=inventory_informix_sessions, diff --git a/cmk/base/legacy_checks/informix_status.py b/cmk/base/legacy_checks/informix_status.py index 5eb2316ec57..0fef3c87537 100644 --- a/cmk/base/legacy_checks/informix_status.py +++ b/cmk/base/legacy_checks/informix_status.py @@ -60,6 +60,7 @@ def check_informix_status(item, params, parsed): check_info["informix_status"] = LegacyCheckDefinition( + name="informix_status", parse_function=parse_informix_status, service_name="Informix Instance %s", discovery_function=inventory_informix_status, diff --git a/cmk/base/legacy_checks/informix_tabextents.py b/cmk/base/legacy_checks/informix_tabextents.py index 9a4a800d51b..286fb59da0f 100644 --- a/cmk/base/legacy_checks/informix_tabextents.py +++ b/cmk/base/legacy_checks/informix_tabextents.py @@ -65,6 +65,7 @@ def check_informix_tabextents(item, params, parsed): check_info["informix_tabextents"] = LegacyCheckDefinition( + name="informix_tabextents", parse_function=parse_informix_tabextents, service_name="Informix Table Extents %s", discovery_function=inventory_informix_tabextents, diff --git a/cmk/base/legacy_checks/innovaphone_channels.py b/cmk/base/legacy_checks/innovaphone_channels.py index c11613f6155..8f9c6c70913 100644 --- a/cmk/base/legacy_checks/innovaphone_channels.py +++ b/cmk/base/legacy_checks/innovaphone_channels.py @@ -35,6 +35,7 @@ def parse_innovaphone_channels(string_table: StringTable) -> StringTable: check_info["innovaphone_channels"] = LegacyCheckDefinition( + name="innovaphone_channels", parse_function=parse_innovaphone_channels, service_name="Channel %s", discovery_function=discover_innovaphone_channels, diff --git a/cmk/base/legacy_checks/innovaphone_cpu.py b/cmk/base/legacy_checks/innovaphone_cpu.py index f110d65827b..cf55cfe3a7a 100644 --- a/cmk/base/legacy_checks/innovaphone_cpu.py +++ b/cmk/base/legacy_checks/innovaphone_cpu.py @@ -38,6 +38,7 @@ def parse_innovaphone_cpu(string_table: StringTable) -> StringTable: check_info["innovaphone_cpu"] = LegacyCheckDefinition( + name="innovaphone_cpu", parse_function=parse_innovaphone_cpu, service_name="CPU utilization", discovery_function=inventory_innovaphone_cpu, diff --git a/cmk/base/legacy_checks/innovaphone_licenses.py b/cmk/base/legacy_checks/innovaphone_licenses.py index f976d353538..6b2baa6ced3 100644 --- a/cmk/base/legacy_checks/innovaphone_licenses.py +++ b/cmk/base/legacy_checks/innovaphone_licenses.py @@ -49,6 +49,7 @@ def parse_innovaphone_licenses(string_table: StringTable) -> StringTable: check_info["innovaphone_licenses"] = LegacyCheckDefinition( + name="innovaphone_licenses", parse_function=parse_innovaphone_licenses, service_name="Licenses", discovery_function=discover_innovaphone_licenses, diff --git a/cmk/base/legacy_checks/innovaphone_mem.py b/cmk/base/legacy_checks/innovaphone_mem.py index 6d1eeb4a1ba..47ce06b0532 100644 --- a/cmk/base/legacy_checks/innovaphone_mem.py +++ b/cmk/base/legacy_checks/innovaphone_mem.py @@ -29,6 +29,7 @@ def parse_innovaphone_mem(string_table: StringTable) -> StringTable: check_info["innovaphone_mem"] = LegacyCheckDefinition( + name="innovaphone_mem", parse_function=parse_innovaphone_mem, service_name="Memory", discovery_function=inventory_innovaphone_mem, diff --git a/cmk/base/legacy_checks/innovaphone_priports_l1.py b/cmk/base/legacy_checks/innovaphone_priports_l1.py index a1e33598ee3..39c248dfefb 100644 --- a/cmk/base/legacy_checks/innovaphone_priports_l1.py +++ b/cmk/base/legacy_checks/innovaphone_priports_l1.py @@ -72,6 +72,7 @@ def check_innovaphone_priports_l1(item, params, parsed): check_info["innovaphone_priports_l1"] = LegacyCheckDefinition( + name="innovaphone_priports_l1", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.6666"), fetch=SNMPTree( base=".1.3.6.1.4.1.6666.1.2.1", diff --git a/cmk/base/legacy_checks/innovaphone_priports_l2.py b/cmk/base/legacy_checks/innovaphone_priports_l2.py index 7a394ea5a13..b63d1eb8046 100644 --- a/cmk/base/legacy_checks/innovaphone_priports_l2.py +++ b/cmk/base/legacy_checks/innovaphone_priports_l2.py @@ -70,6 +70,7 @@ def parse_innovaphone_priports_l2(string_table: StringTable) -> StringTable: check_info["innovaphone_priports_l2"] = LegacyCheckDefinition( + name="innovaphone_priports_l2", parse_function=parse_innovaphone_priports_l2, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.6666"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/innovaphone_temp.py b/cmk/base/legacy_checks/innovaphone_temp.py index c4280b09d13..94a869298de 100644 --- a/cmk/base/legacy_checks/innovaphone_temp.py +++ b/cmk/base/legacy_checks/innovaphone_temp.py @@ -24,6 +24,7 @@ def parse_innovaphone_temp(string_table: StringTable) -> StringTable: check_info["innovaphone_temp"] = LegacyCheckDefinition( + name="innovaphone_temp", parse_function=parse_innovaphone_temp, service_name="Temperature %s", discovery_function=inventory_innovaphone_temp, diff --git a/cmk/base/legacy_checks/intel_true_scale_chassis_temp.py b/cmk/base/legacy_checks/intel_true_scale_chassis_temp.py index e0a27ef24a2..72814f906a9 100644 --- a/cmk/base/legacy_checks/intel_true_scale_chassis_temp.py +++ b/cmk/base/legacy_checks/intel_true_scale_chassis_temp.py @@ -48,6 +48,7 @@ def parse_intel_true_scale_chassis_temp(string_table: StringTable) -> StringTabl check_info["intel_true_scale_chassis_temp"] = LegacyCheckDefinition( + name="intel_true_scale_chassis_temp", parse_function=parse_intel_true_scale_chassis_temp, detect=DETECT_INTEL_TRUE_SCALE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/intel_true_scale_fans.py b/cmk/base/legacy_checks/intel_true_scale_fans.py index 28811ba9e63..1fe207bcbea 100644 --- a/cmk/base/legacy_checks/intel_true_scale_fans.py +++ b/cmk/base/legacy_checks/intel_true_scale_fans.py @@ -82,6 +82,7 @@ def parse_intel_true_scale_fans(string_table: StringTable) -> StringTable: check_info["intel_true_scale_fans"] = LegacyCheckDefinition( + name="intel_true_scale_fans", parse_function=parse_intel_true_scale_fans, detect=DETECT_INTEL_TRUE_SCALE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/intel_true_scale_psus.py b/cmk/base/legacy_checks/intel_true_scale_psus.py index 617e6727bde..451092e8af7 100644 --- a/cmk/base/legacy_checks/intel_true_scale_psus.py +++ b/cmk/base/legacy_checks/intel_true_scale_psus.py @@ -89,6 +89,7 @@ def check_intel_true_scale_psus(item, params, parsed): check_info["intel_true_scale_psus"] = LegacyCheckDefinition( + name="intel_true_scale_psus", detect=DETECT_INTEL_TRUE_SCALE, fetch=SNMPTree( base=".1.3.6.1.4.1.10222.2.1.4.7.1", diff --git a/cmk/base/legacy_checks/intel_true_scale_sensors_temp.py b/cmk/base/legacy_checks/intel_true_scale_sensors_temp.py index a396869a337..fd1e1fdd49b 100644 --- a/cmk/base/legacy_checks/intel_true_scale_sensors_temp.py +++ b/cmk/base/legacy_checks/intel_true_scale_sensors_temp.py @@ -131,6 +131,7 @@ def check_intel_true_scale_sensors_temp(item, params, parsed): check_info["intel_true_scale_sensors_temp"] = LegacyCheckDefinition( + name="intel_true_scale_sensors_temp", detect=DETECT_INTEL_TRUE_SCALE, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/ipr400_in_voltage.py b/cmk/base/legacy_checks/ipr400_in_voltage.py index fe2702bfaf7..de2919dc80c 100644 --- a/cmk/base/legacy_checks/ipr400_in_voltage.py +++ b/cmk/base/legacy_checks/ipr400_in_voltage.py @@ -34,6 +34,7 @@ def parse_ipr400_in_voltage(string_table: StringTable) -> StringTable: check_info["ipr400_in_voltage"] = LegacyCheckDefinition( + name="ipr400_in_voltage", parse_function=parse_ipr400_in_voltage, detect=startswith(".1.3.6.1.2.1.1.1.0", "ipr voip device ipr400"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ipr400_temp.py b/cmk/base/legacy_checks/ipr400_temp.py index 30ab2f173ab..8548d3fcf09 100644 --- a/cmk/base/legacy_checks/ipr400_temp.py +++ b/cmk/base/legacy_checks/ipr400_temp.py @@ -25,6 +25,7 @@ def parse_ipr400_temp(string_table: StringTable) -> StringTable: check_info["ipr400_temp"] = LegacyCheckDefinition( + name="ipr400_temp", parse_function=parse_ipr400_temp, detect=startswith(".1.3.6.1.2.1.1.1.0", "ipr voip device ipr400"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/iptables.py b/cmk/base/legacy_checks/iptables.py index 14cb3b2ab15..289b691bce6 100644 --- a/cmk/base/legacy_checks/iptables.py +++ b/cmk/base/legacy_checks/iptables.py @@ -87,6 +87,7 @@ def check_iptables(_no_item, params, parsed): check_info["iptables"] = LegacyCheckDefinition( + name="iptables", parse_function=parse_iptables, service_name="Iptables", discovery_function=inventory_iptables, diff --git a/cmk/base/legacy_checks/ispro_sensors_digital.py b/cmk/base/legacy_checks/ispro_sensors_digital.py index 63a3b24ed91..b3343f310b5 100644 --- a/cmk/base/legacy_checks/ispro_sensors_digital.py +++ b/cmk/base/legacy_checks/ispro_sensors_digital.py @@ -54,6 +54,7 @@ def parse_ispro_sensors_digital(string_table: StringTable) -> StringTable: check_info["ispro_sensors_digital"] = LegacyCheckDefinition( + name="ispro_sensors_digital", parse_function=parse_ispro_sensors_digital, detect=DETECT_ISPRO_SENSORS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ispro_sensors_humid.py b/cmk/base/legacy_checks/ispro_sensors_humid.py index 7e602f66bcf..875317b38f3 100644 --- a/cmk/base/legacy_checks/ispro_sensors_humid.py +++ b/cmk/base/legacy_checks/ispro_sensors_humid.py @@ -33,6 +33,7 @@ def parse_ispro_sensors_humid(string_table: StringTable) -> StringTable: check_info["ispro_sensors_humid"] = LegacyCheckDefinition( + name="ispro_sensors_humid", parse_function=parse_ispro_sensors_humid, detect=DETECT_ISPRO_SENSORS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ispro_sensors_temp.py b/cmk/base/legacy_checks/ispro_sensors_temp.py index fd6818a5a1f..604e552cff8 100644 --- a/cmk/base/legacy_checks/ispro_sensors_temp.py +++ b/cmk/base/legacy_checks/ispro_sensors_temp.py @@ -46,6 +46,7 @@ def parse_ispro_sensors_temp(string_table: StringTable) -> StringTable: check_info["ispro_sensors_temp"] = LegacyCheckDefinition( + name="ispro_sensors_temp", parse_function=parse_ispro_sensors_temp, detect=DETECT_ISPRO_SENSORS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/janitza_umg.py b/cmk/base/legacy_checks/janitza_umg.py index c7bb3bde440..4d6ad0cecdf 100644 --- a/cmk/base/legacy_checks/janitza_umg.py +++ b/cmk/base/legacy_checks/janitza_umg.py @@ -104,6 +104,7 @@ def inventory_janitza_umg_inphase(parsed): check_info["janitza_umg"] = LegacyCheckDefinition( + name="janitza_umg", detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.34278.8.6"), equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.34278.10.1"), @@ -176,6 +177,7 @@ def check_janitza_umg_freq(item, params, parsed): check_info["janitza_umg.freq"] = LegacyCheckDefinition( + name="janitza_umg_freq", service_name="Frequency %s", sections=["janitza_umg"], discovery_function=inventory_janitza_umg_freq, @@ -203,6 +205,7 @@ def check_janitza_umg_temp(item, params, parsed): check_info["janitza_umg.temp"] = LegacyCheckDefinition( + name="janitza_umg_temp", service_name="Temperature External %s", sections=["janitza_umg"], discovery_function=inventory_janitza_umg_temp, diff --git a/cmk/base/legacy_checks/jar_signature.py b/cmk/base/legacy_checks/jar_signature.py index 47ee5f4a69e..7906af9b979 100644 --- a/cmk/base/legacy_checks/jar_signature.py +++ b/cmk/base/legacy_checks/jar_signature.py @@ -116,6 +116,7 @@ def parse_jar_signature(string_table: StringTable) -> StringTable: check_info["jar_signature"] = LegacyCheckDefinition( + name="jar_signature", parse_function=parse_jar_signature, service_name="Jar-Signature %s", discovery_function=inventory_jar_signature, diff --git a/cmk/base/legacy_checks/jira_custom_svc.py b/cmk/base/legacy_checks/jira_custom_svc.py index 739f2c7e06a..f024a0fcdfc 100644 --- a/cmk/base/legacy_checks/jira_custom_svc.py +++ b/cmk/base/legacy_checks/jira_custom_svc.py @@ -124,6 +124,7 @@ def discover_jira_custom_svc(section): check_info["jira_custom_svc"] = LegacyCheckDefinition( + name="jira_custom_svc", parse_function=parse_jira_custom_svc, service_name="Jira %s", discovery_function=discover_jira_custom_svc, diff --git a/cmk/base/legacy_checks/jira_workflow.py b/cmk/base/legacy_checks/jira_workflow.py index 02625ceb5d4..83f43b1666e 100644 --- a/cmk/base/legacy_checks/jira_workflow.py +++ b/cmk/base/legacy_checks/jira_workflow.py @@ -69,6 +69,7 @@ def discover_jira_workflow(section): check_info["jira_workflow"] = LegacyCheckDefinition( + name="jira_workflow", parse_function=parse_jira_workflow, service_name="Jira Workflow %s", discovery_function=discover_jira_workflow, diff --git a/cmk/base/legacy_checks/jolokia_generic.py b/cmk/base/legacy_checks/jolokia_generic.py index 3be63cae470..25c067f04d7 100644 --- a/cmk/base/legacy_checks/jolokia_generic.py +++ b/cmk/base/legacy_checks/jolokia_generic.py @@ -70,6 +70,7 @@ def check_jolokia_generic_string(item, params, parsed): check_info["jolokia_generic.string"] = LegacyCheckDefinition( + name="jolokia_generic_string", service_name="JVM %s", sections=["jolokia_generic"], discovery_function=discover_type("string"), @@ -97,6 +98,7 @@ def check_jolokia_generic_rate(item, params, parsed): check_info["jolokia_generic.rate"] = LegacyCheckDefinition( + name="jolokia_generic_rate", service_name="JVM %s", sections=["jolokia_generic"], discovery_function=discover_type("rate"), @@ -124,6 +126,7 @@ def check_jolokia_generic(item, params, parsed): check_info["jolokia_generic"] = LegacyCheckDefinition( + name="jolokia_generic", parse_function=parse_jolokia_generic, service_name="JVM %s", discovery_function=discover_type("number"), diff --git a/cmk/base/legacy_checks/jolokia_info.py b/cmk/base/legacy_checks/jolokia_info.py index c2de89ea3c0..a8021725853 100644 --- a/cmk/base/legacy_checks/jolokia_info.py +++ b/cmk/base/legacy_checks/jolokia_info.py @@ -41,6 +41,7 @@ def discover_jolokia_info(section): check_info["jolokia_info"] = LegacyCheckDefinition( + name="jolokia_info", parse_function=parse_jolokia_info, service_name="JVM %s", discovery_function=discover_jolokia_info, diff --git a/cmk/base/legacy_checks/jolokia_jvm_garbagecollectors.py b/cmk/base/legacy_checks/jolokia_jvm_garbagecollectors.py index c86b067728d..11aafe1b2df 100644 --- a/cmk/base/legacy_checks/jolokia_jvm_garbagecollectors.py +++ b/cmk/base/legacy_checks/jolokia_jvm_garbagecollectors.py @@ -74,6 +74,7 @@ def check_jolokia_jvm_garbagecollectors_testable(item, params, parsed, value_sto check_info["jolokia_jvm_garbagecollectors"] = LegacyCheckDefinition( + name="jolokia_jvm_garbagecollectors", parse_function=parse_jolokia_jvm_garbagecollectors, service_name="JVM %s", discovery_function=discover_jolokia_jvm_garbagecollectors, diff --git a/cmk/base/legacy_checks/jolokia_jvm_memory.py b/cmk/base/legacy_checks/jolokia_jvm_memory.py index ff34f0a95cd..33d64512718 100644 --- a/cmk/base/legacy_checks/jolokia_jvm_memory.py +++ b/cmk/base/legacy_checks/jolokia_jvm_memory.py @@ -89,6 +89,7 @@ def check_jolokia_jvm_memory(item, params, parsed): check_info["jolokia_jvm_memory"] = LegacyCheckDefinition( + name="jolokia_jvm_memory", parse_function=parse_jolokia_jvm_memory, service_name="JVM %s Memory", discovery_function=discover_jolokia_jvm_memory, @@ -156,6 +157,7 @@ def check_jolokia_jvm_memory_pools(item, params, parsed): check_info["jolokia_jvm_memory.pools"] = LegacyCheckDefinition( + name="jolokia_jvm_memory_pools", service_name="JVM %s", sections=["jolokia_jvm_memory"], discovery_function=discover_jolokia_jvm_memory_pools, diff --git a/cmk/base/legacy_checks/jolokia_jvm_runtime.py b/cmk/base/legacy_checks/jolokia_jvm_runtime.py index 15b9671ae75..7071b093fae 100644 --- a/cmk/base/legacy_checks/jolokia_jvm_runtime.py +++ b/cmk/base/legacy_checks/jolokia_jvm_runtime.py @@ -31,6 +31,7 @@ def discover_jolokia_jvm_runtime(section): check_info["jolokia_jvm_runtime"] = LegacyCheckDefinition( + name="jolokia_jvm_runtime", parse_function=parse_jolokia_jvm_runtime, service_name="JVM %s Uptime", discovery_function=discover_jolokia_jvm_runtime, diff --git a/cmk/base/legacy_checks/jolokia_jvm_threading.py b/cmk/base/legacy_checks/jolokia_jvm_threading.py index cea161e0d04..bb2c4f9e213 100644 --- a/cmk/base/legacy_checks/jolokia_jvm_threading.py +++ b/cmk/base/legacy_checks/jolokia_jvm_threading.py @@ -69,6 +69,7 @@ def check_jolokia_jvm_threading(item, params, parsed): check_info["jolokia_jvm_threading"] = LegacyCheckDefinition( + name="jolokia_jvm_threading", parse_function=parse_jolokia_jvm_threading, service_name="JVM %s Threading", discovery_function=discover_jolokia_jvm_threading, @@ -117,6 +118,7 @@ def check_jolokia_jvm_threading_pool(item, params, parsed): check_info["jolokia_jvm_threading.pool"] = LegacyCheckDefinition( + name="jolokia_jvm_threading_pool", service_name="JVM %s", sections=["jolokia_jvm_threading"], discovery_function=discover_jolokia_jvm_threading_pool, diff --git a/cmk/base/legacy_checks/jolokia_metrics.py b/cmk/base/legacy_checks/jolokia_metrics.py index 8184035180f..dee0b286b3f 100644 --- a/cmk/base/legacy_checks/jolokia_metrics.py +++ b/cmk/base/legacy_checks/jolokia_metrics.py @@ -55,6 +55,7 @@ def parse_jolokia_metrics(string_table: StringTable) -> StringTable: check_info["jolokia_metrics"] = LegacyCheckDefinition( + name="jolokia_metrics", parse_function=parse_jolokia_metrics, ) @@ -150,6 +151,7 @@ def check_jolokia_metrics_serv_req(item, params, info): check_info["jolokia_metrics.serv_req"] = LegacyCheckDefinition( + name="jolokia_metrics_serv_req", service_name="JVM %s Requests", sections=["jolokia_metrics"], discovery_function=inventory_jolokia_metrics_serv, @@ -199,6 +201,7 @@ def check_jolokia_metrics_app_state(item, _no_params, info): check_info["jolokia_metrics.app_state"] = LegacyCheckDefinition( + name="jolokia_metrics_app_state", service_name="JVM %s State", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps( @@ -319,6 +322,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): check_info["jolokia_metrics.app_sess"] = LegacyCheckDefinition( + name="jolokia_metrics_app_sess", service_name="JVM %s Sessions", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps( @@ -333,6 +337,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): ) check_info["jolokia_metrics.requests"] = LegacyCheckDefinition( + name="jolokia_metrics_requests", service_name="JVM %s Requests", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps("requests", needed_keys={"requestCount"}), @@ -341,6 +346,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): # Stuff found on BEA Weblogic check_info["jolokia_metrics.bea_queue"] = LegacyCheckDefinition( + name="jolokia_metrics_bea_queue", service_name="JVM %s Queue", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps("queue", needed_keys={"QueueLength"}), @@ -352,6 +358,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): ) check_info["jolokia_metrics.bea_requests"] = LegacyCheckDefinition( + name="jolokia_metrics_bea_requests", service_name="JVM %s Requests", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps( @@ -361,6 +368,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): ) check_info["jolokia_metrics.bea_threads"] = LegacyCheckDefinition( + name="jolokia_metrics_bea_threads", service_name="JVM %s Threads", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps( @@ -370,6 +378,7 @@ def check_jolokia_metrics_bea_threads(item, _no_params, info): ) check_info["jolokia_metrics.bea_sess"] = LegacyCheckDefinition( + name="jolokia_metrics_bea_sess", service_name="JVM %s Sessions", sections=["jolokia_metrics"], discovery_function=get_inventory_jolokia_metrics_apps( @@ -445,6 +454,7 @@ def check_jolokia_metrics_cache_hits(item, _no_params, parsed): check_info["jolokia_metrics.cache_hits"] = LegacyCheckDefinition( + name="jolokia_metrics_cache_hits", service_name="JVM %s Cache Usage", sections=["jolokia_metrics"], discovery_function=discover_jolokia_metrics_cache_hits, @@ -469,6 +479,7 @@ def check_jolokia_metrics_in_memory(item, _no_params, parsed): check_info["jolokia_metrics.in_memory"] = LegacyCheckDefinition( + name="jolokia_metrics_in_memory", service_name="JVM %s In Memory", sections=["jolokia_metrics"], discovery_function=discover_jolokia_metrics_in_memory, @@ -493,6 +504,7 @@ def check_jolokia_metrics_on_disk(item, _no_params, parsed): check_info["jolokia_metrics.on_disk"] = LegacyCheckDefinition( + name="jolokia_metrics_on_disk", service_name="JVM %s On Disk", sections=["jolokia_metrics"], discovery_function=discover_jolokia_metrics_on_disk, @@ -517,6 +529,7 @@ def check_jolokia_metrics_off_heap(item, _no_params, parsed): check_info["jolokia_metrics.off_heap"] = LegacyCheckDefinition( + name="jolokia_metrics_off_heap", service_name="JVM %s Off Heap", sections=["jolokia_metrics"], discovery_function=discover_jolokia_metrics_off_heap, @@ -535,6 +548,7 @@ def check_jolokia_metrics_writer(item, _no_params, parsed): check_info["jolokia_metrics.writer"] = LegacyCheckDefinition( + name="jolokia_metrics_writer", service_name="JVM %s Cache Writer", sections=["jolokia_metrics"], discovery_function=discover_jolokia_metrics_writer, diff --git a/cmk/base/legacy_checks/juniper_alarm.py b/cmk/base/legacy_checks/juniper_alarm.py index 4ed48796579..050fb6acc00 100644 --- a/cmk/base/legacy_checks/juniper_alarm.py +++ b/cmk/base/legacy_checks/juniper_alarm.py @@ -40,6 +40,7 @@ def parse_juniper_alarm(string_table: StringTable) -> StringTable: check_info["juniper_alarm"] = LegacyCheckDefinition( + name="juniper_alarm", parse_function=parse_juniper_alarm, detect=DETECT_JUNIPER, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_bgp_state.py b/cmk/base/legacy_checks/juniper_bgp_state.py index 1acab289bb1..ba611dce81a 100644 --- a/cmk/base/legacy_checks/juniper_bgp_state.py +++ b/cmk/base/legacy_checks/juniper_bgp_state.py @@ -82,6 +82,7 @@ def discover_juniper_bgp_state(section): check_info["juniper_bgp_state"] = LegacyCheckDefinition( + name="juniper_bgp_state", detect=DETECT_JUNIPER, fetch=SNMPTree( base=".1.3.6.1.4.1.2636.5.1.1.2.1.1.1", diff --git a/cmk/base/legacy_checks/juniper_fru.py b/cmk/base/legacy_checks/juniper_fru.py index 57abc2c90fc..5d85046c260 100644 --- a/cmk/base/legacy_checks/juniper_fru.py +++ b/cmk/base/legacy_checks/juniper_fru.py @@ -123,6 +123,7 @@ def discover_juniper_fru(info): check_info["juniper_fru"] = LegacyCheckDefinition( + name="juniper_fru", detect=DETECT_JUNIPER, fetch=SNMPTree( base=".1.3.6.1.4.1.2636.3.1.15.1", @@ -150,6 +151,7 @@ def discover_juniper_fru_fan(info): # '----------------------------------------------------------------------' check_info["juniper_fru.fan"] = LegacyCheckDefinition( + name="juniper_fru_fan", service_name="Fan FRU %s", sections=["juniper_fru"], discovery_function=discover_juniper_fru_fan, diff --git a/cmk/base/legacy_checks/juniper_mem.py b/cmk/base/legacy_checks/juniper_mem.py index 82f3ac9bae6..e8899db6dc9 100644 --- a/cmk/base/legacy_checks/juniper_mem.py +++ b/cmk/base/legacy_checks/juniper_mem.py @@ -47,6 +47,7 @@ def check_juniper_mem( check_info["juniper_mem"] = LegacyCheckDefinition( + name="juniper_mem", detect=DETECT_JUNIPER, fetch=SNMPTree( base=".1.3.6.1.4.1.2636.3.1.13.1", diff --git a/cmk/base/legacy_checks/juniper_mem_screenos_trpz.py b/cmk/base/legacy_checks/juniper_mem_screenos_trpz.py index 7b552d3d395..32ad983dfc3 100644 --- a/cmk/base/legacy_checks/juniper_mem_screenos_trpz.py +++ b/cmk/base/legacy_checks/juniper_mem_screenos_trpz.py @@ -48,6 +48,7 @@ def check_juniper_mem_generic( check_info["juniper_trpz_mem"] = LegacyCheckDefinition( + name="juniper_trpz_mem", detect=DETECT_JUNIPER_TRPZ, fetch=SNMPTree( base=".1.3.6.1.4.1.14525.4.8.1.1", @@ -73,6 +74,7 @@ def parse_juniper_screenos_mem(string_table): check_info["juniper_screenos_mem"] = LegacyCheckDefinition( + name="juniper_screenos_mem", detect=DETECT_JUNIPER_SCREENOS, fetch=SNMPTree( base=".1.3.6.1.4.1.3224.16.2", diff --git a/cmk/base/legacy_checks/juniper_screenos_cpu.py b/cmk/base/legacy_checks/juniper_screenos_cpu.py index 05e2501980b..6f4bf848fd0 100644 --- a/cmk/base/legacy_checks/juniper_screenos_cpu.py +++ b/cmk/base/legacy_checks/juniper_screenos_cpu.py @@ -47,6 +47,7 @@ def parse_juniper_screenos_cpu(string_table: StringTable) -> StringTable | None: check_info["juniper_screenos_cpu"] = LegacyCheckDefinition( + name="juniper_screenos_cpu", parse_function=parse_juniper_screenos_cpu, detect=DETECT_JUNIPER_SCREENOS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_screenos_fan.py b/cmk/base/legacy_checks/juniper_screenos_fan.py index d03deb2ca94..1359400f01d 100644 --- a/cmk/base/legacy_checks/juniper_screenos_fan.py +++ b/cmk/base/legacy_checks/juniper_screenos_fan.py @@ -32,6 +32,7 @@ def parse_juniper_screenos_fan(string_table: StringTable) -> StringTable: check_info["juniper_screenos_fan"] = LegacyCheckDefinition( + name="juniper_screenos_fan", parse_function=parse_juniper_screenos_fan, detect=DETECT_JUNIPER_SCREENOS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_screenos_temp.py b/cmk/base/legacy_checks/juniper_screenos_temp.py index 413c625e336..714622dbc1a 100644 --- a/cmk/base/legacy_checks/juniper_screenos_temp.py +++ b/cmk/base/legacy_checks/juniper_screenos_temp.py @@ -33,6 +33,7 @@ def parse_juniper_screenos_temp(string_table: StringTable) -> StringTable: check_info["juniper_screenos_temp"] = LegacyCheckDefinition( + name="juniper_screenos_temp", parse_function=parse_juniper_screenos_temp, detect=DETECT_JUNIPER_SCREENOS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_screenos_vpn.py b/cmk/base/legacy_checks/juniper_screenos_vpn.py index 5d1b728586b..316bd039df3 100644 --- a/cmk/base/legacy_checks/juniper_screenos_vpn.py +++ b/cmk/base/legacy_checks/juniper_screenos_vpn.py @@ -31,6 +31,7 @@ def parse_juniper_screenos_vpn(string_table: StringTable) -> StringTable: check_info["juniper_screenos_vpn"] = LegacyCheckDefinition( + name="juniper_screenos_vpn", parse_function=parse_juniper_screenos_vpn, detect=DETECT_JUNIPER_SCREENOS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_temp.py b/cmk/base/legacy_checks/juniper_temp.py index c6b45a591fd..15ef7918a45 100644 --- a/cmk/base/legacy_checks/juniper_temp.py +++ b/cmk/base/legacy_checks/juniper_temp.py @@ -37,6 +37,7 @@ def check_juniper_temp(item, params, parsed): check_info["juniper_temp"] = LegacyCheckDefinition( + name="juniper_temp", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2636.1.1.1.2"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2636.1.1.1.4"), diff --git a/cmk/base/legacy_checks/juniper_trpz_flash.py b/cmk/base/legacy_checks/juniper_trpz_flash.py index b37a4331608..2a5e2b34999 100644 --- a/cmk/base/legacy_checks/juniper_trpz_flash.py +++ b/cmk/base/legacy_checks/juniper_trpz_flash.py @@ -62,6 +62,7 @@ def parse_juniper_trpz_flash(string_table: StringTable) -> StringTable | None: check_info["juniper_trpz_flash"] = LegacyCheckDefinition( + name="juniper_trpz_flash", parse_function=parse_juniper_trpz_flash, detect=DETECT_JUNIPER_TRPZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_trpz_info.py b/cmk/base/legacy_checks/juniper_trpz_info.py index 707287ac859..7a5849a1ff5 100644 --- a/cmk/base/legacy_checks/juniper_trpz_info.py +++ b/cmk/base/legacy_checks/juniper_trpz_info.py @@ -26,6 +26,7 @@ def parse_juniper_trpz_info(string_table: StringTable) -> StringTable | None: check_info["juniper_trpz_info"] = LegacyCheckDefinition( + name="juniper_trpz_info", parse_function=parse_juniper_trpz_info, detect=DETECT_JUNIPER_TRPZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/juniper_trpz_power.py b/cmk/base/legacy_checks/juniper_trpz_power.py index b13770a6891..f2bcf912209 100644 --- a/cmk/base/legacy_checks/juniper_trpz_power.py +++ b/cmk/base/legacy_checks/juniper_trpz_power.py @@ -53,6 +53,7 @@ def parse_juniper_trpz_power(string_table: StringTable) -> StringTable: check_info["juniper_trpz_power"] = LegacyCheckDefinition( + name="juniper_trpz_power", parse_function=parse_juniper_trpz_power, detect=DETECT_JUNIPER_TRPZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/keepalived.py b/cmk/base/legacy_checks/keepalived.py index 8c328b4b955..e719fb99315 100644 --- a/cmk/base/legacy_checks/keepalived.py +++ b/cmk/base/legacy_checks/keepalived.py @@ -57,6 +57,7 @@ def parse_keepalived(string_table: Sequence[StringTable]) -> Sequence[StringTabl check_info["keepalived"] = LegacyCheckDefinition( + name="keepalived", parse_function=parse_keepalived, detect=all_of(contains(".1.3.6.1.2.1.1.1.0", "linux"), exists(".1.3.6.1.4.1.9586.100.5.1.1.0")), fetch=[ diff --git a/cmk/base/legacy_checks/kemp_loadmaster_ha.py b/cmk/base/legacy_checks/kemp_loadmaster_ha.py index 0929c86794f..11d23aa658e 100644 --- a/cmk/base/legacy_checks/kemp_loadmaster_ha.py +++ b/cmk/base/legacy_checks/kemp_loadmaster_ha.py @@ -35,6 +35,7 @@ def parse_kemp_loadmaster_ha(string_table: StringTable) -> StringTable: check_info["kemp_loadmaster_ha"] = LegacyCheckDefinition( + name="kemp_loadmaster_ha", parse_function=parse_kemp_loadmaster_ha, detect=all_of( any_of( diff --git a/cmk/base/legacy_checks/kentix_amp_sensors.py b/cmk/base/legacy_checks/kentix_amp_sensors.py index 8c890725ac3..b1eb921f99b 100644 --- a/cmk/base/legacy_checks/kentix_amp_sensors.py +++ b/cmk/base/legacy_checks/kentix_amp_sensors.py @@ -80,6 +80,7 @@ def check_kentix_amp_sensors(item, params, parsed): check_info["kentix_amp_sensors"] = LegacyCheckDefinition( + name="kentix_amp_sensors", detect=DETECT_KENTIX, fetch=[ SNMPTree( @@ -116,6 +117,7 @@ def check_kentix_amp_sensors_humidity(item, params, parsed): check_info["kentix_amp_sensors.humidity"] = LegacyCheckDefinition( + name="kentix_amp_sensors_humidity", service_name="Humidity %s", sections=["kentix_amp_sensors"], discovery_function=discover_kentix_amp_sensors_humidity, @@ -163,6 +165,7 @@ def check_kentix_amp_sensors_smoke(item, params, parsed): check_info["kentix_amp_sensors.smoke"] = LegacyCheckDefinition( + name="kentix_amp_sensors_smoke", service_name="Smoke Detector %s", sections=["kentix_amp_sensors"], discovery_function=discover_kentix_amp_sensors_smoke, @@ -195,6 +198,7 @@ def check_kentix_amp_sensors_leakage(item, params, parsed): check_info["kentix_amp_sensors.leakage"] = LegacyCheckDefinition( + name="kentix_amp_sensors_leakage", service_name="Leakage %s", sections=["kentix_amp_sensors"], discovery_function=discover_kentix_amp_sensors_leakage, diff --git a/cmk/base/legacy_checks/kentix_co.py b/cmk/base/legacy_checks/kentix_co.py index a08812ad00a..04a03bbfa33 100644 --- a/cmk/base/legacy_checks/kentix_co.py +++ b/cmk/base/legacy_checks/kentix_co.py @@ -44,6 +44,7 @@ def check_kentix_co(item: str, params: dict, section: int) -> Iterable: check_info["kentix_co"] = LegacyCheckDefinition( + name="kentix_co", detect=DETECT_KENTIX, fetch=SNMPTree( base=".1.3.6.1.4.1.37954", diff --git a/cmk/base/legacy_checks/kentix_dewpoint.py b/cmk/base/legacy_checks/kentix_dewpoint.py index 5174cc6b254..01bfc0a7bd0 100644 --- a/cmk/base/legacy_checks/kentix_dewpoint.py +++ b/cmk/base/legacy_checks/kentix_dewpoint.py @@ -40,6 +40,7 @@ def check_kentix_dewpoint(item: str, params: TempParamType, section: Section) -> check_info["kentix_dewpoint"] = LegacyCheckDefinition( + name="kentix_dewpoint", detect=DETECT_KENTIX, fetch=SNMPTree( base=".1.3.6.1.4.1.37954", diff --git a/cmk/base/legacy_checks/kentix_humidity.py b/cmk/base/legacy_checks/kentix_humidity.py index 150b814760d..26f57e831bd 100644 --- a/cmk/base/legacy_checks/kentix_humidity.py +++ b/cmk/base/legacy_checks/kentix_humidity.py @@ -63,6 +63,7 @@ def check_kentix_humidity( check_info["kentix_humidity"] = LegacyCheckDefinition( + name="kentix_humidity", detect=DETECT_KENTIX, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/kentix_motion.py b/cmk/base/legacy_checks/kentix_motion.py index 466a95cf07d..fcabe5be54b 100644 --- a/cmk/base/legacy_checks/kentix_motion.py +++ b/cmk/base/legacy_checks/kentix_motion.py @@ -83,6 +83,7 @@ def test_in_period( check_info["kentix_motion"] = LegacyCheckDefinition( + name="kentix_motion", detect=DETECT_KENTIX, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/kentix_temp.py b/cmk/base/legacy_checks/kentix_temp.py index 87efb95be47..071b0915978 100644 --- a/cmk/base/legacy_checks/kentix_temp.py +++ b/cmk/base/legacy_checks/kentix_temp.py @@ -61,6 +61,7 @@ def check_kentix_temp( check_info["kentix_temp"] = LegacyCheckDefinition( + name="kentix_temp", detect=DETECT_KENTIX, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/kernel.py b/cmk/base/legacy_checks/kernel.py index 093a91abc31..6ad887f641d 100644 --- a/cmk/base/legacy_checks/kernel.py +++ b/cmk/base/legacy_checks/kernel.py @@ -56,6 +56,7 @@ def check_kernel(item, params, parsed): # This check is deprecated. Please have a look at werk #8969. check_info["kernel"] = LegacyCheckDefinition( + name="kernel", service_name="Kernel %s", check_function=check_kernel, check_ruleset_name="vm_counter", @@ -118,6 +119,7 @@ def check_kernel_performance(_no_item, params, parsed): check_info["kernel.performance"] = LegacyCheckDefinition( + name="kernel_performance", service_name="Kernel Performance", sections=["kernel"], discovery_function=inventory_kernel_performance, diff --git a/cmk/base/legacy_checks/knuerr_rms_humidity.py b/cmk/base/legacy_checks/knuerr_rms_humidity.py index 7ff7c18ebec..93d1a45e6a7 100644 --- a/cmk/base/legacy_checks/knuerr_rms_humidity.py +++ b/cmk/base/legacy_checks/knuerr_rms_humidity.py @@ -26,6 +26,7 @@ def parse_knuerr_rms_humidity(string_table: StringTable) -> StringTable | None: check_info["knuerr_rms_humidity"] = LegacyCheckDefinition( + name="knuerr_rms_humidity", parse_function=parse_knuerr_rms_humidity, detect=DETECT_KNUERR, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/knuerr_rms_temp.py b/cmk/base/legacy_checks/knuerr_rms_temp.py index 54fbafb8c06..e4a3bf3f78c 100644 --- a/cmk/base/legacy_checks/knuerr_rms_temp.py +++ b/cmk/base/legacy_checks/knuerr_rms_temp.py @@ -25,6 +25,7 @@ def parse_knuerr_rms_temp(string_table: StringTable) -> StringTable | None: check_info["knuerr_rms_temp"] = LegacyCheckDefinition( + name="knuerr_rms_temp", parse_function=parse_knuerr_rms_temp, detect=DETECT_KNUERR, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/knuerr_sensors.py b/cmk/base/legacy_checks/knuerr_sensors.py index 44af8652ef3..40557d80a4a 100644 --- a/cmk/base/legacy_checks/knuerr_sensors.py +++ b/cmk/base/legacy_checks/knuerr_sensors.py @@ -31,6 +31,7 @@ def parse_knuerr_sensors(string_table: StringTable) -> StringTable: check_info["knuerr_sensors"] = LegacyCheckDefinition( + name="knuerr_sensors", parse_function=parse_knuerr_sensors, detect=DETECT_KNUERR, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/lgp_info.py b/cmk/base/legacy_checks/lgp_info.py index 3fb037a8cac..91d42191124 100644 --- a/cmk/base/legacy_checks/lgp_info.py +++ b/cmk/base/legacy_checks/lgp_info.py @@ -56,6 +56,7 @@ def parse_lgp_info(string_table: Sequence[StringTable]) -> Sequence[StringTable] check_info["lgp_info"] = LegacyCheckDefinition( + name="lgp_info", parse_function=parse_lgp_info, detect=DETECT_LGP, fetch=[ diff --git a/cmk/base/legacy_checks/lgp_pdu_aux.py b/cmk/base/legacy_checks/lgp_pdu_aux.py index 425efd99a0a..5a4176e7b45 100644 --- a/cmk/base/legacy_checks/lgp_pdu_aux.py +++ b/cmk/base/legacy_checks/lgp_pdu_aux.py @@ -196,6 +196,7 @@ def parse_lgp_pdu_aux(string_table: StringTable) -> StringTable: check_info["lgp_pdu_aux"] = LegacyCheckDefinition( + name="lgp_pdu_aux", parse_function=parse_lgp_pdu_aux, detect=DETECT_LGP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/lgp_pdu_info.py b/cmk/base/legacy_checks/lgp_pdu_info.py index a6bfc27452b..9ffcb78c947 100644 --- a/cmk/base/legacy_checks/lgp_pdu_info.py +++ b/cmk/base/legacy_checks/lgp_pdu_info.py @@ -43,6 +43,7 @@ def parse_lgp_pdu_info(string_table: StringTable) -> StringTable: check_info["lgp_pdu_info"] = LegacyCheckDefinition( + name="lgp_pdu_info", parse_function=parse_lgp_pdu_info, detect=DETECT_LGP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/libelle_business_shadow.py b/cmk/base/legacy_checks/libelle_business_shadow.py index f1ced3997ec..a60a81e8054 100644 --- a/cmk/base/legacy_checks/libelle_business_shadow.py +++ b/cmk/base/legacy_checks/libelle_business_shadow.py @@ -224,6 +224,7 @@ def parse_libelle_business_shadow(string_table: StringTable) -> StringTable: check_info["libelle_business_shadow"] = LegacyCheckDefinition( + name="libelle_business_shadow", parse_function=parse_libelle_business_shadow, ) @@ -297,6 +298,7 @@ def check_libelle_business_shadow_info(_no_item, _no_params, info): check_info["libelle_business_shadow.info"] = LegacyCheckDefinition( + name="libelle_business_shadow_info", service_name="Libelle Business Shadow Info", sections=["libelle_business_shadow"], discovery_function=inventory_libelle_business_shadow_info, @@ -336,6 +338,7 @@ def check_libelle_business_shadow_status(_no_item, _no_params, info): check_info["libelle_business_shadow.status"] = LegacyCheckDefinition( + name="libelle_business_shadow_status", service_name="Libelle Business Shadow Status", sections=["libelle_business_shadow"], discovery_function=inventory_libelle_business_shadow_status, @@ -378,6 +381,7 @@ def check_libelle_business_shadow_process(_no_item, _no_params, info): check_info["libelle_business_shadow.process"] = LegacyCheckDefinition( + name="libelle_business_shadow_process", service_name="Libelle Business Shadow Process", sections=["libelle_business_shadow"], discovery_function=inventory_libelle_business_shadow_process, @@ -412,6 +416,7 @@ def check_libelle_business_shadow_archive_dir(item, params, info): check_info["libelle_business_shadow.archive_dir"] = LegacyCheckDefinition( + name="libelle_business_shadow_archive_dir", service_name="Libelle Business Shadow %s", sections=["libelle_business_shadow"], discovery_function=inventory_libelle_business_shadow_archive_dir, diff --git a/cmk/base/legacy_checks/logins.py b/cmk/base/legacy_checks/logins.py index 90d2900b887..dda5cd24e2d 100644 --- a/cmk/base/legacy_checks/logins.py +++ b/cmk/base/legacy_checks/logins.py @@ -44,6 +44,7 @@ def check_logins( check_info["logins"] = LegacyCheckDefinition( + name="logins", service_name="Logins", parse_function=parse_logins, discovery_function=discover_logins, diff --git a/cmk/base/legacy_checks/lparstat_aix.py b/cmk/base/legacy_checks/lparstat_aix.py index 01a66bb86e5..974075d4933 100644 --- a/cmk/base/legacy_checks/lparstat_aix.py +++ b/cmk/base/legacy_checks/lparstat_aix.py @@ -39,6 +39,7 @@ def check_lparstat(_no_item: int, _no_params: Mapping[str, Any], section: Sectio check_info["lparstat_aix"] = LegacyCheckDefinition( + name="lparstat_aix", service_name="lparstat", discovery_function=inventory_lparstat, check_function=check_lparstat, @@ -91,6 +92,7 @@ def check_lparstat_aix_cpu( check_info["lparstat_aix.cpu_util"] = LegacyCheckDefinition( + name="lparstat_aix_cpu_util", service_name="CPU utilization", sections=["lparstat_aix"], discovery_function=inventory_lparstat_aix_cpu, diff --git a/cmk/base/legacy_checks/lvm_lvs.py b/cmk/base/legacy_checks/lvm_lvs.py index d5ef09d11f9..11c41df9582 100644 --- a/cmk/base/legacy_checks/lvm_lvs.py +++ b/cmk/base/legacy_checks/lvm_lvs.py @@ -59,6 +59,7 @@ def discover_lvm_lvs(section): check_info["lvm_lvs"] = LegacyCheckDefinition( + name="lvm_lvs", parse_function=parse_lvm_lvs, service_name="LVM LV Pool %s", discovery_function=discover_lvm_lvs, diff --git a/cmk/base/legacy_checks/lvm_vgs.py b/cmk/base/legacy_checks/lvm_vgs.py index 2e8af31f96a..dafaa6b5eda 100644 --- a/cmk/base/legacy_checks/lvm_vgs.py +++ b/cmk/base/legacy_checks/lvm_vgs.py @@ -30,6 +30,7 @@ def parse_lvm_vgs(string_table: StringTable) -> StringTable: check_info["lvm_vgs"] = LegacyCheckDefinition( + name="lvm_vgs", parse_function=parse_lvm_vgs, service_name="LVM VG %s", discovery_function=inventory_lvm_vgs, diff --git a/cmk/base/legacy_checks/mailman_lists.py b/cmk/base/legacy_checks/mailman_lists.py index 333d0233b87..1ec4623ef15 100644 --- a/cmk/base/legacy_checks/mailman_lists.py +++ b/cmk/base/legacy_checks/mailman_lists.py @@ -40,6 +40,7 @@ def parse_mailman_lists(string_table: StringTable) -> StringTable: check_info["mailman_lists"] = LegacyCheckDefinition( + name="mailman_lists", parse_function=parse_mailman_lists, service_name="Mailinglist %s", discovery_function=inventory_mailman_lists, diff --git a/cmk/base/legacy_checks/mbg_lantime_ng_fan.py b/cmk/base/legacy_checks/mbg_lantime_ng_fan.py index 835dde2a6f2..f973169734a 100644 --- a/cmk/base/legacy_checks/mbg_lantime_ng_fan.py +++ b/cmk/base/legacy_checks/mbg_lantime_ng_fan.py @@ -69,6 +69,7 @@ def check_mbg_lantime_ng_fan(item, _no_params, parsed): check_info["mbg_lantime_ng_fan"] = LegacyCheckDefinition( + name="mbg_lantime_ng_fan", detect=DETECT_MBG_LANTIME_NG, fetch=SNMPTree( base=".1.3.6.1.4.1.5597.30.0.5.1.2.1", diff --git a/cmk/base/legacy_checks/mbg_lantime_ng_power.py b/cmk/base/legacy_checks/mbg_lantime_ng_power.py index c35e2f37807..f04d52cf08b 100644 --- a/cmk/base/legacy_checks/mbg_lantime_ng_power.py +++ b/cmk/base/legacy_checks/mbg_lantime_ng_power.py @@ -34,6 +34,7 @@ def parse_mbg_lantime_ng_power(string_table: StringTable) -> StringTable: check_info["mbg_lantime_ng_power"] = LegacyCheckDefinition( + name="mbg_lantime_ng_power", parse_function=parse_mbg_lantime_ng_power, detect=DETECT_MBG_LANTIME_NG, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mbg_lantime_ng_refclock.py b/cmk/base/legacy_checks/mbg_lantime_ng_refclock.py index 32d85a79412..3605fca65b4 100644 --- a/cmk/base/legacy_checks/mbg_lantime_ng_refclock.py +++ b/cmk/base/legacy_checks/mbg_lantime_ng_refclock.py @@ -274,6 +274,7 @@ def check_lantime_ng_refclock_gps(item, params, info): check_info["mbg_lantime_ng_refclock.gps"] = LegacyCheckDefinition( + name="mbg_lantime_ng_refclock_gps", service_name="LANTIME Refclock %s", sections=["mbg_lantime_ng_refclock"], discovery_function=inventory_lantime_ng_refclock_gps, @@ -343,6 +344,7 @@ def parse_mbg_lantime_ng_refclock(string_table: StringTable) -> StringTable: check_info["mbg_lantime_ng_refclock"] = LegacyCheckDefinition( + name="mbg_lantime_ng_refclock", parse_function=parse_mbg_lantime_ng_refclock, detect=DETECT_MBG_LANTIME_NG, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mbg_lantime_ng_state.py b/cmk/base/legacy_checks/mbg_lantime_ng_state.py index cebd103c8cd..177f0d33e50 100644 --- a/cmk/base/legacy_checks/mbg_lantime_ng_state.py +++ b/cmk/base/legacy_checks/mbg_lantime_ng_state.py @@ -43,6 +43,7 @@ def parse_mbg_lantime_ng_state(string_table: StringTable) -> StringTable: check_info["mbg_lantime_ng_state"] = LegacyCheckDefinition( + name="mbg_lantime_ng_state", parse_function=parse_mbg_lantime_ng_state, detect=DETECT_MBG_LANTIME_NG, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mbg_lantime_ng_temp.py b/cmk/base/legacy_checks/mbg_lantime_ng_temp.py index f83c048efe6..7006a652788 100644 --- a/cmk/base/legacy_checks/mbg_lantime_ng_temp.py +++ b/cmk/base/legacy_checks/mbg_lantime_ng_temp.py @@ -27,6 +27,7 @@ def parse_mbg_lantime_ng_temp(string_table: StringTable) -> StringTable: check_info["mbg_lantime_ng_temp"] = LegacyCheckDefinition( + name="mbg_lantime_ng_temp", parse_function=parse_mbg_lantime_ng_temp, detect=DETECT_MBG_LANTIME_NG, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mbg_lantime_refclock.py b/cmk/base/legacy_checks/mbg_lantime_refclock.py index 7cac952564b..b9828ad2e21 100644 --- a/cmk/base/legacy_checks/mbg_lantime_refclock.py +++ b/cmk/base/legacy_checks/mbg_lantime_refclock.py @@ -90,6 +90,7 @@ def parse_mbg_lantime_refclock(string_table: StringTable) -> StringTable: check_info["mbg_lantime_refclock"] = LegacyCheckDefinition( + name="mbg_lantime_refclock", parse_function=parse_mbg_lantime_refclock, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.5597.3"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mbg_lantime_state.py b/cmk/base/legacy_checks/mbg_lantime_state.py index 518e46975fc..e64f81d4c5f 100644 --- a/cmk/base/legacy_checks/mbg_lantime_state.py +++ b/cmk/base/legacy_checks/mbg_lantime_state.py @@ -37,6 +37,7 @@ def parse_mbg_lantime_state(string_table: StringTable) -> StringTable: check_info["mbg_lantime_state"] = LegacyCheckDefinition( + name="mbg_lantime_state", parse_function=parse_mbg_lantime_state, detect=all_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.5597.3"), diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_agent.py b/cmk/base/legacy_checks/mcafee_emailgateway_agent.py index bbe470716de..2ace27d7a4b 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_agent.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_agent.py @@ -24,6 +24,7 @@ def check_mcafee_emailgateway_agent(item, params, info): check_info["mcafee_emailgateway_agent"] = LegacyCheckDefinition( + name="mcafee_emailgateway_agent", parse_function=parse_mcafee_emailgateway_agent, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_av_authentium.py b/cmk/base/legacy_checks/mcafee_emailgateway_av_authentium.py index aa11c0dacaf..d4316aaddb8 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_av_authentium.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_av_authentium.py @@ -36,6 +36,7 @@ def parse_mcafee_emailgateway_av_authentium(string_table: StringTable) -> String check_info["mcafee_emailgateway_av_authentium"] = LegacyCheckDefinition( + name="mcafee_emailgateway_av_authentium", parse_function=parse_mcafee_emailgateway_av_authentium, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_av_mcafee.py b/cmk/base/legacy_checks/mcafee_emailgateway_av_mcafee.py index b041651d7bf..4539758aa82 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_av_mcafee.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_av_mcafee.py @@ -29,6 +29,7 @@ def check_mcafee_emailgateway_av_mcafee(item, params, info): check_info["mcafee_emailgateway_av_mcafee"] = LegacyCheckDefinition( + name="mcafee_emailgateway_av_mcafee", parse_function=parse_mcafee_emailgateway_av_mcafee, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_bridge.py b/cmk/base/legacy_checks/mcafee_emailgateway_bridge.py index af355db7454..be01732fc91 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_bridge.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_bridge.py @@ -66,6 +66,7 @@ def check_mcafee_emailgateway_bridge(item, params, info): check_info["mcafee_emailgateway_bridge"] = LegacyCheckDefinition( + name="mcafee_emailgateway_bridge", parse_function=parse_mcafee_emailgateway_bridge, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_entities.py b/cmk/base/legacy_checks/mcafee_emailgateway_entities.py index a17a88e61f6..de14d8e5f71 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_entities.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_entities.py @@ -89,6 +89,7 @@ def check_mcafee_emailgateway_entities(item, params, parsed): check_info["mcafee_emailgateway_entities"] = LegacyCheckDefinition( + name="mcafee_emailgateway_entities", detect=DETECT_EMAIL_GATEWAY, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_smtp.py b/cmk/base/legacy_checks/mcafee_emailgateway_smtp.py index ab0a19a0957..cc012d595ce 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_smtp.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_smtp.py @@ -30,6 +30,7 @@ def check_mcafee_emailgateway_smtp(item, params, info): check_info["mcafee_emailgateway_smtp"] = LegacyCheckDefinition( + name="mcafee_emailgateway_smtp", parse_function=parse_mcafee_emailgateway_smtp, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mcafee_emailgateway_spam_mcafee.py b/cmk/base/legacy_checks/mcafee_emailgateway_spam_mcafee.py index 942f5f7887f..95c7132eb05 100644 --- a/cmk/base/legacy_checks/mcafee_emailgateway_spam_mcafee.py +++ b/cmk/base/legacy_checks/mcafee_emailgateway_spam_mcafee.py @@ -25,6 +25,7 @@ def check_mcafee_emailgateway_spam_mcafee(item, params, info): check_info["mcafee_emailgateway_spam_mcafee"] = LegacyCheckDefinition( + name="mcafee_emailgateway_spam_mcafee", parse_function=parse_mcafee_emailgateway_spam_mcafee, detect=DETECT_EMAIL_GATEWAY, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/md.py b/cmk/base/legacy_checks/md.py index ab01680d270..f8dfe659448 100644 --- a/cmk/base/legacy_checks/md.py +++ b/cmk/base/legacy_checks/md.py @@ -237,6 +237,7 @@ def check_md(item, _no_params, parsed): # pylint: disable=too-many-branches check_info["md"] = LegacyCheckDefinition( + name="md", parse_function=parse_md, service_name="MD Softraid %s", discovery_function=inventory_md, diff --git a/cmk/base/legacy_checks/megaraid_bbu.py b/cmk/base/legacy_checks/megaraid_bbu.py index 9d75fc6276f..b548ee71d09 100644 --- a/cmk/base/legacy_checks/megaraid_bbu.py +++ b/cmk/base/legacy_checks/megaraid_bbu.py @@ -110,6 +110,7 @@ def check_megaraid_bbu(item, _no_params, section): check_info["megaraid_bbu"] = LegacyCheckDefinition( + name="megaraid_bbu", parse_function=megaraid_bbu_parse, service_name="RAID BBU %s", discovery_function=discover_megaraid_bbu, diff --git a/cmk/base/legacy_checks/mem_linux.py b/cmk/base/legacy_checks/mem_linux.py index e9c622df0c4..e476a8d4c4c 100644 --- a/cmk/base/legacy_checks/mem_linux.py +++ b/cmk/base/legacy_checks/mem_linux.py @@ -120,6 +120,7 @@ def _camelcase_to_underscored(name): check_info["mem.linux"] = LegacyCheckDefinition( + name="mem_linux", service_name="Memory", sections=["mem"], discovery_function=inventory_mem_linux, diff --git a/cmk/base/legacy_checks/mem_vmalloc.py b/cmk/base/legacy_checks/mem_vmalloc.py index 138579480e9..640a2e06337 100644 --- a/cmk/base/legacy_checks/mem_vmalloc.py +++ b/cmk/base/legacy_checks/mem_vmalloc.py @@ -55,6 +55,7 @@ def check_mem_vmalloc(_item, params, section): check_info["mem.vmalloc"] = LegacyCheckDefinition( + name="mem_vmalloc", service_name="Vmalloc address space", sections=["mem"], discovery_function=inventory_mem_vmalloc, diff --git a/cmk/base/legacy_checks/mikrotik_signal.py b/cmk/base/legacy_checks/mikrotik_signal.py index 39cd6ecf640..400fd53db0f 100644 --- a/cmk/base/legacy_checks/mikrotik_signal.py +++ b/cmk/base/legacy_checks/mikrotik_signal.py @@ -53,6 +53,7 @@ def parse_mikrotik_signal(string_table: StringTable) -> StringTable: check_info["mikrotik_signal"] = LegacyCheckDefinition( + name="mikrotik_signal", parse_function=parse_mikrotik_signal, detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.14988.1"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/mkbackup.py b/cmk/base/legacy_checks/mkbackup.py index 105d5f3fd58..6d67d51dfe4 100644 --- a/cmk/base/legacy_checks/mkbackup.py +++ b/cmk/base/legacy_checks/mkbackup.py @@ -135,6 +135,7 @@ def check_mkbackup_system(item, _no_params, parsed): check_info["mkbackup"] = LegacyCheckDefinition( + name="mkbackup", parse_function=parse_mkbackup, service_name="Backup %s", discovery_function=inventory_mkbackup_system, @@ -158,6 +159,7 @@ def check_mkbackup_site(item, _no_params, parsed): check_info["mkbackup.site"] = LegacyCheckDefinition( + name="mkbackup_site", service_name="OMD %s", sections=["mkbackup"], discovery_function=inventory_mkbackup_site, diff --git a/cmk/base/legacy_checks/mkeventd_status.py b/cmk/base/legacy_checks/mkeventd_status.py index ceefd2ad86e..0e83e0f9082 100644 --- a/cmk/base/legacy_checks/mkeventd_status.py +++ b/cmk/base/legacy_checks/mkeventd_status.py @@ -129,6 +129,7 @@ def check_mkeventd_status(item, params, parsed): # pylint: disable=too-many-bra check_info["mkeventd_status"] = LegacyCheckDefinition( + name="mkeventd_status", parse_function=parse_mkeventd_status, service_name="OMD %s Event Console", discovery_function=inventory_mkeventd_status, diff --git a/cmk/base/legacy_checks/mongodb_cluster.py b/cmk/base/legacy_checks/mongodb_cluster.py index 8338d86fdc6..53c8ce664d9 100644 --- a/cmk/base/legacy_checks/mongodb_cluster.py +++ b/cmk/base/legacy_checks/mongodb_cluster.py @@ -79,6 +79,7 @@ def check_mongodb_cluster_databases(item, _params, databases_dict): check_info["mongodb_cluster"] = LegacyCheckDefinition( + name="mongodb_cluster", parse_function=parse_mongodb_cluster, service_name="MongoDB Database: %s", discovery_function=inventory_mongodb_cluster_databases, @@ -481,6 +482,7 @@ def _mongodb_cluster_split_namespace(namespace): check_info["mongodb_cluster.collections"] = LegacyCheckDefinition( + name="mongodb_cluster_collections", service_name="MongoDB Cluster: %s", sections=["mongodb_cluster"], discovery_function=inventory_mongodb_cluster_shards, @@ -516,6 +518,7 @@ def check_mongodb_cluster_balancer(_item, _params, databases_dict): check_info["mongodb_cluster.balancer"] = LegacyCheckDefinition( + name="mongodb_cluster_balancer", service_name="MongoDB Balancer", sections=["mongodb_cluster"], discovery_function=discover_mongodb_cluster_balancer, diff --git a/cmk/base/legacy_checks/mongodb_collections.py b/cmk/base/legacy_checks/mongodb_collections.py index f8faa3f53d3..32be74d806f 100644 --- a/cmk/base/legacy_checks/mongodb_collections.py +++ b/cmk/base/legacy_checks/mongodb_collections.py @@ -216,6 +216,7 @@ def _mongodb_collections_get_as_int(data, key): check_info["mongodb_collections"] = LegacyCheckDefinition( + name="mongodb_collections", parse_function=parse_mongodb_collections, service_name="MongoDB Collection: %s", discovery_function=inventory_mongodb_collections, diff --git a/cmk/base/legacy_checks/mongodb_connections.py b/cmk/base/legacy_checks/mongodb_connections.py index b5e76799fe5..3e314da9cf8 100644 --- a/cmk/base/legacy_checks/mongodb_connections.py +++ b/cmk/base/legacy_checks/mongodb_connections.py @@ -78,6 +78,7 @@ def parse_mongodb_connections(string_table: StringTable) -> StringTable: check_info["mongodb_connections"] = LegacyCheckDefinition( + name="mongodb_connections", parse_function=parse_mongodb_connections, service_name="MongoDB %s", discovery_function=inventory_mongodb_connections, diff --git a/cmk/base/legacy_checks/mongodb_counters.py b/cmk/base/legacy_checks/mongodb_counters.py index 253b248e6f4..201a64551a9 100644 --- a/cmk/base/legacy_checks/mongodb_counters.py +++ b/cmk/base/legacy_checks/mongodb_counters.py @@ -32,6 +32,7 @@ def check_mongodb_counters(item, _no_params, parsed): check_info["mongodb_counters"] = LegacyCheckDefinition( + name="mongodb_counters", service_name="MongoDB Counters %s", discovery_function=inventory_mongodb_counters, check_function=check_mongodb_counters, diff --git a/cmk/base/legacy_checks/mongodb_flushing.py b/cmk/base/legacy_checks/mongodb_flushing.py index 8d3fca47757..317a5c5d086 100644 --- a/cmk/base/legacy_checks/mongodb_flushing.py +++ b/cmk/base/legacy_checks/mongodb_flushing.py @@ -91,6 +91,7 @@ def parse_mongodb_flushing(string_table: StringTable) -> StringTable: check_info["mongodb_flushing"] = LegacyCheckDefinition( + name="mongodb_flushing", parse_function=parse_mongodb_flushing, service_name="MongoDB Flushing", discovery_function=inventory_mongodb_flushing, diff --git a/cmk/base/legacy_checks/mongodb_instance.py b/cmk/base/legacy_checks/mongodb_instance.py index 98da8fcb74a..553991ea7a3 100644 --- a/cmk/base/legacy_checks/mongodb_instance.py +++ b/cmk/base/legacy_checks/mongodb_instance.py @@ -31,6 +31,7 @@ def parse_mongodb_instance(string_table: StringTable) -> StringTable: check_info["mongodb_instance"] = LegacyCheckDefinition( + name="mongodb_instance", parse_function=parse_mongodb_instance, service_name="MongoDB Instance", discovery_function=inventory_mongodb_instance, diff --git a/cmk/base/legacy_checks/mongodb_locks.py b/cmk/base/legacy_checks/mongodb_locks.py index 0424da8e9e1..a9890cb07f0 100644 --- a/cmk/base/legacy_checks/mongodb_locks.py +++ b/cmk/base/legacy_checks/mongodb_locks.py @@ -47,6 +47,7 @@ def parse_mongodb_locks(string_table: StringTable) -> StringTable: check_info["mongodb_locks"] = LegacyCheckDefinition( + name="mongodb_locks", parse_function=parse_mongodb_locks, service_name="MongoDB Locks", discovery_function=inventory_mongodb_locks, diff --git a/cmk/base/legacy_checks/mongodb_mem.py b/cmk/base/legacy_checks/mongodb_mem.py index c677debc3ac..528ce4bdc61 100644 --- a/cmk/base/legacy_checks/mongodb_mem.py +++ b/cmk/base/legacy_checks/mongodb_mem.py @@ -64,6 +64,7 @@ def check_mongodb_mem(_no_item, params, parsed): check_info["mongodb_mem"] = LegacyCheckDefinition( + name="mongodb_mem", parse_function=parse_mongodb_mem, service_name="Memory used MongoDB", discovery_function=discover_mongodb_mem, diff --git a/cmk/base/legacy_checks/mongodb_replica_set.py b/cmk/base/legacy_checks/mongodb_replica_set.py index 00192d1bdf9..ed2a82e26cc 100644 --- a/cmk/base/legacy_checks/mongodb_replica_set.py +++ b/cmk/base/legacy_checks/mongodb_replica_set.py @@ -199,6 +199,7 @@ def _calculate_replication_lag(start_operation_time, secondary_operation_time): check_info["mongodb_replica_set"] = LegacyCheckDefinition( + name="mongodb_replica_set", parse_function=parse_mongodb_replica_set, service_name="MongoDB Replication Lag", discovery_function=discover_mongodb_replica_set, @@ -300,6 +301,7 @@ def _get_primary_election_time(primary): check_info["mongodb_replica_set.election"] = LegacyCheckDefinition( + name="mongodb_replica_set_election", service_name="MongoDB Replica Set Primary Election", sections=["mongodb_replica_set"], discovery_function=discover_mongodb_replica_set, diff --git a/cmk/base/legacy_checks/mongodb_replication_info.py b/cmk/base/legacy_checks/mongodb_replication_info.py index e1e6a15962c..bfd2d8898c5 100644 --- a/cmk/base/legacy_checks/mongodb_replication_info.py +++ b/cmk/base/legacy_checks/mongodb_replication_info.py @@ -141,6 +141,7 @@ def _get_as_int(data, key): check_info["mongodb_replication_info"] = LegacyCheckDefinition( + name="mongodb_replication_info", parse_function=parse_mongodb_replication_info, service_name="MongoDB Replication Info", discovery_function=discover_mongodb_replication_info, diff --git a/cmk/base/legacy_checks/moxa_iologik_register.py b/cmk/base/legacy_checks/moxa_iologik_register.py index 993e839a3fb..ed0e492df6a 100644 --- a/cmk/base/legacy_checks/moxa_iologik_register.py +++ b/cmk/base/legacy_checks/moxa_iologik_register.py @@ -35,6 +35,7 @@ def parse_moxa_iologik_register(string_table: StringTable) -> StringTable: check_info["moxa_iologik_register"] = LegacyCheckDefinition( + name="moxa_iologik_register", parse_function=parse_moxa_iologik_register, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8691."), diff --git a/cmk/base/legacy_checks/mq_queues.py b/cmk/base/legacy_checks/mq_queues.py index 589eb173be8..5e465a3065b 100644 --- a/cmk/base/legacy_checks/mq_queues.py +++ b/cmk/base/legacy_checks/mq_queues.py @@ -69,6 +69,7 @@ def parse_mq_queues(string_table: StringTable) -> StringTable: check_info["mq_queues"] = LegacyCheckDefinition( + name="mq_queues", parse_function=parse_mq_queues, service_name="Queue %s", discovery_function=inventory_mq_queues, diff --git a/cmk/base/legacy_checks/msexch_activesync.py b/cmk/base/legacy_checks/msexch_activesync.py index 55a5d55cab2..5d1eceaff5a 100644 --- a/cmk/base/legacy_checks/msexch_activesync.py +++ b/cmk/base/legacy_checks/msexch_activesync.py @@ -26,6 +26,7 @@ def check_msexch_activesync(_no_item, _no_params, parsed): check_info["msexch_activesync"] = LegacyCheckDefinition( + name="msexch_activesync", parse_function=parse_wmi_table, service_name="Exchange ActiveSync", discovery_function=discover_msexch_activesync, diff --git a/cmk/base/legacy_checks/msexch_autodiscovery.py b/cmk/base/legacy_checks/msexch_autodiscovery.py index 8702fdd781f..43f4f112e5b 100644 --- a/cmk/base/legacy_checks/msexch_autodiscovery.py +++ b/cmk/base/legacy_checks/msexch_autodiscovery.py @@ -26,6 +26,7 @@ def check_msexch_autodiscovery(_no_item, params, parsed): check_info["msexch_autodiscovery"] = LegacyCheckDefinition( + name="msexch_autodiscovery", parse_function=parse_wmi_table, service_name="Exchange Autodiscovery", discovery_function=discover_msexch_autodiscovery, diff --git a/cmk/base/legacy_checks/msexch_availability.py b/cmk/base/legacy_checks/msexch_availability.py index 337e75b4131..be16fa4de8d 100644 --- a/cmk/base/legacy_checks/msexch_availability.py +++ b/cmk/base/legacy_checks/msexch_availability.py @@ -28,6 +28,7 @@ def check_msexch_availability(item, params, parsed): check_info["msexch_availability"] = LegacyCheckDefinition( + name="msexch_availability", parse_function=parse_wmi_table, service_name="Exchange Availability Service", discovery_function=discover_msexch_availability, diff --git a/cmk/base/legacy_checks/msexch_dag.py b/cmk/base/legacy_checks/msexch_dag.py index 823a726b896..d8dfeea3b9f 100644 --- a/cmk/base/legacy_checks/msexch_dag.py +++ b/cmk/base/legacy_checks/msexch_dag.py @@ -110,6 +110,7 @@ def parse_msexch_dag(string_table: StringTable) -> StringTable: check_info["msexch_dag"] = LegacyCheckDefinition( + name="msexch_dag", parse_function=parse_msexch_dag, ) @@ -157,6 +158,7 @@ def check_msexch_dag_dbcopy(item, params, info): check_info["msexch_dag.dbcopy"] = LegacyCheckDefinition( + name="msexch_dag_dbcopy", service_name="Exchange DAG DBCopy for %s", sections=["msexch_dag"], discovery_function=inventory_msexch_dag_dbcopy, @@ -198,6 +200,7 @@ def check_msexch_dag_contentindex(item, _no_params, info): check_info["msexch_dag.contentindex"] = LegacyCheckDefinition( + name="msexch_dag_contentindex", service_name="Exchange DAG ContentIndex of %s", sections=["msexch_dag"], discovery_function=inventory_msexch_dag_contentindex, @@ -241,6 +244,7 @@ def check_msexch_dag_copyqueue(item, params, info): check_info["msexch_dag.copyqueue"] = LegacyCheckDefinition( + name="msexch_dag_copyqueue", service_name="Exchange DAG CopyQueue of %s", sections=["msexch_dag"], discovery_function=inventory_msexch_dag_copyqueue, diff --git a/cmk/base/legacy_checks/msexch_owa.py b/cmk/base/legacy_checks/msexch_owa.py index e6c67e3a288..0ffe58182d1 100644 --- a/cmk/base/legacy_checks/msexch_owa.py +++ b/cmk/base/legacy_checks/msexch_owa.py @@ -31,6 +31,7 @@ def check_msexch_owa(_no_item, params, parsed): check_info["msexch_owa"] = LegacyCheckDefinition( + name="msexch_owa", parse_function=parse_wmi_table, service_name="Exchange OWA", discovery_function=discover_msexch_owa, diff --git a/cmk/base/legacy_checks/msexch_replhealth.py b/cmk/base/legacy_checks/msexch_replhealth.py index ee993997a6e..e1f69fa0a21 100644 --- a/cmk/base/legacy_checks/msexch_replhealth.py +++ b/cmk/base/legacy_checks/msexch_replhealth.py @@ -60,6 +60,7 @@ def parse_msexch_replhealth(string_table: StringTable) -> StringTable: check_info["msexch_replhealth"] = LegacyCheckDefinition( + name="msexch_replhealth", parse_function=parse_msexch_replhealth, service_name="Exchange Replication Health %s", discovery_function=inventory_msexch_replhealth, diff --git a/cmk/base/legacy_checks/msoffice_licenses.py b/cmk/base/legacy_checks/msoffice_licenses.py index 45c8b5f9ef4..e76642eb6e4 100644 --- a/cmk/base/legacy_checks/msoffice_licenses.py +++ b/cmk/base/legacy_checks/msoffice_licenses.py @@ -100,6 +100,7 @@ def discover_msoffice_licenses(section): check_info["msoffice_licenses"] = LegacyCheckDefinition( + name="msoffice_licenses", parse_function=parse_msoffice_licenses, service_name="MS Office Licenses %s", discovery_function=discover_msoffice_licenses, diff --git a/cmk/base/legacy_checks/msoffice_serviceplans.py b/cmk/base/legacy_checks/msoffice_serviceplans.py index 3a550811fa5..89a0f02bd25 100644 --- a/cmk/base/legacy_checks/msoffice_serviceplans.py +++ b/cmk/base/legacy_checks/msoffice_serviceplans.py @@ -57,6 +57,7 @@ def parse_msoffice_serviceplans(string_table: StringTable) -> StringTable: check_info["msoffice_serviceplans"] = LegacyCheckDefinition( + name="msoffice_serviceplans", parse_function=parse_msoffice_serviceplans, service_name="MS Office Serviceplans %s", discovery_function=inventory_msoffice_serviceplans, diff --git a/cmk/base/legacy_checks/mssql_connections.py b/cmk/base/legacy_checks/mssql_connections.py index 890b8ff823b..932ee2b2843 100644 --- a/cmk/base/legacy_checks/mssql_connections.py +++ b/cmk/base/legacy_checks/mssql_connections.py @@ -45,6 +45,7 @@ def check_mssql_connections(item, params, parsed): check_info["mssql_connections"] = LegacyCheckDefinition( + name="mssql_connections", parse_function=parse_mssql_connections, service_name="MSSQL Connections %s", discovery_function=inventory_mssql_connections, diff --git a/cmk/base/legacy_checks/mssql_instance.py b/cmk/base/legacy_checks/mssql_instance.py index 70d25495346..0127b37c066 100644 --- a/cmk/base/legacy_checks/mssql_instance.py +++ b/cmk/base/legacy_checks/mssql_instance.py @@ -48,6 +48,7 @@ def check_mssql_instance(item, params, parsed): check_info["mssql_instance"] = LegacyCheckDefinition( + name="mssql_instance", service_name="MSSQL %s Instance", discovery_function=inventory_mssql_instance, check_function=check_mssql_instance, diff --git a/cmk/base/legacy_checks/mysql.py b/cmk/base/legacy_checks/mysql.py index 2fd735dcd03..a14b12b2019 100644 --- a/cmk/base/legacy_checks/mysql.py +++ b/cmk/base/legacy_checks/mysql.py @@ -77,6 +77,7 @@ def check_mysql_version(item, _no_params, parsed): check_info["mysql"] = LegacyCheckDefinition( + name="mysql", parse_function=parse_mysql, service_name="MySQL Version %s", discovery_function=_discover_keys({"version"}), @@ -136,6 +137,7 @@ def check_mysql_sessions(item, params, parsed): check_info["mysql.sessions"] = LegacyCheckDefinition( + name="mysql_sessions", service_name="MySQL Sessions %s", sections=["mysql"], discovery_function=discover_mysql_sessions, @@ -226,6 +228,7 @@ def check_diskstat_line( check_info["mysql.innodb_io"] = LegacyCheckDefinition( + name="mysql_innodb_io", service_name="MySQL InnoDB IO %s", sections=["mysql"], discovery_function=_discover_keys({"Innodb_data_read"}), @@ -306,6 +309,7 @@ def check_mysql_connections(item, params, parsed): check_info["mysql.connections"] = LegacyCheckDefinition( + name="mysql_connections", service_name="MySQL Connections %s", sections=["mysql"], discovery_function=_discover_keys( @@ -357,6 +361,7 @@ def check_mysql_galerasync(item, _no_params, parsed): check_info["mysql.galerasync"] = LegacyCheckDefinition( + name="mysql_galerasync", service_name="MySQL Galera Sync %s", sections=["mysql"], discovery_function=inventory_mysql_galerasync, @@ -399,6 +404,7 @@ def check_mysql_galeradonor(item, params, parsed): check_info["mysql.galeradonor"] = LegacyCheckDefinition( + name="mysql_galeradonor", service_name="MySQL Galera Donor %s", sections=["mysql"], discovery_function=inventory_mysql_galeradonor, @@ -437,6 +443,7 @@ def check_mysql_galerastartup(item, _no_params, parsed): check_info["mysql.galerastartup"] = LegacyCheckDefinition( + name="mysql_galerastartup", service_name="MySQL Galera Startup %s", sections=["mysql"], discovery_function=inventory_mysql_galerastartup, @@ -485,6 +492,7 @@ def check_mysql_galerasize(item, params, parsed): check_info["mysql.galerasize"] = LegacyCheckDefinition( + name="mysql_galerasize", service_name="MySQL Galera Size %s", sections=["mysql"], discovery_function=inventory_mysql_galerasize, @@ -524,6 +532,7 @@ def check_mysql_galerastatus(item, _no_params, parsed): check_info["mysql.galerastatus"] = LegacyCheckDefinition( + name="mysql_galerastatus", service_name="MySQL Galera Status %s", sections=["mysql"], discovery_function=inventory_mysql_galerastatus, diff --git a/cmk/base/legacy_checks/mysql_ping.py b/cmk/base/legacy_checks/mysql_ping.py index 94627fcb1a9..d2d903f8252 100644 --- a/cmk/base/legacy_checks/mysql_ping.py +++ b/cmk/base/legacy_checks/mysql_ping.py @@ -42,6 +42,7 @@ def discover_mysql_ping(section): check_info["mysql_ping"] = LegacyCheckDefinition( + name="mysql_ping", parse_function=parse_mysql_ping, service_name="MySQL Instance %s", discovery_function=discover_mysql_ping, diff --git a/cmk/base/legacy_checks/netapp_cluster.py b/cmk/base/legacy_checks/netapp_cluster.py index a246826a244..f75d2567f36 100644 --- a/cmk/base/legacy_checks/netapp_cluster.py +++ b/cmk/base/legacy_checks/netapp_cluster.py @@ -95,6 +95,7 @@ def parse_netapp_cluster(string_table: StringTable) -> StringTable: check_info["netapp_cluster"] = LegacyCheckDefinition( + name="netapp_cluster", parse_function=parse_netapp_cluster, detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "netapp release"), diff --git a/cmk/base/legacy_checks/netapp_cpu.py b/cmk/base/legacy_checks/netapp_cpu.py index 2de2b6c78cc..50798d994c0 100644 --- a/cmk/base/legacy_checks/netapp_cpu.py +++ b/cmk/base/legacy_checks/netapp_cpu.py @@ -25,6 +25,7 @@ def discover_netapp_cpu(info): check_info["netapp_cpu"] = LegacyCheckDefinition( + name="netapp_cpu", parse_function=parse_netapp_cpu, detect=all_of( startswith(".1.3.6.1.2.1.1.1.0", "NetApp Release"), exists(".1.3.6.1.4.1.789.1.2.1.3.0") diff --git a/cmk/base/legacy_checks/netapp_fcpio.py b/cmk/base/legacy_checks/netapp_fcpio.py index 56950b0c96d..39f4bbd20fa 100644 --- a/cmk/base/legacy_checks/netapp_fcpio.py +++ b/cmk/base/legacy_checks/netapp_fcpio.py @@ -57,6 +57,7 @@ def discover_netapp_fcpio(info): check_info["netapp_fcpio"] = LegacyCheckDefinition( + name="netapp_fcpio", parse_function=parse_netapp_fcpio, detect=all_of( startswith(".1.3.6.1.2.1.1.1.0", "NetApp Release"), exists(".1.3.6.1.4.1.789.1.17.20.0") diff --git a/cmk/base/legacy_checks/netapp_vfiler.py b/cmk/base/legacy_checks/netapp_vfiler.py index 291f01a6a03..4d09ad2dddd 100644 --- a/cmk/base/legacy_checks/netapp_vfiler.py +++ b/cmk/base/legacy_checks/netapp_vfiler.py @@ -41,6 +41,7 @@ def parse_netapp_vfiler(string_table: StringTable) -> StringTable: check_info["netapp_vfiler"] = LegacyCheckDefinition( + name="netapp_vfiler", parse_function=parse_netapp_vfiler, detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "netapp release"), diff --git a/cmk/base/legacy_checks/netctr.py b/cmk/base/legacy_checks/netctr.py index dd45c8f5597..0950e1e1580 100644 --- a/cmk/base/legacy_checks/netctr.py +++ b/cmk/base/legacy_checks/netctr.py @@ -103,10 +103,12 @@ def parse_netctr(string_table: StringTable) -> StringTable: check_info["netctr"] = LegacyCheckDefinition( + name="netctr", parse_function=parse_netctr, ) check_info["netctr.combined"] = LegacyCheckDefinition( + name="netctr_combined", service_name="NIC %s counters", sections=["netctr"], discovery_function=inventory_netctr_combined, diff --git a/cmk/base/legacy_checks/netextreme_cpu_util.py b/cmk/base/legacy_checks/netextreme_cpu_util.py index 349f5c860e2..3c2c925190e 100644 --- a/cmk/base/legacy_checks/netextreme_cpu_util.py +++ b/cmk/base/legacy_checks/netextreme_cpu_util.py @@ -30,6 +30,7 @@ def parse_netextreme_cpu_util(string_table: StringTable) -> StringTable: check_info["netextreme_cpu_util"] = LegacyCheckDefinition( + name="netextreme_cpu_util", parse_function=parse_netextreme_cpu_util, detect=DETECT_NETEXTREME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netextreme_fan.py b/cmk/base/legacy_checks/netextreme_fan.py index a08aea04d6c..d47e6afcd9a 100644 --- a/cmk/base/legacy_checks/netextreme_fan.py +++ b/cmk/base/legacy_checks/netextreme_fan.py @@ -36,6 +36,7 @@ def parse_netextreme_fan(string_table: StringTable) -> StringTable: check_info["netextreme_fan"] = LegacyCheckDefinition( + name="netextreme_fan", parse_function=parse_netextreme_fan, detect=DETECT_NETEXTREME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netextreme_psu.py b/cmk/base/legacy_checks/netextreme_psu.py index f39c59579a7..6a1de1ec688 100644 --- a/cmk/base/legacy_checks/netextreme_psu.py +++ b/cmk/base/legacy_checks/netextreme_psu.py @@ -30,6 +30,7 @@ def discover_netextreme_psu(section): check_info["netextreme_psu"] = LegacyCheckDefinition( + name="netextreme_psu", detect=DETECT_NETEXTREME, fetch=SNMPTree( base=".1.3.6.1.4.1.1916.1.1.1.40", diff --git a/cmk/base/legacy_checks/netextreme_psu_in.py b/cmk/base/legacy_checks/netextreme_psu_in.py index 94214587f27..44c31183066 100644 --- a/cmk/base/legacy_checks/netextreme_psu_in.py +++ b/cmk/base/legacy_checks/netextreme_psu_in.py @@ -35,6 +35,7 @@ def discover_netextreme_psu_in(section): check_info["netextreme_psu_in"] = LegacyCheckDefinition( + name="netextreme_psu_in", detect=DETECT_NETEXTREME, fetch=SNMPTree( base=".1.3.6.1.4.1.1916.1.1.1.27.1", diff --git a/cmk/base/legacy_checks/netextreme_psu_out.py b/cmk/base/legacy_checks/netextreme_psu_out.py index 41856e2ba5c..47ecd118780 100644 --- a/cmk/base/legacy_checks/netextreme_psu_out.py +++ b/cmk/base/legacy_checks/netextreme_psu_out.py @@ -57,6 +57,7 @@ def discover_netextreme_psu_out(section): check_info["netextreme_psu_out"] = LegacyCheckDefinition( + name="netextreme_psu_out", detect=DETECT_NETEXTREME, fetch=SNMPTree( base=".1.3.6.1.4.1.1916.1.1.1.38.1", diff --git a/cmk/base/legacy_checks/netextreme_temp.py b/cmk/base/legacy_checks/netextreme_temp.py index 9790a7f261a..f79559767a9 100644 --- a/cmk/base/legacy_checks/netextreme_temp.py +++ b/cmk/base/legacy_checks/netextreme_temp.py @@ -29,6 +29,7 @@ def parse_netextreme_temp(string_table: StringTable) -> StringTable | None: check_info["netextreme_temp"] = LegacyCheckDefinition( + name="netextreme_temp", parse_function=parse_netextreme_temp, detect=DETECT_NETEXTREME, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netgear_fans.py b/cmk/base/legacy_checks/netgear_fans.py index 3c170c4d534..7fbf8755c04 100644 --- a/cmk/base/legacy_checks/netgear_fans.py +++ b/cmk/base/legacy_checks/netgear_fans.py @@ -123,6 +123,7 @@ def check_netgear_fans(item, params, parsed): check_info["netgear_fans"] = LegacyCheckDefinition( + name="netgear_fans", detect=DETECT_NETGEAR, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/netgear_powersupplies.py b/cmk/base/legacy_checks/netgear_powersupplies.py index 349361248de..bc257c57ca0 100644 --- a/cmk/base/legacy_checks/netgear_powersupplies.py +++ b/cmk/base/legacy_checks/netgear_powersupplies.py @@ -44,6 +44,7 @@ def check_netgear_powersupplies(item, params, parsed): check_info["netgear_powersupplies"] = LegacyCheckDefinition( + name="netgear_powersupplies", detect=DETECT_NETGEAR, fetch=SNMPTree( base=".1.3.6.1.4.1.4526.10.43.1.7.1", diff --git a/cmk/base/legacy_checks/netgear_temp.py b/cmk/base/legacy_checks/netgear_temp.py index 6cc68bde532..c1b6f09471b 100644 --- a/cmk/base/legacy_checks/netgear_temp.py +++ b/cmk/base/legacy_checks/netgear_temp.py @@ -107,6 +107,7 @@ def check_netgear_temp(item, params, parsed): check_info["netgear_temp"] = LegacyCheckDefinition( + name="netgear_temp", detect=DETECT_NETGEAR, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/netscaler_cpu.py b/cmk/base/legacy_checks/netscaler_cpu.py index d293060409b..09c44e285ab 100644 --- a/cmk/base/legacy_checks/netscaler_cpu.py +++ b/cmk/base/legacy_checks/netscaler_cpu.py @@ -49,6 +49,7 @@ def parse_netscaler_cpu(string_table: StringTable) -> StringTable: check_info["netscaler_cpu"] = LegacyCheckDefinition( + name="netscaler_cpu", parse_function=parse_netscaler_cpu, detect=SNMP_DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netscaler_dnsrates.py b/cmk/base/legacy_checks/netscaler_dnsrates.py index cbb596af64b..3579f83579e 100644 --- a/cmk/base/legacy_checks/netscaler_dnsrates.py +++ b/cmk/base/legacy_checks/netscaler_dnsrates.py @@ -51,6 +51,7 @@ def parse_netscaler_dnsrates(string_table: StringTable) -> StringTable: check_info["netscaler_dnsrates"] = LegacyCheckDefinition( + name="netscaler_dnsrates", parse_function=parse_netscaler_dnsrates, detect=SNMP_DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netscaler_ha.py b/cmk/base/legacy_checks/netscaler_ha.py index 1374669c15b..7a21d6f88cd 100644 --- a/cmk/base/legacy_checks/netscaler_ha.py +++ b/cmk/base/legacy_checks/netscaler_ha.py @@ -90,6 +90,7 @@ def parse_netscaler_ha(string_table: StringTable) -> StringTable: check_info["netscaler_ha"] = LegacyCheckDefinition( + name="netscaler_ha", parse_function=parse_netscaler_ha, detect=SNMP_DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netscaler_health.py b/cmk/base/legacy_checks/netscaler_health.py index 097c9a4c587..07c05702cf3 100644 --- a/cmk/base/legacy_checks/netscaler_health.py +++ b/cmk/base/legacy_checks/netscaler_health.py @@ -39,6 +39,7 @@ def parse_netscaler_health(string_table: StringTable) -> StringTable: check_info["netscaler_health"] = LegacyCheckDefinition( + name="netscaler_health", parse_function=parse_netscaler_health, detect=SNMP_DETECT, fetch=SNMPTree( @@ -72,6 +73,7 @@ def check_netscaler_health_fan(item, params, info): check_info["netscaler_health.fan"] = LegacyCheckDefinition( + name="netscaler_health_fan", service_name="FAN %s", sections=["netscaler_health"], discovery_function=inventory_netscaler_health_fan, @@ -107,6 +109,7 @@ def check_netscaler_health_temp(item, params, info): check_info["netscaler_health.temp"] = LegacyCheckDefinition( + name="netscaler_health_temp", service_name="Temperature %s", sections=["netscaler_health"], discovery_function=inventory_netscaler_health_temp, @@ -154,6 +157,7 @@ def check_netscaler_health_psu(item, _no_params, info): check_info["netscaler_health.psu"] = LegacyCheckDefinition( + name="netscaler_health_psu", service_name="Power Supply %s", sections=["netscaler_health"], discovery_function=inventory_netscaler_health_psu, diff --git a/cmk/base/legacy_checks/netscaler_mem.py b/cmk/base/legacy_checks/netscaler_mem.py index af131d1de1b..9d5c9eee322 100644 --- a/cmk/base/legacy_checks/netscaler_mem.py +++ b/cmk/base/legacy_checks/netscaler_mem.py @@ -41,6 +41,7 @@ def parse_netscaler_mem(string_table: StringTable) -> StringTable: check_info["netscaler_mem"] = LegacyCheckDefinition( + name="netscaler_mem", parse_function=parse_netscaler_mem, detect=SNMP_DETECT, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/netstat.py b/cmk/base/legacy_checks/netstat.py index b3bc360e848..4b56e3d4fc1 100644 --- a/cmk/base/legacy_checks/netstat.py +++ b/cmk/base/legacy_checks/netstat.py @@ -67,6 +67,7 @@ def split_ip_address(ip_address): check_info["netstat"] = LegacyCheckDefinition( + name="netstat", parse_function=parse_netstat, service_name="TCP Connection %s", check_function=check_netstat_generic, diff --git a/cmk/base/legacy_checks/nfsexports.py b/cmk/base/legacy_checks/nfsexports.py index cf1329dac8a..9431c3952ce 100644 --- a/cmk/base/legacy_checks/nfsexports.py +++ b/cmk/base/legacy_checks/nfsexports.py @@ -52,6 +52,7 @@ def parse_nfsexports(string_table: StringTable) -> StringTable: check_info["nfsexports"] = LegacyCheckDefinition( + name="nfsexports", parse_function=parse_nfsexports, service_name="NFS export %s", discovery_function=inventory_nfsexports, diff --git a/cmk/base/legacy_checks/nginx_status.py b/cmk/base/legacy_checks/nginx_status.py index e39526efd84..1583306e7c8 100644 --- a/cmk/base/legacy_checks/nginx_status.py +++ b/cmk/base/legacy_checks/nginx_status.py @@ -99,6 +99,7 @@ def discover_nginx_status(section): check_info["nginx_status"] = LegacyCheckDefinition( + name="nginx_status", parse_function=parse_nginx_status, service_name="Nginx %s Status", discovery_function=discover_nginx_status, diff --git a/cmk/base/legacy_checks/nimble_latency.py b/cmk/base/legacy_checks/nimble_latency.py index 64603f77cb2..910a1088328 100644 --- a/cmk/base/legacy_checks/nimble_latency.py +++ b/cmk/base/legacy_checks/nimble_latency.py @@ -121,6 +121,7 @@ def discover_nimble_latency(parsed): check_info["nimble_latency"] = LegacyCheckDefinition( + name="nimble_latency", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.37447.3.1"), fetch=SNMPTree( base=".1.3.6.1.4.1.37447.1.2.1", @@ -184,6 +185,7 @@ def discover_nimble_latency_write(parsed): check_info["nimble_latency.write"] = LegacyCheckDefinition( + name="nimble_latency_write", service_name="Volume %s Write IO", sections=["nimble_latency"], discovery_function=discover_nimble_latency_write, diff --git a/cmk/base/legacy_checks/nimble_volumes.py b/cmk/base/legacy_checks/nimble_volumes.py index 57244cec0a3..a229b47912d 100644 --- a/cmk/base/legacy_checks/nimble_volumes.py +++ b/cmk/base/legacy_checks/nimble_volumes.py @@ -35,6 +35,7 @@ def parse_nimble_volumes(string_table: StringTable) -> StringTable: check_info["nimble_volumes"] = LegacyCheckDefinition( + name="nimble_volumes", parse_function=parse_nimble_volumes, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.37447.3.1"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/nullmailer_mailq.py b/cmk/base/legacy_checks/nullmailer_mailq.py index 75447e08f9b..8d29176fd2c 100644 --- a/cmk/base/legacy_checks/nullmailer_mailq.py +++ b/cmk/base/legacy_checks/nullmailer_mailq.py @@ -29,6 +29,7 @@ def discover_nullmailer_mailq(parsed): check_info["nullmailer_mailq"] = LegacyCheckDefinition( + name="nullmailer_mailq", parse_function=parse_nullmailer_mailq, service_name="Nullmailer Queue", discovery_function=discover_nullmailer_mailq, diff --git a/cmk/base/legacy_checks/nvidia.py b/cmk/base/legacy_checks/nvidia.py index ab7988dbea5..76ea286dadb 100644 --- a/cmk/base/legacy_checks/nvidia.py +++ b/cmk/base/legacy_checks/nvidia.py @@ -42,6 +42,7 @@ def parse_nvidia(string_table: StringTable) -> StringTable: check_info["nvidia"] = LegacyCheckDefinition( + name="nvidia", parse_function=parse_nvidia, ) @@ -51,6 +52,7 @@ def discover_nvidia_temp(info): check_info["nvidia.temp"] = LegacyCheckDefinition( + name="nvidia_temp", service_name="Temperature %s", sections=["nvidia"], discovery_function=discover_nvidia_temp, @@ -65,6 +67,7 @@ def discover_nvidia_temp_core(info): check_info["nvidia.temp_core"] = LegacyCheckDefinition( + name="nvidia_temp_core", service_name="Temperature %s", sections=["nvidia"], discovery_function=discover_nvidia_temp_core, @@ -92,6 +95,7 @@ def check_nvidia_errors(_no_item, _no_params, info): check_info["nvidia.errors"] = LegacyCheckDefinition( + name="nvidia_errors", service_name="NVIDIA GPU Errors", sections=["nvidia"], discovery_function=inventory_nvidia_errors, diff --git a/cmk/base/legacy_checks/omd_apache.py b/cmk/base/legacy_checks/omd_apache.py index a0212d67ba6..606633a5bc8 100644 --- a/cmk/base/legacy_checks/omd_apache.py +++ b/cmk/base/legacy_checks/omd_apache.py @@ -118,6 +118,7 @@ def check_omd_apache(item, _no_params, parsed): # This check uses the section defined in cmk/base/plugins/agent_based/omd_apache.py! check_info["omd_apache"] = LegacyCheckDefinition( + name="omd_apache", service_name="OMD %s apache", discovery_function=inventory_omd_apache, check_function=check_omd_apache, diff --git a/cmk/base/legacy_checks/openbsd_sensors.py b/cmk/base/legacy_checks/openbsd_sensors.py index 37a2d49793f..cd78cdddb80 100644 --- a/cmk/base/legacy_checks/openbsd_sensors.py +++ b/cmk/base/legacy_checks/openbsd_sensors.py @@ -194,6 +194,7 @@ def discover_openbsd_sensors(parsed): check_info["openbsd_sensors"] = LegacyCheckDefinition( + name="openbsd_sensors", detect=exists(".1.3.6.1.4.1.30155.2.1.1.0"), fetch=SNMPTree( base=".1.3.6.1.4.1.30155.2.1.2.1", @@ -230,6 +231,7 @@ def discover_openbsd_sensors_fan(parsed): check_info["openbsd_sensors.fan"] = LegacyCheckDefinition( + name="openbsd_sensors_fan", service_name="Fan %s", sections=["openbsd_sensors"], discovery_function=discover_openbsd_sensors_fan, @@ -270,6 +272,7 @@ def discover_openbsd_sensors_voltage(parsed): check_info["openbsd_sensors.voltage"] = LegacyCheckDefinition( + name="openbsd_sensors_voltage", service_name="Voltage Type %s", sections=["openbsd_sensors"], discovery_function=discover_openbsd_sensors_voltage, @@ -300,6 +303,7 @@ def discover_openbsd_sensors_powersupply(parsed): check_info["openbsd_sensors.powersupply"] = LegacyCheckDefinition( + name="openbsd_sensors_powersupply", service_name="Powersupply %s", sections=["openbsd_sensors"], discovery_function=discover_openbsd_sensors_powersupply, @@ -329,6 +333,7 @@ def discover_openbsd_sensors_indicator(parsed): check_info["openbsd_sensors.indicator"] = LegacyCheckDefinition( + name="openbsd_sensors_indicator", service_name="Indicator %s", sections=["openbsd_sensors"], discovery_function=discover_openbsd_sensors_indicator, @@ -358,6 +363,7 @@ def discover_openbsd_sensors_drive(parsed): check_info["openbsd_sensors.drive"] = LegacyCheckDefinition( + name="openbsd_sensors_drive", service_name="Drive %s", sections=["openbsd_sensors"], discovery_function=discover_openbsd_sensors_drive, diff --git a/cmk/base/legacy_checks/openhardwaremonitor.py b/cmk/base/legacy_checks/openhardwaremonitor.py index 2e82074cf2f..255dcd96a86 100644 --- a/cmk/base/legacy_checks/openhardwaremonitor.py +++ b/cmk/base/legacy_checks/openhardwaremonitor.py @@ -175,6 +175,7 @@ def check_openhardwaremonitor_clock(item, params, parsed): # '----------------------------------------------------------------------' check_info["openhardwaremonitor"] = LegacyCheckDefinition( + name="openhardwaremonitor", parse_function=parse_openhardwaremonitor, service_name="Clock %s", discovery_function=discover_openhardwaremonitor, @@ -208,6 +209,7 @@ def discover_openhardwaremonitor_temperature(parsed): check_info["openhardwaremonitor.temperature"] = LegacyCheckDefinition( + name="openhardwaremonitor_temperature", service_name="Temperature %s", sections=["openhardwaremonitor"], discovery_function=discover_openhardwaremonitor_temperature, @@ -242,6 +244,7 @@ def check_openhardwaremonitor_power(item, params, parsed): # '----------------------------------------------------------------------' check_info["openhardwaremonitor.power"] = LegacyCheckDefinition( + name="openhardwaremonitor_power", service_name="Power %s", sections=["openhardwaremonitor"], discovery_function=discover_openhardwaremonitor_power, @@ -272,6 +275,7 @@ def discover_openhardwaremonitor_fan(parsed): check_info["openhardwaremonitor.fan"] = LegacyCheckDefinition( + name="openhardwaremonitor_fan", service_name="Fan %s", sections=["openhardwaremonitor"], discovery_function=discover_openhardwaremonitor_fan, @@ -334,6 +338,7 @@ def check_openhardwaremonitor_smart(item, params, parsed): # combines different sensors per item (but not all, i.e. hdd temperature is still # reported as a temperature item) check_info["openhardwaremonitor.smart"] = LegacyCheckDefinition( + name="openhardwaremonitor_smart", service_name="SMART %s Stats", sections=["openhardwaremonitor"], discovery_function=inventory_openhardwaremonitor_smart, diff --git a/cmk/base/legacy_checks/openvpn_clients.py b/cmk/base/legacy_checks/openvpn_clients.py index 2277c5a0880..034aee384ab 100644 --- a/cmk/base/legacy_checks/openvpn_clients.py +++ b/cmk/base/legacy_checks/openvpn_clients.py @@ -56,6 +56,7 @@ def parse_openvpn_clients(string_table: StringTable) -> StringTable: check_info["openvpn_clients"] = LegacyCheckDefinition( + name="openvpn_clients", parse_function=parse_openvpn_clients, service_name="OpenVPN Client %s", discovery_function=inventory_openvpn_clients, diff --git a/cmk/base/legacy_checks/oracle_crs_version.py b/cmk/base/legacy_checks/oracle_crs_version.py index eb2bf511764..203e6cec7e3 100644 --- a/cmk/base/legacy_checks/oracle_crs_version.py +++ b/cmk/base/legacy_checks/oracle_crs_version.py @@ -29,6 +29,7 @@ def parse_oracle_crs_version(string_table: StringTable) -> StringTable: check_info["oracle_crs_version"] = LegacyCheckDefinition( + name="oracle_crs_version", parse_function=parse_oracle_crs_version, service_name="ORA-GI Version", discovery_function=inventory_oracle_crs_version, diff --git a/cmk/base/legacy_checks/oracle_crs_voting.py b/cmk/base/legacy_checks/oracle_crs_voting.py index a6a83ba0a7c..e32a9aed398 100644 --- a/cmk/base/legacy_checks/oracle_crs_voting.py +++ b/cmk/base/legacy_checks/oracle_crs_voting.py @@ -52,6 +52,7 @@ def parse_oracle_crs_voting(string_table: StringTable) -> StringTable: check_info["oracle_crs_voting"] = LegacyCheckDefinition( + name="oracle_crs_voting", parse_function=parse_oracle_crs_voting, service_name="ORA-GI Voting", discovery_function=inventory_oracle_crs_voting, diff --git a/cmk/base/legacy_checks/oracle_dataguard_stats.py b/cmk/base/legacy_checks/oracle_dataguard_stats.py index 87947bf8fbc..c3e8ec88aa5 100644 --- a/cmk/base/legacy_checks/oracle_dataguard_stats.py +++ b/cmk/base/legacy_checks/oracle_dataguard_stats.py @@ -158,6 +158,7 @@ def check_oracle_dataguard_stats(item, params, parsed): # pylint: disable=too-m check_info["oracle_dataguard_stats"] = LegacyCheckDefinition( + name="oracle_dataguard_stats", # section is already migrated! service_name="ORA %s Dataguard-Stats", discovery_function=inventory_oracle_dataguard_stats, diff --git a/cmk/base/legacy_checks/oracle_diva_csm.py b/cmk/base/legacy_checks/oracle_diva_csm.py index 30589926ef1..f0825f24305 100644 --- a/cmk/base/legacy_checks/oracle_diva_csm.py +++ b/cmk/base/legacy_checks/oracle_diva_csm.py @@ -90,6 +90,7 @@ def check_oracle_diva_csm(item, params, info): check_info["oracle_diva_csm"] = LegacyCheckDefinition( + name="oracle_diva_csm", parse_function=parse_oracle_diva_csm, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.311.1.1.3.1.2"), fetch=[ @@ -133,6 +134,7 @@ def check_oracle_diva_csm_drive(item, params, info): check_info["oracle_diva_csm.drive"] = LegacyCheckDefinition( + name="oracle_diva_csm_drive", service_name="DIVA Status %s", sections=["oracle_diva_csm"], discovery_function=discover_oracle_diva_csm_drive, @@ -149,6 +151,7 @@ def check_oracle_diva_csm_actor(item, params, info): check_info["oracle_diva_csm.actor"] = LegacyCheckDefinition( + name="oracle_diva_csm_actor", service_name="DIVA Status %s", sections=["oracle_diva_csm"], discovery_function=discover_oracle_diva_csm_actor, @@ -165,6 +168,7 @@ def check_oracle_diva_csm_archive(item, params, info): check_info["oracle_diva_csm.archive"] = LegacyCheckDefinition( + name="oracle_diva_csm_archive", service_name="DIVA Status %s", sections=["oracle_diva_csm"], discovery_function=discover_oracle_diva_csm_archive, @@ -223,6 +227,7 @@ def check_oracle_diva_csm_objects(item, params, info): check_info["oracle_diva_csm.objects"] = LegacyCheckDefinition( + name="oracle_diva_csm_objects", service_name="DIVA Managed Objects", sections=["oracle_diva_csm"], discovery_function=inventory_oracle_diva_csm_objects, @@ -261,6 +266,7 @@ def check_oracle_diva_csm_tapes(item, params, info): check_info["oracle_diva_csm.tapes"] = LegacyCheckDefinition( + name="oracle_diva_csm_tapes", service_name="DIVA Blank Tapes", sections=["oracle_diva_csm"], discovery_function=inventory_oracle_diva_csm_tapes, diff --git a/cmk/base/legacy_checks/oracle_jobs.py b/cmk/base/legacy_checks/oracle_jobs.py index 0b162b73784..ee6e65152bd 100644 --- a/cmk/base/legacy_checks/oracle_jobs.py +++ b/cmk/base/legacy_checks/oracle_jobs.py @@ -264,6 +264,7 @@ def parse_oracle_jobs(string_table: StringTable) -> StringTable: check_info["oracle_jobs"] = LegacyCheckDefinition( + name="oracle_jobs", parse_function=parse_oracle_jobs, service_name="ORA %s Job", discovery_function=inventory_oracle_jobs, diff --git a/cmk/base/legacy_checks/oracle_locks.py b/cmk/base/legacy_checks/oracle_locks.py index 6d6c7d8efbf..9f60dfd3473 100644 --- a/cmk/base/legacy_checks/oracle_locks.py +++ b/cmk/base/legacy_checks/oracle_locks.py @@ -128,6 +128,7 @@ def parse_oracle_locks(string_table: StringTable) -> StringTable: check_info["oracle_locks"] = LegacyCheckDefinition( + name="oracle_locks", parse_function=parse_oracle_locks, service_name="ORA %s Locks", discovery_function=inventory_oracle_locks, diff --git a/cmk/base/legacy_checks/oracle_logswitches.py b/cmk/base/legacy_checks/oracle_logswitches.py index 68f8de42578..0113138ab39 100644 --- a/cmk/base/legacy_checks/oracle_logswitches.py +++ b/cmk/base/legacy_checks/oracle_logswitches.py @@ -65,6 +65,7 @@ def parse_oracle_logswitches(string_table: StringTable) -> StringTable: check_info["oracle_logswitches"] = LegacyCheckDefinition( + name="oracle_logswitches", parse_function=parse_oracle_logswitches, service_name="ORA %s Logswitches", discovery_function=inventory_oracle_logswitches, diff --git a/cmk/base/legacy_checks/oracle_longactivesessions.py b/cmk/base/legacy_checks/oracle_longactivesessions.py index 5c9227e0350..e2f922d401a 100644 --- a/cmk/base/legacy_checks/oracle_longactivesessions.py +++ b/cmk/base/legacy_checks/oracle_longactivesessions.py @@ -81,6 +81,7 @@ def parse_oracle_longactivesessions(string_table: StringTable) -> StringTable: check_info["oracle_longactivesessions"] = LegacyCheckDefinition( + name="oracle_longactivesessions", parse_function=parse_oracle_longactivesessions, service_name="ORA %s Long Active Sessions", discovery_function=inventory_oracle_longactivesessions, diff --git a/cmk/base/legacy_checks/oracle_recovery_area.py b/cmk/base/legacy_checks/oracle_recovery_area.py index 8a42a8d0f3e..43a943d7a00 100644 --- a/cmk/base/legacy_checks/oracle_recovery_area.py +++ b/cmk/base/legacy_checks/oracle_recovery_area.py @@ -68,6 +68,7 @@ def parse_oracle_recovery_area(string_table: StringTable) -> StringTable: check_info["oracle_recovery_area"] = LegacyCheckDefinition( + name="oracle_recovery_area", parse_function=parse_oracle_recovery_area, service_name="ORA %s Recovery Area", discovery_function=inventory_oracle_recovery_area, diff --git a/cmk/base/legacy_checks/oracle_recovery_status.py b/cmk/base/legacy_checks/oracle_recovery_status.py index 12df5ed3796..b5089e8b348 100644 --- a/cmk/base/legacy_checks/oracle_recovery_status.py +++ b/cmk/base/legacy_checks/oracle_recovery_status.py @@ -215,6 +215,7 @@ def parse_oracle_recovery_status(string_table: StringTable) -> StringTable: check_info["oracle_recovery_status"] = LegacyCheckDefinition( + name="oracle_recovery_status", parse_function=parse_oracle_recovery_status, service_name="ORA %s Recovery Status", discovery_function=inventory_oracle_recovery_status, diff --git a/cmk/base/legacy_checks/oracle_sessions.py b/cmk/base/legacy_checks/oracle_sessions.py index 05ab6d29d52..642deab0821 100644 --- a/cmk/base/legacy_checks/oracle_sessions.py +++ b/cmk/base/legacy_checks/oracle_sessions.py @@ -82,6 +82,7 @@ def check_oracle_sessions(item, params, parsed): check_info["oracle_sessions"] = LegacyCheckDefinition( + name="oracle_sessions", parse_function=parse_oracle_sessions, service_name="ORA %s Sessions", discovery_function=inventory_oracle_sessions, diff --git a/cmk/base/legacy_checks/oracle_undostat.py b/cmk/base/legacy_checks/oracle_undostat.py index 14bba983ef1..f9b8edf1ec4 100644 --- a/cmk/base/legacy_checks/oracle_undostat.py +++ b/cmk/base/legacy_checks/oracle_undostat.py @@ -66,6 +66,7 @@ def check_oracle_undostat(item, params, parsed): check_info["oracle_undostat"] = LegacyCheckDefinition( + name="oracle_undostat", parse_function=parse_oracle_undostat, service_name="ORA %s Undo Retention", discovery_function=discover_oracle_undostat, diff --git a/cmk/base/legacy_checks/oracle_version.py b/cmk/base/legacy_checks/oracle_version.py index e2afebd0232..171edee5e12 100644 --- a/cmk/base/legacy_checks/oracle_version.py +++ b/cmk/base/legacy_checks/oracle_version.py @@ -40,6 +40,7 @@ def parse_oracle_version(string_table: StringTable) -> StringTable: check_info["oracle_version"] = LegacyCheckDefinition( + name="oracle_version", parse_function=parse_oracle_version, service_name="ORA Version %s", discovery_function=inventory_oracle_version, diff --git a/cmk/base/legacy_checks/orion_backup.py b/cmk/base/legacy_checks/orion_backup.py index 1264119155a..6df4ef08224 100644 --- a/cmk/base/legacy_checks/orion_backup.py +++ b/cmk/base/legacy_checks/orion_backup.py @@ -32,6 +32,7 @@ def parse_orion_backup(string_table: StringTable) -> StringTable | None: check_info["orion_backup"] = LegacyCheckDefinition( + name="orion_backup", parse_function=parse_orion_backup, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.20246"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/orion_batterytest.py b/cmk/base/legacy_checks/orion_batterytest.py index 7428c04c41f..bc597f16c90 100644 --- a/cmk/base/legacy_checks/orion_batterytest.py +++ b/cmk/base/legacy_checks/orion_batterytest.py @@ -41,6 +41,7 @@ def parse_orion_batterytest(string_table: StringTable) -> StringTable | None: check_info["orion_batterytest"] = LegacyCheckDefinition( + name="orion_batterytest", parse_function=parse_orion_batterytest, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.20246"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/orion_system.py b/cmk/base/legacy_checks/orion_system.py index 2f9573d8b63..9463683cba1 100644 --- a/cmk/base/legacy_checks/orion_system.py +++ b/cmk/base/legacy_checks/orion_system.py @@ -87,6 +87,7 @@ def check_orion_system_temp(item, params, parsed): check_info["orion_system"] = LegacyCheckDefinition( + name="orion_system", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.20246"), fetch=SNMPTree( base=".1.3.6.1.4.1.20246.2.3.1.1.1.2.3", @@ -113,6 +114,7 @@ def check_orion_system_charging(item, params, parsed): check_info["orion_system.charging"] = LegacyCheckDefinition( + name="orion_system_charging", service_name="Charge %s", sections=["orion_system"], discovery_function=inventory_orion_system_charging, @@ -130,6 +132,7 @@ def check_orion_system_electrical(item, params, parsed): check_info["orion_system.dc"] = LegacyCheckDefinition( + name="orion_system_dc", service_name="Direct Current %s", sections=["orion_system"], discovery_function=discover_orion_system_electrical, diff --git a/cmk/base/legacy_checks/packeteer_fan_status.py b/cmk/base/legacy_checks/packeteer_fan_status.py index 495499199b7..1bf8becbbf1 100644 --- a/cmk/base/legacy_checks/packeteer_fan_status.py +++ b/cmk/base/legacy_checks/packeteer_fan_status.py @@ -32,6 +32,7 @@ def parse_packeteer_fan_status(string_table: StringTable) -> StringTable | None: check_info["packeteer_fan_status"] = LegacyCheckDefinition( + name="packeteer_fan_status", parse_function=parse_packeteer_fan_status, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2334"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/packeteer_ps_status.py b/cmk/base/legacy_checks/packeteer_ps_status.py index 4d0d5fa83b4..61f225ed695 100644 --- a/cmk/base/legacy_checks/packeteer_ps_status.py +++ b/cmk/base/legacy_checks/packeteer_ps_status.py @@ -29,6 +29,7 @@ def parse_packeteer_ps_status(string_table: StringTable) -> StringTable: check_info["packeteer_ps_status"] = LegacyCheckDefinition( + name="packeteer_ps_status", parse_function=parse_packeteer_ps_status, detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2334"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/palo_alto_sessions.py b/cmk/base/legacy_checks/palo_alto_sessions.py index eb555b0d52e..0a6e5447b24 100644 --- a/cmk/base/legacy_checks/palo_alto_sessions.py +++ b/cmk/base/legacy_checks/palo_alto_sessions.py @@ -64,6 +64,7 @@ def parse_palo_alto_sessions(string_table: StringTable) -> StringTable | None: check_info["palo_alto_sessions"] = LegacyCheckDefinition( + name="palo_alto_sessions", parse_function=parse_palo_alto_sessions, detect=DETECT_PALO_ALTO, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/pandacom_fan.py b/cmk/base/legacy_checks/pandacom_fan.py index 29571ebd2f8..325869dd7df 100644 --- a/cmk/base/legacy_checks/pandacom_fan.py +++ b/cmk/base/legacy_checks/pandacom_fan.py @@ -48,6 +48,7 @@ def parse_pandacom_fan(string_table: StringTable) -> StringTable: check_info["pandacom_fan"] = LegacyCheckDefinition( + name="pandacom_fan", parse_function=parse_pandacom_fan, detect=DETECT_PANDACOM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/pandacom_psu.py b/cmk/base/legacy_checks/pandacom_psu.py index 7ba1bf75ea7..d2211b5c184 100644 --- a/cmk/base/legacy_checks/pandacom_psu.py +++ b/cmk/base/legacy_checks/pandacom_psu.py @@ -86,6 +86,7 @@ def check_pandacom_psu(item, _no_params, parsed): check_info["pandacom_psu"] = LegacyCheckDefinition( + name="pandacom_psu", detect=DETECT_PANDACOM, fetch=SNMPTree( base=".1.3.6.1.4.1.3652.3.2", diff --git a/cmk/base/legacy_checks/pandacom_sys_temp.py b/cmk/base/legacy_checks/pandacom_sys_temp.py index acee6c80472..c16015a5758 100644 --- a/cmk/base/legacy_checks/pandacom_sys_temp.py +++ b/cmk/base/legacy_checks/pandacom_sys_temp.py @@ -24,6 +24,7 @@ def check_pandacom_sys_temp(item, params, info): check_info["pandacom_sys_temp"] = LegacyCheckDefinition( + name="pandacom_sys_temp", parse_function=parse_pandacom_sys_temp, detect=DETECT_PANDACOM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/pandacom_temp.py b/cmk/base/legacy_checks/pandacom_temp.py index e5865581e30..bf83ea45972 100644 --- a/cmk/base/legacy_checks/pandacom_temp.py +++ b/cmk/base/legacy_checks/pandacom_temp.py @@ -34,6 +34,7 @@ def check_pandacom_module_temp(item, params, info): check_info["pandacom_10gm_temp"] = LegacyCheckDefinition( + name="pandacom_10gm_temp", parse_function=parse_pandacom_temp, detect=DETECT_PANDACOM, fetch=SNMPTree( @@ -57,6 +58,7 @@ def check_pandacom_module_temp(item, params, info): check_info["pandacom_fc_temp"] = LegacyCheckDefinition( + name="pandacom_fc_temp", parse_function=parse_pandacom_temp, detect=DETECT_PANDACOM, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/papouch_th2e_sensors.py b/cmk/base/legacy_checks/papouch_th2e_sensors.py index 76d4c2e6c2c..f3d920fa37e 100644 --- a/cmk/base/legacy_checks/papouch_th2e_sensors.py +++ b/cmk/base/legacy_checks/papouch_th2e_sensors.py @@ -104,6 +104,7 @@ def check_papouch_th2e_sensors(item, params, parsed): check_info["papouch_th2e_sensors"] = LegacyCheckDefinition( + name="papouch_th2e_sensors", detect=all_of( contains(".1.3.6.1.2.1.1.1.0", "th2e"), startswith(".1.3.6.1.2.1.1.2.0", ".0.10.43.6.1.4.1") ), @@ -139,6 +140,7 @@ def check_papouch_th2e_sensors_dewpoint(item, params, parsed): check_info["papouch_th2e_sensors.dewpoint"] = LegacyCheckDefinition( + name="papouch_th2e_sensors_dewpoint", service_name="Dew point %s", sections=["papouch_th2e_sensors"], discovery_function=discover_papouch_th2e_sensors_dewpoint, @@ -170,6 +172,7 @@ def check_papouch_th2e_sensors_humidity(item, params, parsed): check_info["papouch_th2e_sensors.humidity"] = LegacyCheckDefinition( + name="papouch_th2e_sensors_humidity", service_name="Humidity %s", sections=["papouch_th2e_sensors"], discovery_function=inventory_papouch_th2e_sensors_humidity, diff --git a/cmk/base/legacy_checks/perle_chassis.py b/cmk/base/legacy_checks/perle_chassis.py index fdcbc2651c7..a3c9d9b9a82 100644 --- a/cmk/base/legacy_checks/perle_chassis.py +++ b/cmk/base/legacy_checks/perle_chassis.py @@ -35,6 +35,7 @@ def check_perle_chassis(_no_item, _no_params, section): check_info["perle_chassis"] = LegacyCheckDefinition( + name="perle_chassis", service_name="Chassis status", discovery_function=inventory_perle_chassis, check_function=check_perle_chassis, @@ -50,6 +51,7 @@ def check_perle_chassis_temp(item, params, section): check_info["perle_chassis.temp"] = LegacyCheckDefinition( + name="perle_chassis_temp", service_name="Temperature %s", sections=["perle_chassis"], discovery_function=inventory_perle_chassis_temp, diff --git a/cmk/base/legacy_checks/perle_chassis_slots.py b/cmk/base/legacy_checks/perle_chassis_slots.py index 4f2f1ae476e..22742a210d2 100644 --- a/cmk/base/legacy_checks/perle_chassis_slots.py +++ b/cmk/base/legacy_checks/perle_chassis_slots.py @@ -43,6 +43,7 @@ def check_perle_chassis_slots(item, _no_params, info): check_info["perle_chassis_slots"] = LegacyCheckDefinition( + name="perle_chassis_slots", # section is already migrated! service_name="Chassis status slot %s", discovery_function=inventory_perle_chassis_slots, diff --git a/cmk/base/legacy_checks/perle_modules_cm1000.py b/cmk/base/legacy_checks/perle_modules_cm1000.py index 84b12f83166..afb5f8cee75 100644 --- a/cmk/base/legacy_checks/perle_modules_cm1000.py +++ b/cmk/base/legacy_checks/perle_modules_cm1000.py @@ -105,6 +105,7 @@ def check_perle_cm_modules(item, _no_params, info): check_info["perle_modules_cm1110"] = LegacyCheckDefinition( + name="perle_modules_cm1110", parse_function=parse_perle_modules, detect=DETECT_PERLE, fetch=SNMPTree( @@ -130,6 +131,7 @@ def check_perle_cm_modules(item, _no_params, info): check_info["perle_modules_cm1000"] = LegacyCheckDefinition( + name="perle_modules_cm1000", parse_function=parse_perle_modules, detect=DETECT_PERLE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/perle_modules_mgt.py b/cmk/base/legacy_checks/perle_modules_mgt.py index 613801534d9..556a0815187 100644 --- a/cmk/base/legacy_checks/perle_modules_mgt.py +++ b/cmk/base/legacy_checks/perle_modules_mgt.py @@ -46,6 +46,7 @@ def parse_perle_modules_mgt(string_table: StringTable) -> StringTable: check_info["perle_modules_mgt"] = LegacyCheckDefinition( + name="perle_modules_mgt", parse_function=parse_perle_modules_mgt, detect=DETECT_PERLE, # If you change snmp info please adapt the related inventory plugin, diff --git a/cmk/base/legacy_checks/perle_psmu.py b/cmk/base/legacy_checks/perle_psmu.py index 15e155b77d4..25587a5d479 100644 --- a/cmk/base/legacy_checks/perle_psmu.py +++ b/cmk/base/legacy_checks/perle_psmu.py @@ -27,6 +27,7 @@ def discover_perle_psmu(info): check_info["perle_psmu"] = LegacyCheckDefinition( + name="perle_psmu", # section is already migrated! service_name="Power supply %s", discovery_function=discover_perle_psmu, @@ -47,6 +48,7 @@ def discover_perle_psmu_fan(info): check_info["perle_psmu.fan"] = LegacyCheckDefinition( + name="perle_psmu_fan", service_name="Fan %s", sections=["perle_psmu"], discovery_function=discover_perle_psmu_fan, diff --git a/cmk/base/legacy_checks/pfsense_status.py b/cmk/base/legacy_checks/pfsense_status.py index 68c73eb5b64..94204541c56 100644 --- a/cmk/base/legacy_checks/pfsense_status.py +++ b/cmk/base/legacy_checks/pfsense_status.py @@ -31,6 +31,7 @@ def parse_pfsense_status(string_table: StringTable) -> StringTable: check_info["pfsense_status"] = LegacyCheckDefinition( + name="pfsense_status", parse_function=parse_pfsense_status, detect=contains(".1.3.6.1.2.1.1.1.0", "pfsense"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/plesk_backups.py b/cmk/base/legacy_checks/plesk_backups.py index fef3e2938e3..6f3735cb693 100644 --- a/cmk/base/legacy_checks/plesk_backups.py +++ b/cmk/base/legacy_checks/plesk_backups.py @@ -87,6 +87,7 @@ def check_plesk_backups(item: str, params: Mapping[str, object], section: Sectio check_info["plesk_backups"] = LegacyCheckDefinition( + name="plesk_backups", parse_function=parse_plesk_backups, service_name="Plesk Backup %s", discovery_function=inventory_plesk_backups, diff --git a/cmk/base/legacy_checks/plesk_domains.py b/cmk/base/legacy_checks/plesk_domains.py index 8cc3d6b5272..cde7ec4bf9a 100644 --- a/cmk/base/legacy_checks/plesk_domains.py +++ b/cmk/base/legacy_checks/plesk_domains.py @@ -27,6 +27,7 @@ def parse_plesk_domains(string_table: StringTable) -> StringTable: check_info["plesk_domains"] = LegacyCheckDefinition( + name="plesk_domains", parse_function=parse_plesk_domains, service_name="Plesk Domains", discovery_function=inventory_plesk_domains, diff --git a/cmk/base/legacy_checks/poseidon_inputs.py b/cmk/base/legacy_checks/poseidon_inputs.py index 991e049d48a..a219f142ffe 100644 --- a/cmk/base/legacy_checks/poseidon_inputs.py +++ b/cmk/base/legacy_checks/poseidon_inputs.py @@ -61,6 +61,7 @@ def discover_poseidon_inputs(section): check_info["poseidon_inputs"] = LegacyCheckDefinition( + name="poseidon_inputs", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21796.3"), fetch=SNMPTree( base=".1.3.6.1.4.1.21796.3.3.1.1", diff --git a/cmk/base/legacy_checks/poseidon_temp.py b/cmk/base/legacy_checks/poseidon_temp.py index aa940808332..1750f300f3b 100644 --- a/cmk/base/legacy_checks/poseidon_temp.py +++ b/cmk/base/legacy_checks/poseidon_temp.py @@ -52,6 +52,7 @@ def discover_poseidon_temp(section): check_info["poseidon_temp"] = LegacyCheckDefinition( + name="poseidon_temp", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21796.3"), fetch=SNMPTree( base=".1.3.6.1.4.1.21796.3.3.3.1", diff --git a/cmk/base/legacy_checks/postfix_mailq.py b/cmk/base/legacy_checks/postfix_mailq.py index f9d2191ccd6..4c3ef3ad156 100644 --- a/cmk/base/legacy_checks/postfix_mailq.py +++ b/cmk/base/legacy_checks/postfix_mailq.py @@ -62,6 +62,8 @@ from cmk.base.check_api import LegacyCheckDefinition from cmk.base.config import check_info +DEFAULT_ITEM_NAME = "default" + def postfix_mailq_to_bytes(value, uom): uom = uom.lower() @@ -76,12 +78,12 @@ def postfix_mailq_to_bytes(value, uom): def parse_postfix_mailq(string_table): parsed = {} - instance_name = "" + instance_name = DEFAULT_ITEM_NAME for line in string_table: if line[0].startswith("[[[") and line[0].endswith("]]]"): # deal with the pre 2.3 agent output that will send an empty instance # name for the "default" queue. - instance_name = line[0][3:-3] or "default" + instance_name = line[0][3:-3] or DEFAULT_ITEM_NAME queueinfo = None # single and old output formats @@ -123,8 +125,13 @@ def inventory_postfix_mailq(parsed): def check_postfix_mailq(item, params, parsed): + # If the user disabled the "Use new service description" option, we arrive + # at this function with item being None. In this case we still need to + # lookup the data in parsed under the default item name. + if item is None: + item = DEFAULT_ITEM_NAME + if item not in parsed: - yield 3, "Item not found" return if not isinstance(params, dict): @@ -158,6 +165,7 @@ def check_postfix_mailq(item, params, parsed): check_info["postfix_mailq"] = LegacyCheckDefinition( + name="postfix_mailq", parse_function=parse_postfix_mailq, service_name="Postfix Queue %s", discovery_function=inventory_postfix_mailq, diff --git a/cmk/base/legacy_checks/postgres_bloat.py b/cmk/base/legacy_checks/postgres_bloat.py index b7a084b0531..c78340b4fde 100644 --- a/cmk/base/legacy_checks/postgres_bloat.py +++ b/cmk/base/legacy_checks/postgres_bloat.py @@ -156,6 +156,7 @@ def check_postgres_bloat(item, params, parsed): # pylint: disable=too-many-bran check_info["postgres_bloat"] = LegacyCheckDefinition( + name="postgres_bloat", parse_function=postgres.parse_dbs, service_name="PostgreSQL Bloat %s", discovery_function=inventory_postgres_bloat, diff --git a/cmk/base/legacy_checks/postgres_conn_time.py b/cmk/base/legacy_checks/postgres_conn_time.py index 0f026d1c272..aed44ff073f 100644 --- a/cmk/base/legacy_checks/postgres_conn_time.py +++ b/cmk/base/legacy_checks/postgres_conn_time.py @@ -48,6 +48,7 @@ def check_postgres_conn_time(item, _no_params, parsed): check_info["postgres_conn_time"] = LegacyCheckDefinition( + name="postgres_conn_time", parse_function=parse_postgres_conn_time, service_name="PostgreSQL Connection Time %s", discovery_function=inventory_postgres_conn_time, diff --git a/cmk/base/legacy_checks/postgres_connections.py b/cmk/base/legacy_checks/postgres_connections.py index f4975ebd6fd..c0ed3843489 100644 --- a/cmk/base/legacy_checks/postgres_connections.py +++ b/cmk/base/legacy_checks/postgres_connections.py @@ -130,6 +130,7 @@ def check_postgres_connections(item, params, parsed): check_info["postgres_connections"] = LegacyCheckDefinition( + name="postgres_connections", parse_function=postgres.parse_dbs, service_name="PostgreSQL Connections %s", discovery_function=inventory_postgres_connections, diff --git a/cmk/base/legacy_checks/postgres_locks.py b/cmk/base/legacy_checks/postgres_locks.py index 150c0244ae2..583e73516be 100644 --- a/cmk/base/legacy_checks/postgres_locks.py +++ b/cmk/base/legacy_checks/postgres_locks.py @@ -74,6 +74,7 @@ def check_postgres_locks(item, params, parsed): check_info["postgres_locks"] = LegacyCheckDefinition( + name="postgres_locks", parse_function=postgres.parse_dbs, service_name="PostgreSQL Locks %s", discovery_function=inventory_postgres_locks, diff --git a/cmk/base/legacy_checks/postgres_sessions.py b/cmk/base/legacy_checks/postgres_sessions.py index 271c5cb441e..3f2739159cb 100644 --- a/cmk/base/legacy_checks/postgres_sessions.py +++ b/cmk/base/legacy_checks/postgres_sessions.py @@ -79,6 +79,7 @@ def check_postgres_sessions(item, params, parsed): check_info["postgres_sessions"] = LegacyCheckDefinition( + name="postgres_sessions", parse_function=parse_postgres_sessions, service_name="PostgreSQL Daemon Sessions %s", discovery_function=inventory_postgres_sessions, diff --git a/cmk/base/legacy_checks/postgres_stat_database.py b/cmk/base/legacy_checks/postgres_stat_database.py index ec11b7a1f2e..b59ab2f0249 100644 --- a/cmk/base/legacy_checks/postgres_stat_database.py +++ b/cmk/base/legacy_checks/postgres_stat_database.py @@ -104,6 +104,7 @@ def check_postgres_stat_database(item, params, parsed): check_info["postgres_stat_database"] = LegacyCheckDefinition( + name="postgres_stat_database", parse_function=parse_postgres_stat_database, service_name="PostgreSQL DB %s Statistics", discovery_function=inventory_postgres_stat_database, @@ -136,6 +137,7 @@ def check_postgres_stat_database_size(item, params, parsed): check_info["postgres_stat_database.size"] = LegacyCheckDefinition( + name="postgres_stat_database_size", service_name="PostgreSQL DB %s Size", sections=["postgres_stat_database"], discovery_function=inventory_postgres_stat_database_size, diff --git a/cmk/base/legacy_checks/printer_supply_ricoh.py b/cmk/base/legacy_checks/printer_supply_ricoh.py index 047719350bf..ee085476f35 100644 --- a/cmk/base/legacy_checks/printer_supply_ricoh.py +++ b/cmk/base/legacy_checks/printer_supply_ricoh.py @@ -103,6 +103,7 @@ def handle_negative(code): check_info["printer_supply_ricoh"] = LegacyCheckDefinition( + name="printer_supply_ricoh", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.367.1.1"), fetch=SNMPTree( base=".1.3.6.1.4.1.367.3.2.1.2.24.1.1", diff --git a/cmk/base/legacy_checks/prometheus_custom.py b/cmk/base/legacy_checks/prometheus_custom.py index 8969323b70d..07b65853864 100644 --- a/cmk/base/legacy_checks/prometheus_custom.py +++ b/cmk/base/legacy_checks/prometheus_custom.py @@ -141,6 +141,7 @@ def discover_prometheus_custom(section): check_info["prometheus_custom"] = LegacyCheckDefinition( + name="prometheus_custom", parse_function=parse_prometheus_custom, service_name="%s", discovery_function=discover_prometheus_custom, diff --git a/cmk/base/legacy_checks/pulse_secure_cpu_util.py b/cmk/base/legacy_checks/pulse_secure_cpu_util.py index 1e32e75bf66..ae03158361f 100644 --- a/cmk/base/legacy_checks/pulse_secure_cpu_util.py +++ b/cmk/base/legacy_checks/pulse_secure_cpu_util.py @@ -36,6 +36,7 @@ def check_pulse_secure_cpu(item, params, parsed): check_info["pulse_secure_cpu_util"] = LegacyCheckDefinition( + name="pulse_secure_cpu_util", detect=pulse_secure.DETECT_PULSE_SECURE, fetch=SNMPTree( base=".1.3.6.1.4.1.12532", diff --git a/cmk/base/legacy_checks/pulse_secure_disk_util.py b/cmk/base/legacy_checks/pulse_secure_disk_util.py index cf2c3bea6de..de54f209c5e 100644 --- a/cmk/base/legacy_checks/pulse_secure_disk_util.py +++ b/cmk/base/legacy_checks/pulse_secure_disk_util.py @@ -40,6 +40,7 @@ def check_pulse_secure_disk_util(item, params, parsed): check_info["pulse_secure_disk_util"] = LegacyCheckDefinition( + name="pulse_secure_disk_util", detect=pulse_secure.DETECT_PULSE_SECURE, fetch=SNMPTree( base=".1.3.6.1.4.1.12532", diff --git a/cmk/base/legacy_checks/pulse_secure_log_util.py b/cmk/base/legacy_checks/pulse_secure_log_util.py index cff406f6557..9d9a950dc5f 100644 --- a/cmk/base/legacy_checks/pulse_secure_log_util.py +++ b/cmk/base/legacy_checks/pulse_secure_log_util.py @@ -39,6 +39,7 @@ def check_pulse_secure_log_util(_no_item, _no_params, parsed): check_info["pulse_secure_log_util"] = LegacyCheckDefinition( + name="pulse_secure_log_util", detect=pulse_secure.DETECT_PULSE_SECURE, fetch=SNMPTree( base=".1.3.6.1.4.1.12532", diff --git a/cmk/base/legacy_checks/pulse_secure_mem_util.py b/cmk/base/legacy_checks/pulse_secure_mem_util.py index 274bd5d6b28..b395190d93a 100644 --- a/cmk/base/legacy_checks/pulse_secure_mem_util.py +++ b/cmk/base/legacy_checks/pulse_secure_mem_util.py @@ -44,6 +44,7 @@ def check_pulse_secure_mem(item, params, parsed): check_info["pulse_secure_mem_util"] = LegacyCheckDefinition( + name="pulse_secure_mem_util", detect=pulse_secure.DETECT_PULSE_SECURE, fetch=SNMPTree( base=".1.3.6.1.4.1.12532", diff --git a/cmk/base/legacy_checks/pulse_secure_temp.py b/cmk/base/legacy_checks/pulse_secure_temp.py index 6b6e95bbc64..c346e0a7959 100644 --- a/cmk/base/legacy_checks/pulse_secure_temp.py +++ b/cmk/base/legacy_checks/pulse_secure_temp.py @@ -31,6 +31,7 @@ def discover_pulse_secure_temp(section): check_info["pulse_secure_temp"] = LegacyCheckDefinition( + name="pulse_secure_temp", detect=pulse_secure.DETECT_PULSE_SECURE, fetch=SNMPTree( base=".1.3.6.1.4.1.12532", diff --git a/cmk/base/legacy_checks/pvecm_nodes.py b/cmk/base/legacy_checks/pvecm_nodes.py index 11e5cbd719b..98b13cfcb85 100644 --- a/cmk/base/legacy_checks/pvecm_nodes.py +++ b/cmk/base/legacy_checks/pvecm_nodes.py @@ -115,6 +115,7 @@ def check_pvecm_nodes(item, _no_params, parsed): check_info["pvecm_nodes"] = LegacyCheckDefinition( + name="pvecm_nodes", parse_function=parse_pvecm_nodes, service_name="PVE Node %s", discovery_function=inventory_pvecm_nodes, diff --git a/cmk/base/legacy_checks/pvecm_status.py b/cmk/base/legacy_checks/pvecm_status.py index dd80ec6ca0c..c5162391930 100644 --- a/cmk/base/legacy_checks/pvecm_status.py +++ b/cmk/base/legacy_checks/pvecm_status.py @@ -100,6 +100,7 @@ def check_pvecm_status(_no_item, _no_params, parsed): check_info["pvecm_status"] = LegacyCheckDefinition( + name="pvecm_status", parse_function=parse_pvecm_status, service_name="PVE Cluster State", discovery_function=inventory_pvecm_status, diff --git a/cmk/base/legacy_checks/qlogic_fcport.py b/cmk/base/legacy_checks/qlogic_fcport.py index 288dc9abffc..9807291fe55 100644 --- a/cmk/base/legacy_checks/qlogic_fcport.py +++ b/cmk/base/legacy_checks/qlogic_fcport.py @@ -255,6 +255,7 @@ def parse_qlogic_fcport(string_table: StringTable) -> StringTable: check_info["qlogic_fcport"] = LegacyCheckDefinition( + name="qlogic_fcport", parse_function=parse_qlogic_fcport, detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1663.1.1"), diff --git a/cmk/base/legacy_checks/qlogic_sanbox.py b/cmk/base/legacy_checks/qlogic_sanbox.py index 46c37c4abe0..d95d50d980b 100644 --- a/cmk/base/legacy_checks/qlogic_sanbox.py +++ b/cmk/base/legacy_checks/qlogic_sanbox.py @@ -24,6 +24,7 @@ def parse_qlogic_sanbox(string_table: StringTable) -> StringTable: check_info["qlogic_sanbox"] = LegacyCheckDefinition( + name="qlogic_sanbox", parse_function=parse_qlogic_sanbox, detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3873.1.14"), @@ -106,6 +107,7 @@ def check_qlogic_sanbox_temp(item, _no_params, info): check_info["qlogic_sanbox.temp"] = LegacyCheckDefinition( + name="qlogic_sanbox_temp", service_name="Temperature Sensor %s", sections=["qlogic_sanbox"], discovery_function=inventory_qlogic_sanbox_temp, @@ -171,6 +173,7 @@ def check_qlogic_sanbox_psu(item, _no_params, info): check_info["qlogic_sanbox.psu"] = LegacyCheckDefinition( + name="qlogic_sanbox_psu", service_name="PSU %s", sections=["qlogic_sanbox"], discovery_function=inventory_qlogic_sanbox_psu, diff --git a/cmk/base/legacy_checks/qlogic_sanbox_fabric_element.py b/cmk/base/legacy_checks/qlogic_sanbox_fabric_element.py index e3a70751eea..c508ef15ad2 100644 --- a/cmk/base/legacy_checks/qlogic_sanbox_fabric_element.py +++ b/cmk/base/legacy_checks/qlogic_sanbox_fabric_element.py @@ -38,6 +38,7 @@ def parse_qlogic_sanbox_fabric_element(string_table: StringTable) -> StringTable check_info["qlogic_sanbox_fabric_element"] = LegacyCheckDefinition( + name="qlogic_sanbox_fabric_element", parse_function=parse_qlogic_sanbox_fabric_element, detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.3873.1.14"), diff --git a/cmk/base/legacy_checks/qmail_stats.py b/cmk/base/legacy_checks/qmail_stats.py index bab56b8cdb7..cc30f2b7f30 100644 --- a/cmk/base/legacy_checks/qmail_stats.py +++ b/cmk/base/legacy_checks/qmail_stats.py @@ -54,6 +54,7 @@ def parse_qmail_stats(string_table: StringTable) -> StringTable: check_info["qmail_stats"] = LegacyCheckDefinition( + name="qmail_stats", parse_function=parse_qmail_stats, service_name="Qmail Queue", discovery_function=discover_qmail_stats, diff --git a/cmk/base/legacy_checks/qnap_disks.py b/cmk/base/legacy_checks/qnap_disks.py index 3f8d7a37854..9959476bf7a 100644 --- a/cmk/base/legacy_checks/qnap_disks.py +++ b/cmk/base/legacy_checks/qnap_disks.py @@ -42,6 +42,7 @@ def parse_qnap_disks(string_table: StringTable) -> StringTable: check_info["qnap_disks"] = LegacyCheckDefinition( + name="qnap_disks", parse_function=parse_qnap_disks, detect=DETECT_QNAP, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/qnap_fans.py b/cmk/base/legacy_checks/qnap_fans.py index db96c514ff0..a9a972154a8 100644 --- a/cmk/base/legacy_checks/qnap_fans.py +++ b/cmk/base/legacy_checks/qnap_fans.py @@ -33,6 +33,7 @@ def discover_qnap_fans(section): check_info["qnap_fans"] = LegacyCheckDefinition( + name="qnap_fans", detect=DETECT_QNAP, fetch=SNMPTree( base=".1.3.6.1.4.1.24681.1.2.15.1", diff --git a/cmk/base/legacy_checks/qnap_hdd_temp.py b/cmk/base/legacy_checks/qnap_hdd_temp.py index 051daec3692..cb29f36cfa3 100644 --- a/cmk/base/legacy_checks/qnap_hdd_temp.py +++ b/cmk/base/legacy_checks/qnap_hdd_temp.py @@ -34,6 +34,7 @@ def discover_qnap_hdd_temp(section): check_info["qnap_hdd_temp"] = LegacyCheckDefinition( + name="qnap_hdd_temp", detect=DETECT_QNAP, fetch=SNMPTree( base=".1.3.6.1.4.1.24681.1.2.11.1", diff --git a/cmk/base/legacy_checks/quanta_fan.py b/cmk/base/legacy_checks/quanta_fan.py index d3bde7c3290..dbb4eb4f27b 100644 --- a/cmk/base/legacy_checks/quanta_fan.py +++ b/cmk/base/legacy_checks/quanta_fan.py @@ -58,6 +58,7 @@ def discover_quanta_fan(section): check_info["quanta_fan"] = LegacyCheckDefinition( + name="quanta_fan", detect=DETECT_QUANTA, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/quanta_temperature.py b/cmk/base/legacy_checks/quanta_temperature.py index aa20f3864fc..cca5998ad71 100644 --- a/cmk/base/legacy_checks/quanta_temperature.py +++ b/cmk/base/legacy_checks/quanta_temperature.py @@ -60,6 +60,7 @@ def discover_quanta_temperature(section): check_info["quanta_temperature"] = LegacyCheckDefinition( + name="quanta_temperature", detect=DETECT_QUANTA, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/quanta_voltage.py b/cmk/base/legacy_checks/quanta_voltage.py index 9d734be3d81..b865445a048 100644 --- a/cmk/base/legacy_checks/quanta_voltage.py +++ b/cmk/base/legacy_checks/quanta_voltage.py @@ -57,6 +57,7 @@ def discover_quanta_voltage(section): check_info["quanta_voltage"] = LegacyCheckDefinition( + name="quanta_voltage", detect=DETECT_QUANTA, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/ra32e_power.py b/cmk/base/legacy_checks/ra32e_power.py index 502b5c802e5..649c90bff2b 100644 --- a/cmk/base/legacy_checks/ra32e_power.py +++ b/cmk/base/legacy_checks/ra32e_power.py @@ -31,6 +31,7 @@ def parse_ra32e_power(string_table: StringTable) -> StringTable: check_info["ra32e_power"] = LegacyCheckDefinition( + name="ra32e_power", parse_function=parse_ra32e_power, detect=DETECT_RA32E, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ra32e_sensors.py b/cmk/base/legacy_checks/ra32e_sensors.py index 9901596f2f7..12a53e786f7 100644 --- a/cmk/base/legacy_checks/ra32e_sensors.py +++ b/cmk/base/legacy_checks/ra32e_sensors.py @@ -118,6 +118,7 @@ def discover_ra32e_sensors(x): check_info["ra32e_sensors"] = LegacyCheckDefinition( + name="ra32e_sensors", detect=DETECT_RA32E, fetch=[ SNMPTree( @@ -183,6 +184,7 @@ def discover_ra32e_sensors_humidity(x): check_info["ra32e_sensors.humidity"] = LegacyCheckDefinition( + name="ra32e_sensors_humidity", service_name="Humidity %s", sections=["ra32e_sensors"], discovery_function=discover_ra32e_sensors_humidity, @@ -213,6 +215,7 @@ def discover_ra32e_sensors_voltage(x): check_info["ra32e_sensors.voltage"] = LegacyCheckDefinition( + name="ra32e_sensors_voltage", service_name="Voltage %s", sections=["ra32e_sensors"], discovery_function=discover_ra32e_sensors_voltage, @@ -243,6 +246,7 @@ def discover_ra32e_sensors_power(x): check_info["ra32e_sensors.power"] = LegacyCheckDefinition( + name="ra32e_sensors_power", service_name="Power State %s", sections=["ra32e_sensors"], discovery_function=discover_ra32e_sensors_power, diff --git a/cmk/base/legacy_checks/ra32e_switch.py b/cmk/base/legacy_checks/ra32e_switch.py index 0ed854f9595..87be4ea0680 100644 --- a/cmk/base/legacy_checks/ra32e_switch.py +++ b/cmk/base/legacy_checks/ra32e_switch.py @@ -35,6 +35,7 @@ def parse_ra32e_switch(string_table: StringTable) -> StringTable | None: check_info["ra32e_switch"] = LegacyCheckDefinition( + name="ra32e_switch", parse_function=parse_ra32e_switch, detect=DETECT_RA32E, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/rabbitmq_cluster.py b/cmk/base/legacy_checks/rabbitmq_cluster.py index 93670cd2c08..7590a4a064a 100644 --- a/cmk/base/legacy_checks/rabbitmq_cluster.py +++ b/cmk/base/legacy_checks/rabbitmq_cluster.py @@ -123,6 +123,7 @@ def check_rabbitmq_cluster(_no_item, params, parsed): check_info["rabbitmq_cluster"] = LegacyCheckDefinition( + name="rabbitmq_cluster", parse_function=parse_rabbitmq_cluster, service_name="RabbitMQ Cluster", discovery_function=inventory_rabbitmq_cluster, @@ -159,6 +160,7 @@ def check_rabbitmq_cluster_messages(_no_item, params, parsed): check_info["rabbitmq_cluster.messages"] = LegacyCheckDefinition( + name="rabbitmq_cluster_messages", service_name="RabbitMQ Cluster Messages", sections=["rabbitmq_cluster"], discovery_function=inventory_rabbitmq_cluster_messages, @@ -210,6 +212,7 @@ def _handle_output(params, value, key, infotext, hr_func): check_info["rabbitmq_cluster.stats"] = LegacyCheckDefinition( + name="rabbitmq_cluster_stats", service_name="RabbitMQ Cluster Stats", sections=["rabbitmq_cluster"], discovery_function=inventory_rabbitmq_cluster_stats, diff --git a/cmk/base/legacy_checks/rabbitmq_nodes.py b/cmk/base/legacy_checks/rabbitmq_nodes.py index a7523fc2b56..9df406d5f40 100644 --- a/cmk/base/legacy_checks/rabbitmq_nodes.py +++ b/cmk/base/legacy_checks/rabbitmq_nodes.py @@ -150,6 +150,7 @@ def check_rabbitmq_nodes(item, params, parsed): check_info["rabbitmq_nodes"] = LegacyCheckDefinition( + name="rabbitmq_nodes", parse_function=parse_rabbitmq_nodes, service_name="RabbitMQ Node %s", discovery_function=discover_rabbitmq_nodes, @@ -206,6 +207,7 @@ def check_rabbitmq_nodes_filedesc(item, params, parsed): check_info["rabbitmq_nodes.filedesc"] = LegacyCheckDefinition( + name="rabbitmq_nodes_filedesc", service_name="RabbitMQ Node %s Filedesc", sections=["rabbitmq_nodes"], discovery_function=discover_key("fd"), @@ -231,6 +233,7 @@ def check_rabbitmq_nodes_sockets(item, params, parsed): check_info["rabbitmq_nodes.sockets"] = LegacyCheckDefinition( + name="rabbitmq_nodes_sockets", service_name="RabbitMQ Node %s Sockets", sections=["rabbitmq_nodes"], discovery_function=discover_key("sockets"), @@ -266,6 +269,7 @@ def check_rabbitmq_nodes_mem(item, params, parsed): check_info["rabbitmq_nodes.mem"] = LegacyCheckDefinition( + name="rabbitmq_nodes_mem", service_name="RabbitMQ Node %s Memory", sections=["rabbitmq_nodes"], discovery_function=discover_key("mem"), @@ -332,6 +336,7 @@ def check_rabbitmq_nodes_uptime(item, params, parsed): check_info["rabbitmq_nodes.uptime"] = LegacyCheckDefinition( + name="rabbitmq_nodes_uptime", service_name="RabbitMQ Node %s Uptime", sections=["rabbitmq_nodes"], discovery_function=discover_key("uptime"), @@ -384,6 +389,7 @@ def _handle_output(params, value, total, info_text, perf_key): check_info["rabbitmq_nodes.gc"] = LegacyCheckDefinition( + name="rabbitmq_nodes_gc", service_name="RabbitMQ Node %s GC", sections=["rabbitmq_nodes"], discovery_function=discover_key("gc"), diff --git a/cmk/base/legacy_checks/rabbitmq_queues.py b/cmk/base/legacy_checks/rabbitmq_queues.py index 81384427855..74b63ac1ab5 100644 --- a/cmk/base/legacy_checks/rabbitmq_queues.py +++ b/cmk/base/legacy_checks/rabbitmq_queues.py @@ -117,6 +117,7 @@ def discover_rabbitmq_queues(section): check_info["rabbitmq_queues"] = LegacyCheckDefinition( + name="rabbitmq_queues", parse_function=parse_rabbitmq_queues, service_name="RabbitMQ Queue %s", discovery_function=discover_rabbitmq_queues, diff --git a/cmk/base/legacy_checks/rabbitmq_vhosts.py b/cmk/base/legacy_checks/rabbitmq_vhosts.py index 4c6de7ee3bf..c976739b9a3 100644 --- a/cmk/base/legacy_checks/rabbitmq_vhosts.py +++ b/cmk/base/legacy_checks/rabbitmq_vhosts.py @@ -103,6 +103,7 @@ def discover_rabbitmq_vhosts(section): check_info["rabbitmq_vhosts"] = LegacyCheckDefinition( + name="rabbitmq_vhosts", parse_function=parse_rabbitmq_vhosts, service_name="RabbitMQ Vhost %s", discovery_function=discover_rabbitmq_vhosts, diff --git a/cmk/base/legacy_checks/raritan_emx.py b/cmk/base/legacy_checks/raritan_emx.py index b552699c81e..a5fbead1932 100644 --- a/cmk/base/legacy_checks/raritan_emx.py +++ b/cmk/base/legacy_checks/raritan_emx.py @@ -102,6 +102,7 @@ def check_raritan_emx_temp(item, params, parsed): check_info["raritan_emx"] = LegacyCheckDefinition( + name="raritan_emx", detect=any_of(equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.8")), fetch=SNMPTree( base=".1.3.6.1.4.1.13742.9", @@ -139,6 +140,7 @@ def discover_raritan_emx_fan(parsed): check_info["raritan_emx.fan"] = LegacyCheckDefinition( + name="raritan_emx_fan", service_name="Fan %s", sections=["raritan_emx"], discovery_function=discover_raritan_emx_fan, @@ -161,6 +163,7 @@ def discover_raritan_emx_binary(parsed): # '----------------------------------------------------------------------' check_info["raritan_emx.binary"] = LegacyCheckDefinition( + name="raritan_emx_binary", service_name="Door %s", sections=["raritan_emx"], discovery_function=discover_raritan_emx_binary, diff --git a/cmk/base/legacy_checks/raritan_emx_sensors.py b/cmk/base/legacy_checks/raritan_emx_sensors.py index 9e36aa474fb..713b1d90186 100644 --- a/cmk/base/legacy_checks/raritan_emx_sensors.py +++ b/cmk/base/legacy_checks/raritan_emx_sensors.py @@ -35,6 +35,7 @@ def discover_raritan_emx_sensors(parsed): check_info["raritan_emx_sensors"] = LegacyCheckDefinition( + name="raritan_emx_sensors", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.8"), fetch=SNMPTree( base=".1.3.6.1.4.1.13742.8", @@ -75,6 +76,7 @@ def discover_raritan_emx_sensors_temp(parsed): # +----------------------------------------------------------------------+ check_info["raritan_emx_sensors.temp"] = LegacyCheckDefinition( + name="raritan_emx_sensors_temp", service_name="Temperature %s", sections=["raritan_emx_sensors"], discovery_function=discover_raritan_emx_sensors_temp, @@ -98,6 +100,7 @@ def discover_raritan_emx_sensors_airflow(parsed): # +----------------------------------------------------------------------+ check_info["raritan_emx_sensors.airflow"] = LegacyCheckDefinition( + name="raritan_emx_sensors_airflow", service_name="Air flow %s", sections=["raritan_emx_sensors"], discovery_function=discover_raritan_emx_sensors_airflow, @@ -120,6 +123,7 @@ def discover_raritan_emx_sensors_humidity(parsed): # +----------------------------------------------------------------------+ check_info["raritan_emx_sensors.humidity"] = LegacyCheckDefinition( + name="raritan_emx_sensors_humidity", service_name="Humidity %s", sections=["raritan_emx_sensors"], discovery_function=discover_raritan_emx_sensors_humidity, @@ -142,6 +146,7 @@ def discover_raritan_emx_sensors_pressure(parsed): # +----------------------------------------------------------------------+ check_info["raritan_emx_sensors.pressure"] = LegacyCheckDefinition( + name="raritan_emx_sensors_pressure", service_name="Pressure %s", sections=["raritan_emx_sensors"], discovery_function=discover_raritan_emx_sensors_pressure, diff --git a/cmk/base/legacy_checks/raritan_pdu_inlet.py b/cmk/base/legacy_checks/raritan_pdu_inlet.py index 78e0b4d69c1..1b2c506d7ba 100644 --- a/cmk/base/legacy_checks/raritan_pdu_inlet.py +++ b/cmk/base/legacy_checks/raritan_pdu_inlet.py @@ -43,6 +43,7 @@ def discover_raritan_pdu_inlet(section): check_info["raritan_pdu_inlet"] = LegacyCheckDefinition( + name="raritan_pdu_inlet", detect=DETECT_RARITAN, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/raritan_pdu_inlet_summary.py b/cmk/base/legacy_checks/raritan_pdu_inlet_summary.py index 05f4af51722..823be0b3c1e 100644 --- a/cmk/base/legacy_checks/raritan_pdu_inlet_summary.py +++ b/cmk/base/legacy_checks/raritan_pdu_inlet_summary.py @@ -34,6 +34,7 @@ def discover_raritan_pdu_inlet_summary(section): check_info["raritan_pdu_inlet_summary"] = LegacyCheckDefinition( + name="raritan_pdu_inlet_summary", detect=DETECT_RARITAN, fetch=SNMPTree( base=".1.3.6.1.4.1.13742.6", diff --git a/cmk/base/legacy_checks/raritan_pdu_ocprot.py b/cmk/base/legacy_checks/raritan_pdu_ocprot.py index d12bbca4819..0d11c31cd70 100644 --- a/cmk/base/legacy_checks/raritan_pdu_ocprot.py +++ b/cmk/base/legacy_checks/raritan_pdu_ocprot.py @@ -78,6 +78,7 @@ def check_raritan_pdu_ocprot(item, params, parsed): check_info["raritan_pdu_ocprot"] = LegacyCheckDefinition( + name="raritan_pdu_ocprot", detect=contains(".1.3.6.1.2.1.1.2.0", "13742"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/raritan_pdu_outletcount.py b/cmk/base/legacy_checks/raritan_pdu_outletcount.py index 50ea59327f0..f5efb57f238 100644 --- a/cmk/base/legacy_checks/raritan_pdu_outletcount.py +++ b/cmk/base/legacy_checks/raritan_pdu_outletcount.py @@ -30,6 +30,7 @@ def parse_raritan_pdu_outletcount(string_table: StringTable) -> StringTable: check_info["raritan_pdu_outletcount"] = LegacyCheckDefinition( + name="raritan_pdu_outletcount", parse_function=parse_raritan_pdu_outletcount, detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.6"), diff --git a/cmk/base/legacy_checks/raritan_pdu_plugs.py b/cmk/base/legacy_checks/raritan_pdu_plugs.py index 157da5bebca..b5f7fce5019 100644 --- a/cmk/base/legacy_checks/raritan_pdu_plugs.py +++ b/cmk/base/legacy_checks/raritan_pdu_plugs.py @@ -5,7 +5,7 @@ from cmk.base.check_api import LegacyCheckDefinition -from cmk.base.check_legacy_includes.raritan import raritan_map_state +from cmk.base.check_legacy_includes.raritan import raritan_pdu_plug_state from cmk.base.config import check_info from cmk.agent_based.v2 import all_of, any_of, SNMPTree, startswith @@ -15,33 +15,35 @@ def parse_raritan_pdu_plugs(string_table): parsed = {} for outlet_label, outlet_name, outlet_state in string_table: - parsed[outlet_label] = { - "state": raritan_map_state.get(outlet_state, (3, "unknown")), - "outlet_name": outlet_name, - } + state = raritan_pdu_plug_state.get(outlet_state, "unknown") + parsed[outlet_label] = {"state": state, "outlet_name": outlet_name} + return parsed def inventory_raritan_pdu_plugs(parsed): for key, value in parsed.items(): - yield key, {"discovered_state": value["state"][1]} + yield key, {"discovered_state": value["state"]} def check_raritan_pdu_plugs(item, params, parsed): if not (data := parsed.get(item)): return - if data.get("outlet_name"): - yield 0, data["outlet_name"] - state, state_info = data["state"] - yield state, "Status: %s" % state_info + if outlet_name := data.get("outlet_name"): + yield 0, outlet_name + + state = data["state"] + expected_state = params["required_state"] or params["discovered_state"] - required_state = params.get("required_state", params["discovered_state"]) - if state_info != required_state: - yield 2, "Expected: %s" % required_state + if state != expected_state: + yield (2, "Status: %s (expected: %s)" % (state, expected_state)) + else: + yield 0, "Status: %s" % state check_info["raritan_pdu_plugs"] = LegacyCheckDefinition( + name="raritan_pdu_plugs", detect=all_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.6"), any_of( @@ -58,4 +60,5 @@ def check_raritan_pdu_plugs(item, params, parsed): discovery_function=inventory_raritan_pdu_plugs, check_function=check_raritan_pdu_plugs, check_ruleset_name="plugs", + check_default_parameters={"required_state": None}, ) diff --git a/cmk/base/legacy_checks/raritan_px2_sensors.py b/cmk/base/legacy_checks/raritan_px2_sensors.py index 23f0fbfec10..32bb2e1b986 100644 --- a/cmk/base/legacy_checks/raritan_px2_sensors.py +++ b/cmk/base/legacy_checks/raritan_px2_sensors.py @@ -34,6 +34,7 @@ def discover_raritan_px2_sensors(parsed): check_info["raritan_px2_sensors"] = LegacyCheckDefinition( + name="raritan_px2_sensors", detect=DETECT_RARITAN, fetch=SNMPTree( base=".1.3.6.1.4.1.13742.6", @@ -75,6 +76,7 @@ def discover_raritan_px2_sensors_airflow(parsed): # +----------------------------------------------------------------------+ check_info["raritan_px2_sensors.airflow"] = LegacyCheckDefinition( + name="raritan_px2_sensors_airflow", service_name="Air flow %s", sections=["raritan_px2_sensors"], discovery_function=discover_raritan_px2_sensors_airflow, @@ -97,6 +99,7 @@ def discover_raritan_px2_sensors_humidity(parsed): # +----------------------------------------------------------------------+ check_info["raritan_px2_sensors.humidity"] = LegacyCheckDefinition( + name="raritan_px2_sensors_humidity", service_name="Humidity %s", sections=["raritan_px2_sensors"], discovery_function=discover_raritan_px2_sensors_humidity, @@ -119,6 +122,7 @@ def discover_raritan_px2_sensors_pressure(parsed): # +----------------------------------------------------------------------+ check_info["raritan_px2_sensors.pressure"] = LegacyCheckDefinition( + name="raritan_px2_sensors_pressure", service_name="Pressure %s", sections=["raritan_px2_sensors"], discovery_function=discover_raritan_px2_sensors_pressure, diff --git a/cmk/base/legacy_checks/raritan_px_outlets.py b/cmk/base/legacy_checks/raritan_px_outlets.py index 54a3a329829..8b16c0ca595 100644 --- a/cmk/base/legacy_checks/raritan_px_outlets.py +++ b/cmk/base/legacy_checks/raritan_px_outlets.py @@ -79,6 +79,7 @@ def check_raritan_px_outlets(item, params, parsed): check_info["raritan_px_outlets"] = LegacyCheckDefinition( + name="raritan_px_outlets", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.4"), fetch=SNMPTree( base=".1.3.6.1.4.1.13742.4.1.2.2.1", diff --git a/cmk/base/legacy_checks/raritan_px_sensors.py b/cmk/base/legacy_checks/raritan_px_sensors.py index 7e6c536be48..036d0b7a43a 100644 --- a/cmk/base/legacy_checks/raritan_px_sensors.py +++ b/cmk/base/legacy_checks/raritan_px_sensors.py @@ -120,6 +120,7 @@ def discover_raritan_px_sensors(parsed): # '----------------------------------------------------------------------' check_info["raritan_px_sensors"] = LegacyCheckDefinition( + name="raritan_px_sensors", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.13742.4"), fetch=SNMPTree( base=".1.3.6.1.4.1.13742.4.3.3.1", @@ -148,6 +149,7 @@ def discover_raritan_px_sensors_humidity(parsed): # '----------------------------------------------------------------------' check_info["raritan_px_sensors.humidity"] = LegacyCheckDefinition( + name="raritan_px_sensors_humidity", service_name="Humidity %s", sections=["raritan_px_sensors"], discovery_function=discover_raritan_px_sensors_humidity, @@ -170,6 +172,7 @@ def discover_raritan_px_sensors_binary(parsed): # '----------------------------------------------------------------------' check_info["raritan_px_sensors.binary"] = LegacyCheckDefinition( + name="raritan_px_sensors_binary", service_name="Contact %s", sections=["raritan_px_sensors"], discovery_function=discover_raritan_px_sensors_binary, diff --git a/cmk/base/legacy_checks/rds_licenses.py b/cmk/base/legacy_checks/rds_licenses.py index 6be0d705277..82f994c895d 100644 --- a/cmk/base/legacy_checks/rds_licenses.py +++ b/cmk/base/legacy_checks/rds_licenses.py @@ -72,6 +72,7 @@ def discover_rds_licenses(section): check_info["rds_licenses"] = LegacyCheckDefinition( + name="rds_licenses", parse_function=parse_rds_licenses, service_name="RDS Licenses %s", discovery_function=discover_rds_licenses, diff --git a/cmk/base/legacy_checks/rms200_temp.py b/cmk/base/legacy_checks/rms200_temp.py index 6e4aff2955d..58e233fe900 100644 --- a/cmk/base/legacy_checks/rms200_temp.py +++ b/cmk/base/legacy_checks/rms200_temp.py @@ -34,6 +34,7 @@ def parse_rms200_temp(string_table: StringTable) -> StringTable: check_info["rms200_temp"] = LegacyCheckDefinition( + name="rms200_temp", parse_function=parse_rms200_temp, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1909.13"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/rstcli.py b/cmk/base/legacy_checks/rstcli.py index 52b5e23e4b8..aa3382faee7 100644 --- a/cmk/base/legacy_checks/rstcli.py +++ b/cmk/base/legacy_checks/rstcli.py @@ -146,6 +146,7 @@ def check_rstcli(item, _no_params, parsed): check_info["rstcli"] = LegacyCheckDefinition( + name="rstcli", parse_function=parse_rstcli, service_name="RAID Volume %s", discovery_function=inventory_rstcli, @@ -178,6 +179,7 @@ def check_rstcli_pdisks(item, _no_params, parsed): check_info["rstcli.pdisks"] = LegacyCheckDefinition( + name="rstcli_pdisks", service_name="RAID Disk %s", sections=["rstcli"], discovery_function=inventory_rstcli_pdisks, diff --git a/cmk/base/legacy_checks/safenet_hsm.py b/cmk/base/legacy_checks/safenet_hsm.py index 5ca8498be9a..429ef49eb32 100644 --- a/cmk/base/legacy_checks/safenet_hsm.py +++ b/cmk/base/legacy_checks/safenet_hsm.py @@ -95,6 +95,7 @@ def check_event_rate(event_type): check_info["safenet_hsm.events"] = LegacyCheckDefinition( + name="safenet_hsm_events", service_name="HSM Safenet Event Stats", sections=["safenet_hsm"], discovery_function=inventory_safenet_hsm_events, @@ -187,6 +188,7 @@ def check_operation_errors(operation_errors): check_info["safenet_hsm"] = LegacyCheckDefinition( + name="safenet_hsm", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12383"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072"), diff --git a/cmk/base/legacy_checks/safenet_ntls.py b/cmk/base/legacy_checks/safenet_ntls.py index 250ae471eba..59791375a1d 100644 --- a/cmk/base/legacy_checks/safenet_ntls.py +++ b/cmk/base/legacy_checks/safenet_ntls.py @@ -60,6 +60,7 @@ def check_safenet_ntls_connrate(item, _no_params, parsed): check_info["safenet_ntls.connrate"] = LegacyCheckDefinition( + name="safenet_ntls_connrate", service_name="NTLS Connection Rate: %s", sections=["safenet_ntls"], discovery_function=inventory_safenet_ntls_connrate, @@ -94,6 +95,7 @@ def check_safenet_ntls_expiration(_no_item, _no_params, parsed): check_info["safenet_ntls.expiration"] = LegacyCheckDefinition( + name="safenet_ntls_expiration", service_name="NTLS Expiration Date", sections=["safenet_ntls"], discovery_function=inventory_safenet_ntls_expiration, @@ -124,6 +126,7 @@ def check_safenet_ntls_links(_no_item, params, parsed): check_info["safenet_ntls.links"] = LegacyCheckDefinition( + name="safenet_ntls_links", service_name="NTLS Links", sections=["safenet_ntls"], discovery_function=inventory_safenet_ntls_links, @@ -166,6 +169,7 @@ def check_safenet_ntls_clients(_no_item, params, parsed): check_info["safenet_ntls.clients"] = LegacyCheckDefinition( + name="safenet_ntls_clients", service_name="NTLS Clients", sections=["safenet_ntls"], discovery_function=inventory_safenet_ntls_clients, @@ -209,6 +213,7 @@ def check_safenet_ntls(_no_item, _no_params, parsed): check_info["safenet_ntls"] = LegacyCheckDefinition( + name="safenet_ntls", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12383"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072"), diff --git a/cmk/base/legacy_checks/salesforce_instances.py b/cmk/base/legacy_checks/salesforce_instances.py index ba8baab76d2..62ce27e48c1 100644 --- a/cmk/base/legacy_checks/salesforce_instances.py +++ b/cmk/base/legacy_checks/salesforce_instances.py @@ -59,6 +59,7 @@ def check_salesforce_instances(item, params, parsed): check_info["salesforce_instances"] = LegacyCheckDefinition( + name="salesforce_instances", parse_function=parse_salesforce, service_name="Salesforce Instance %s", discovery_function=inventory_salesforce_instances, diff --git a/cmk/base/legacy_checks/sansymphony_alerts.py b/cmk/base/legacy_checks/sansymphony_alerts.py index 8ff387bb646..f14999e3672 100644 --- a/cmk/base/legacy_checks/sansymphony_alerts.py +++ b/cmk/base/legacy_checks/sansymphony_alerts.py @@ -30,6 +30,7 @@ def parse_sansymphony_alerts(string_table: StringTable) -> StringTable: check_info["sansymphony_alerts"] = LegacyCheckDefinition( + name="sansymphony_alerts", parse_function=parse_sansymphony_alerts, service_name="sansymphony Alerts", discovery_function=inventory_sansymphony_alerts, diff --git a/cmk/base/legacy_checks/sansymphony_ports.py b/cmk/base/legacy_checks/sansymphony_ports.py index 00955a57cd8..e529cc6aa96 100644 --- a/cmk/base/legacy_checks/sansymphony_ports.py +++ b/cmk/base/legacy_checks/sansymphony_ports.py @@ -38,6 +38,7 @@ def parse_sansymphony_ports(string_table: StringTable) -> StringTable: check_info["sansymphony_ports"] = LegacyCheckDefinition( + name="sansymphony_ports", parse_function=parse_sansymphony_ports, service_name="sansymphony Port %s", discovery_function=inventory_sansymphony_ports, diff --git a/cmk/base/legacy_checks/sansymphony_serverstatus.py b/cmk/base/legacy_checks/sansymphony_serverstatus.py index e9e8a6e3001..789ac7cd016 100644 --- a/cmk/base/legacy_checks/sansymphony_serverstatus.py +++ b/cmk/base/legacy_checks/sansymphony_serverstatus.py @@ -35,6 +35,7 @@ def parse_sansymphony_serverstatus(string_table: StringTable) -> StringTable: check_info["sansymphony_serverstatus"] = LegacyCheckDefinition( + name="sansymphony_serverstatus", parse_function=parse_sansymphony_serverstatus, service_name="sansymphony Serverstatus", discovery_function=inventory_sansymphony_serverstatus, diff --git a/cmk/base/legacy_checks/sansymphony_virtualdiskstatus.py b/cmk/base/legacy_checks/sansymphony_virtualdiskstatus.py index 7ce744d78bf..706224606f2 100644 --- a/cmk/base/legacy_checks/sansymphony_virtualdiskstatus.py +++ b/cmk/base/legacy_checks/sansymphony_virtualdiskstatus.py @@ -33,6 +33,7 @@ def discover_sansymphony_virtualdiskstatus(section): check_info["sansymphony_virtualdiskstatus"] = LegacyCheckDefinition( + name="sansymphony_virtualdiskstatus", parse_function=parse_sansymphony_virtualdiskstatus, service_name="sansymphony Virtual Disk %s", discovery_function=discover_sansymphony_virtualdiskstatus, diff --git a/cmk/base/legacy_checks/sap_hana_connect.py b/cmk/base/legacy_checks/sap_hana_connect.py index 0c89108de56..01a755f857f 100644 --- a/cmk/base/legacy_checks/sap_hana_connect.py +++ b/cmk/base/legacy_checks/sap_hana_connect.py @@ -71,6 +71,7 @@ def discover_sap_hana_connect(section): check_info["sap_hana_connect"] = LegacyCheckDefinition( + name="sap_hana_connect", parse_function=parse_sap_hana_connect, service_name="SAP HANA CONNECT %s", discovery_function=discover_sap_hana_connect, diff --git a/cmk/base/legacy_checks/sap_hana_ess_migration.py b/cmk/base/legacy_checks/sap_hana_ess_migration.py index 62839c8d159..c64459d7499 100644 --- a/cmk/base/legacy_checks/sap_hana_ess_migration.py +++ b/cmk/base/legacy_checks/sap_hana_ess_migration.py @@ -68,6 +68,7 @@ def check_sap_hana_ess_migration(item, params, parsed): check_info["sap_hana_ess_migration"] = LegacyCheckDefinition( + name="sap_hana_ess_migration", parse_function=parse_sap_hana_ess_migration, service_name="SAP HANA ESS Migration %s", discovery_function=inventory_sap_hana_ess_migration, diff --git a/cmk/base/legacy_checks/sap_state.py b/cmk/base/legacy_checks/sap_state.py index e62edb79601..a419682989a 100644 --- a/cmk/base/legacy_checks/sap_state.py +++ b/cmk/base/legacy_checks/sap_state.py @@ -33,6 +33,7 @@ def parse_sap_state(string_table: StringTable) -> StringTable: check_info["sap_state"] = LegacyCheckDefinition( + name="sap_state", parse_function=parse_sap_state, service_name="SAP State %s", discovery_function=inventory_sap_state, diff --git a/cmk/base/legacy_checks/saprouter_cert.py b/cmk/base/legacy_checks/saprouter_cert.py index bf45860a66a..e032e482d7b 100644 --- a/cmk/base/legacy_checks/saprouter_cert.py +++ b/cmk/base/legacy_checks/saprouter_cert.py @@ -105,6 +105,7 @@ def check_saprouter_cert(_no_item, params, parsed): check_info["saprouter_cert"] = LegacyCheckDefinition( + name="saprouter_cert", parse_function=parse_saprouter_cert, service_name="SAP router certificate", discovery_function=inventory_saprouter_cert, diff --git a/cmk/base/legacy_checks/scaleio_devices.py b/cmk/base/legacy_checks/scaleio_devices.py index fa8213f33f0..c17bf703e43 100644 --- a/cmk/base/legacy_checks/scaleio_devices.py +++ b/cmk/base/legacy_checks/scaleio_devices.py @@ -81,6 +81,7 @@ def discover_scaleio_devices(section): check_info["scaleio_devices"] = LegacyCheckDefinition( + name="scaleio_devices", parse_function=parse_scaleio_devices, service_name="ScaleIO Data Server %s Devices", discovery_function=discover_scaleio_devices, diff --git a/cmk/base/legacy_checks/scaleio_mdm.py b/cmk/base/legacy_checks/scaleio_mdm.py index 45722f81cf6..1f4a913d399 100644 --- a/cmk/base/legacy_checks/scaleio_mdm.py +++ b/cmk/base/legacy_checks/scaleio_mdm.py @@ -131,6 +131,7 @@ def check_scaleio_mdm(_no_item, _no_params, parsed): check_info["scaleio_mdm"] = LegacyCheckDefinition( + name="scaleio_mdm", parse_function=parse_scaleio_mdm, service_name="ScaleIO cluster status", discovery_function=inventory_scaleio_mdm, diff --git a/cmk/base/legacy_checks/scaleio_pd.py b/cmk/base/legacy_checks/scaleio_pd.py index d38f8f849d5..d5462f3d28b 100644 --- a/cmk/base/legacy_checks/scaleio_pd.py +++ b/cmk/base/legacy_checks/scaleio_pd.py @@ -44,6 +44,7 @@ def check_scaleio_pd(item, params, parsed): check_info["scaleio_pd"] = LegacyCheckDefinition( + name="scaleio_pd", parse_function=parse_scaleio_pd, service_name="ScaleIO PD capacity %s", discovery_function=inventory_scaleio_pd, @@ -70,6 +71,7 @@ def check_scaleio_pd_status(item, _no_params, parsed): check_info["scaleio_pd.status"] = LegacyCheckDefinition( + name="scaleio_pd_status", service_name="ScaleIO PD status %s", sections=["scaleio_pd"], discovery_function=inventory_scaleio_pd_status, diff --git a/cmk/base/legacy_checks/scaleio_sds.py b/cmk/base/legacy_checks/scaleio_sds.py index 5cd3134c309..c31a0e5783a 100644 --- a/cmk/base/legacy_checks/scaleio_sds.py +++ b/cmk/base/legacy_checks/scaleio_sds.py @@ -72,6 +72,7 @@ def check_scaleio_sds(item, params, parsed): check_info["scaleio_sds"] = LegacyCheckDefinition( + name="scaleio_sds", parse_function=parse_scaleio_sds, service_name="ScaleIO SDS capacity %s", discovery_function=inventory_scaleio_sds, @@ -111,6 +112,7 @@ def check_scaleio_sds_status(item, _no_params, parsed): check_info["scaleio_sds.status"] = LegacyCheckDefinition( + name="scaleio_sds_status", service_name="ScaleIO SDS status %s", sections=["scaleio_sds"], discovery_function=inventory_scaleio_sds_status, diff --git a/cmk/base/legacy_checks/scaleio_system.py b/cmk/base/legacy_checks/scaleio_system.py index 0b399107bb0..7498413c675 100644 --- a/cmk/base/legacy_checks/scaleio_system.py +++ b/cmk/base/legacy_checks/scaleio_system.py @@ -47,6 +47,7 @@ def check_scaleio_system(item, params, parsed): check_info["scaleio_system"] = LegacyCheckDefinition( + name="scaleio_system", parse_function=parse_scaleio_system, service_name="ScaleIO System %s", discovery_function=inventory_scaleio_system, diff --git a/cmk/base/legacy_checks/security_master.py b/cmk/base/legacy_checks/security_master.py index b89dda67c70..382f824224d 100644 --- a/cmk/base/legacy_checks/security_master.py +++ b/cmk/base/legacy_checks/security_master.py @@ -173,6 +173,7 @@ def discover_security_master(parsed): check_info["security_master"] = LegacyCheckDefinition( + name="security_master", detect=startswith(".1.3.6.1.2.1.1.2.0", "1.3.6.1.4.1.35491"), fetch=[ SNMPTree( @@ -216,6 +217,7 @@ def discover_security_master_humidity(parsed): check_info["security_master.humidity"] = LegacyCheckDefinition( + name="security_master_humidity", service_name="Sensor %s", sections=["security_master"], discovery_function=discover_security_master_humidity, @@ -257,6 +259,7 @@ def discover_security_master_temp(parsed): check_info["security_master.temp"] = LegacyCheckDefinition( + name="security_master_temp", service_name="Sensor %s", sections=["security_master"], discovery_function=discover_security_master_temp, diff --git a/cmk/base/legacy_checks/seh_ports.py b/cmk/base/legacy_checks/seh_ports.py index 773efec09c2..f5168e027d9 100644 --- a/cmk/base/legacy_checks/seh_ports.py +++ b/cmk/base/legacy_checks/seh_ports.py @@ -40,6 +40,7 @@ def check_seh_ports(item, params, parsed): check_info["seh_ports"] = LegacyCheckDefinition( + name="seh_ports", detect=contains(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1229.1.1"), fetch=[ # format taken from SEH-PSRV-MIB v1.167 (2021.10.15) diff --git a/cmk/base/legacy_checks/sensatronics_temp.py b/cmk/base/legacy_checks/sensatronics_temp.py index 2251bf2062f..9ab507d3e67 100644 --- a/cmk/base/legacy_checks/sensatronics_temp.py +++ b/cmk/base/legacy_checks/sensatronics_temp.py @@ -41,6 +41,7 @@ def check_sensatronics_temp( check_info["sensatronics_temp"] = LegacyCheckDefinition( + name="sensatronics_temp", detect=any_of(equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.16174.1.1.1")), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/sentry_pdu_systempower.py b/cmk/base/legacy_checks/sentry_pdu_systempower.py index 432a73c2134..9ce4908e3dd 100644 --- a/cmk/base/legacy_checks/sentry_pdu_systempower.py +++ b/cmk/base/legacy_checks/sentry_pdu_systempower.py @@ -28,6 +28,7 @@ def discover_sentry_pdu_systempower(section): check_info["sentry_pdu_systempower"] = LegacyCheckDefinition( + name="sentry_pdu_systempower", detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1718.3"), fetch=SNMPTree( base=".1.3.6.1.4.1.1718.3.1", diff --git a/cmk/base/legacy_checks/siemens_plc.py b/cmk/base/legacy_checks/siemens_plc.py index d9cbf238ca7..cc29424b056 100644 --- a/cmk/base/legacy_checks/siemens_plc.py +++ b/cmk/base/legacy_checks/siemens_plc.py @@ -35,7 +35,9 @@ def parse_siemens_plc(string_table: StringTable) -> StringTable: return string_table -check_info["siemens_plc"] = LegacyCheckDefinition(parse_function=parse_siemens_plc) +check_info["siemens_plc"] = LegacyCheckDefinition( + name="siemens_plc", parse_function=parse_siemens_plc +) # . @@ -64,6 +66,7 @@ def check_siemens_plc_temp(item, params, info): check_info["siemens_plc.temp"] = LegacyCheckDefinition( + name="siemens_plc_temp", service_name="Temperature %s", sections=["siemens_plc"], discovery_function=inventory_siemens_plc_temp, @@ -107,6 +110,7 @@ def check_siemens_plc_flag(item, params, info): check_info["siemens_plc.flag"] = LegacyCheckDefinition( + name="siemens_plc_flag", service_name="Flag %s", sections=["siemens_plc"], discovery_function=inventory_siemens_plc_flag, @@ -172,6 +176,7 @@ def check_siemens_plc_duration(item, params, info): check_info["siemens_plc.duration"] = LegacyCheckDefinition( + name="siemens_plc_duration", service_name="Duration %s", sections=["siemens_plc"], discovery_function=inventory_siemens_plc_duration, @@ -221,6 +226,7 @@ def check_siemens_plc_counter(item, params, info): check_info["siemens_plc.counter"] = LegacyCheckDefinition( + name="siemens_plc_counter", service_name="Counter %s", sections=["siemens_plc"], discovery_function=inventory_siemens_plc_counter, @@ -253,6 +259,7 @@ def check_siemens_plc_info(item, _no_params, info): check_info["siemens_plc.info"] = LegacyCheckDefinition( + name="siemens_plc_info", service_name="Info %s", sections=["siemens_plc"], discovery_function=inventory_siemens_plc_info, @@ -294,6 +301,7 @@ def parse_siemens_plc_cpu_state(string_table: StringTable) -> StringTable: check_info["siemens_plc_cpu_state"] = LegacyCheckDefinition( + name="siemens_plc_cpu_state", parse_function=parse_siemens_plc_cpu_state, service_name="CPU state", discovery_function=inventory_siemens_plc_cpu_state, diff --git a/cmk/base/legacy_checks/silverpeak_VX6000.py b/cmk/base/legacy_checks/silverpeak_VX6000.py index e808fb284a6..5ade6ba4730 100644 --- a/cmk/base/legacy_checks/silverpeak_VX6000.py +++ b/cmk/base/legacy_checks/silverpeak_VX6000.py @@ -117,6 +117,7 @@ def check_silverpeak(_item, _params, parsed): check_info["silverpeak_VX6000"] = LegacyCheckDefinition( + name="silverpeak_VX6000", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.23867"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/skype.py b/cmk/base/legacy_checks/skype.py index cb6832ecf29..32aa452125e 100644 --- a/cmk/base/legacy_checks/skype.py +++ b/cmk/base/legacy_checks/skype.py @@ -127,6 +127,7 @@ def discover_skype(table): check_info["skype"] = LegacyCheckDefinition( + name="skype", parse_function=parse_skype, service_name="Skype Web Components", discovery_function=discover_skype, @@ -194,6 +195,7 @@ def discover_skype_mcu(parsed): check_info["skype.mcu"] = LegacyCheckDefinition( + name="skype_mcu", service_name="Skype MCU Health", sections=["skype"], discovery_function=discover_skype_mcu, @@ -245,6 +247,7 @@ def discover_skype_conferencing(table): check_info["skype.conferencing"] = LegacyCheckDefinition( + name="skype_conferencing", service_name="Skype Conferencing", sections=["skype"], discovery_function=discover_skype_conferencing, @@ -407,6 +410,7 @@ def check_skype_sip_stack(_no_item, params, parsed): check_info["skype.sip_stack"] = LegacyCheckDefinition( + name="skype_sip_stack", service_name="Skype SIP Stack", sections=["skype"], discovery_function=discover_skype_sip_stack, @@ -486,6 +490,7 @@ def discover_skype_mediation_server(parsed): check_info["skype.mediation_server"] = LegacyCheckDefinition( + name="skype_mediation_server", service_name="Skype Mediation Server", sections=["skype"], discovery_function=discover_skype_mediation_server, @@ -517,6 +522,7 @@ def discover_skype_edge_auth(parsed): check_info["skype.edge_auth"] = LegacyCheckDefinition( + name="skype_edge_auth", service_name="Skype Edge Authentification", sections=["skype"], discovery_function=discover_skype_edge_auth, @@ -597,6 +603,7 @@ def discover_skype_edge(parsed): check_info["skype.edge"] = LegacyCheckDefinition( + name="skype_edge", service_name="Skype AV Edge %s", sections=["skype"], discovery_function=discover_skype_edge, @@ -637,6 +644,7 @@ def discover_skype_data_proxy(parsed): check_info["skype.data_proxy"] = LegacyCheckDefinition( + name="skype_data_proxy", service_name="Skype Data Proxy %s", sections=["skype"], discovery_function=discover_skype_data_proxy, @@ -675,6 +683,7 @@ def discover_skype_xmpp_proxy(parsed): check_info["skype.xmpp_proxy"] = LegacyCheckDefinition( + name="skype_xmpp_proxy", service_name="Skype XMPP Proxy", sections=["skype"], discovery_function=discover_skype_xmpp_proxy, @@ -728,6 +737,7 @@ def discover_skype_mobile(parsed): check_info["skype.mobile"] = LegacyCheckDefinition( + name="skype_mobile", service_name="Skype Mobile Sessions", sections=["skype"], discovery_function=discover_skype_mobile, diff --git a/cmk/base/legacy_checks/smart.py b/cmk/base/legacy_checks/smart.py index 6d5a047e14a..0ffbef65799 100644 --- a/cmk/base/legacy_checks/smart.py +++ b/cmk/base/legacy_checks/smart.py @@ -45,6 +45,7 @@ def check_smart_temp(item, params, section): check_info["smart.temp"] = LegacyCheckDefinition( + name="smart_temp", # section already migrated! service_name="Temperature SMART %s", sections=["smart"], diff --git a/cmk/base/legacy_checks/sni_octopuse_cpu.py b/cmk/base/legacy_checks/sni_octopuse_cpu.py index a975895d437..471ffd9f8f4 100644 --- a/cmk/base/legacy_checks/sni_octopuse_cpu.py +++ b/cmk/base/legacy_checks/sni_octopuse_cpu.py @@ -27,6 +27,7 @@ def parse_sni_octopuse_cpu(string_table: StringTable) -> StringTable | None: check_info["sni_octopuse_cpu"] = LegacyCheckDefinition( + name="sni_octopuse_cpu", parse_function=parse_sni_octopuse_cpu, detect=DETECT_SNI_OCTOPUSE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/sni_octopuse_status.py b/cmk/base/legacy_checks/sni_octopuse_status.py index 728a3673278..8222ca5fa96 100644 --- a/cmk/base/legacy_checks/sni_octopuse_status.py +++ b/cmk/base/legacy_checks/sni_octopuse_status.py @@ -45,6 +45,7 @@ def parse_sni_octopuse_status(string_table: StringTable) -> StringTable | None: check_info["sni_octopuse_status"] = LegacyCheckDefinition( + name="sni_octopuse_status", parse_function=parse_sni_octopuse_status, detect=DETECT_SNI_OCTOPUSE, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/sni_octopuse_trunks.py b/cmk/base/legacy_checks/sni_octopuse_trunks.py index b8450b0d8e7..eba8ebba563 100644 --- a/cmk/base/legacy_checks/sni_octopuse_trunks.py +++ b/cmk/base/legacy_checks/sni_octopuse_trunks.py @@ -54,6 +54,7 @@ def parse_sni_octopuse_trunks(string_table: Sequence[StringTable]) -> Sequence[S check_info["sni_octopuse_trunks"] = LegacyCheckDefinition( + name="sni_octopuse_trunks", parse_function=parse_sni_octopuse_trunks, detect=DETECT_SNI_OCTOPUSE, fetch=[ diff --git a/cmk/base/legacy_checks/solaris_fmadm.py b/cmk/base/legacy_checks/solaris_fmadm.py index 0de96c4abca..6267be64406 100644 --- a/cmk/base/legacy_checks/solaris_fmadm.py +++ b/cmk/base/legacy_checks/solaris_fmadm.py @@ -195,6 +195,7 @@ def check_solaris_fmadm(_no_item, params, parsed): check_info["solaris_fmadm"] = LegacyCheckDefinition( + name="solaris_fmadm", parse_function=parse_solaris_fmadm, service_name="FMD Status", discovery_function=inventory_solaris_fmadm, diff --git a/cmk/base/legacy_checks/solaris_multipath.py b/cmk/base/legacy_checks/solaris_multipath.py index c7a4c935e32..824cbf435d3 100644 --- a/cmk/base/legacy_checks/solaris_multipath.py +++ b/cmk/base/legacy_checks/solaris_multipath.py @@ -73,6 +73,7 @@ def parse_solaris_multipath(string_table: StringTable) -> StringTable: check_info["solaris_multipath"] = LegacyCheckDefinition( + name="solaris_multipath", parse_function=parse_solaris_multipath, service_name="Multipath %s", discovery_function=inventory_solaris_multipath, diff --git a/cmk/base/legacy_checks/solaris_prtdiag_status.py b/cmk/base/legacy_checks/solaris_prtdiag_status.py index be53246df2c..8b2524e2170 100644 --- a/cmk/base/legacy_checks/solaris_prtdiag_status.py +++ b/cmk/base/legacy_checks/solaris_prtdiag_status.py @@ -40,6 +40,7 @@ def parse_solaris_prtdiag_status(string_table: StringTable) -> StringTable: check_info["solaris_prtdiag_status"] = LegacyCheckDefinition( + name="solaris_prtdiag_status", parse_function=parse_solaris_prtdiag_status, service_name="Hardware Overall State", discovery_function=inventory_solaris_prtdiag_status, diff --git a/cmk/base/legacy_checks/sophos.py b/cmk/base/legacy_checks/sophos.py index 815e06744c1..1b4421e579b 100644 --- a/cmk/base/legacy_checks/sophos.py +++ b/cmk/base/legacy_checks/sophos.py @@ -158,6 +158,7 @@ def parse_sophos(string_table: StringTable) -> StringTable: check_info["sophos"] = LegacyCheckDefinition( + name="sophos", parse_function=parse_sophos, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2604"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/sophos_cpu.py b/cmk/base/legacy_checks/sophos_cpu.py index 18c21ae9fdf..5d2d765f6b8 100644 --- a/cmk/base/legacy_checks/sophos_cpu.py +++ b/cmk/base/legacy_checks/sophos_cpu.py @@ -27,6 +27,7 @@ def discover_sophos_cpu(parsed): check_info["sophos_cpu"] = LegacyCheckDefinition( + name="sophos_cpu", detect=DETECT_SOPHOS, fetch=SNMPTree( base=".1.3.6.1.4.1.21067.2.1.2.2", diff --git a/cmk/base/legacy_checks/sophos_disk.py b/cmk/base/legacy_checks/sophos_disk.py index 9125d22125b..c66822775d2 100644 --- a/cmk/base/legacy_checks/sophos_disk.py +++ b/cmk/base/legacy_checks/sophos_disk.py @@ -34,6 +34,7 @@ def discover_sophos_disk(parsed): check_info["sophos_disk"] = LegacyCheckDefinition( + name="sophos_disk", detect=DETECT_SOPHOS, fetch=SNMPTree( base=".1.3.6.1.4.1.21067.2.1.2.3", diff --git a/cmk/base/legacy_checks/sophos_memory.py b/cmk/base/legacy_checks/sophos_memory.py index b0d8eb260a1..47f3451b3f6 100644 --- a/cmk/base/legacy_checks/sophos_memory.py +++ b/cmk/base/legacy_checks/sophos_memory.py @@ -33,6 +33,7 @@ def discover_sophos_memory(parsed): check_info["sophos_memory"] = LegacyCheckDefinition( + name="sophos_memory", detect=DETECT_SOPHOS, fetch=SNMPTree( base=".1.3.6.1.4.1.21067.2.1.2.4", diff --git a/cmk/base/legacy_checks/sophos_messages.py b/cmk/base/legacy_checks/sophos_messages.py index cc4505f503a..446a51d5df4 100644 --- a/cmk/base/legacy_checks/sophos_messages.py +++ b/cmk/base/legacy_checks/sophos_messages.py @@ -56,6 +56,7 @@ def parse_sophos_messages(string_table: StringTable) -> StringTable: check_info["sophos_messages"] = LegacyCheckDefinition( + name="sophos_messages", parse_function=parse_sophos_messages, detect=equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.2604"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/statgrab_cpu.py b/cmk/base/legacy_checks/statgrab_cpu.py index 4e2ccdfe699..f9a52e4da30 100644 --- a/cmk/base/legacy_checks/statgrab_cpu.py +++ b/cmk/base/legacy_checks/statgrab_cpu.py @@ -48,6 +48,7 @@ def parse_statgrab_cpu(string_table: StringTable) -> StringTable: check_info["statgrab_cpu"] = LegacyCheckDefinition( + name="statgrab_cpu", parse_function=parse_statgrab_cpu, service_name="CPU utilization", discovery_function=inventory_statgrab_cpu, diff --git a/cmk/base/legacy_checks/steelhead_connections.py b/cmk/base/legacy_checks/steelhead_connections.py index 8a4f57c97c1..2c5b92cf378 100644 --- a/cmk/base/legacy_checks/steelhead_connections.py +++ b/cmk/base/legacy_checks/steelhead_connections.py @@ -74,6 +74,7 @@ def parse_steelhead_connections(string_table: StringTable) -> StringTable: check_info["steelhead_connections"] = LegacyCheckDefinition( + name="steelhead_connections", parse_function=parse_steelhead_connections, detect=DETECT_STEELHEAD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/steelhead_peers.py b/cmk/base/legacy_checks/steelhead_peers.py index 0d40bbfd980..6077f691fc5 100644 --- a/cmk/base/legacy_checks/steelhead_peers.py +++ b/cmk/base/legacy_checks/steelhead_peers.py @@ -32,6 +32,7 @@ def parse_steelhead_peers(string_table: StringTable) -> StringTable: check_info["steelhead_peers"] = LegacyCheckDefinition( + name="steelhead_peers", parse_function=parse_steelhead_peers, detect=DETECT_STEELHEAD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/steelhead_status.py b/cmk/base/legacy_checks/steelhead_status.py index 438e0224d8f..079e95e2342 100644 --- a/cmk/base/legacy_checks/steelhead_status.py +++ b/cmk/base/legacy_checks/steelhead_status.py @@ -28,6 +28,7 @@ def parse_steelhead_status(string_table: StringTable) -> StringTable: check_info["steelhead_status"] = LegacyCheckDefinition( + name="steelhead_status", parse_function=parse_steelhead_status, detect=DETECT_STEELHEAD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/storcli_pdisks.py b/cmk/base/legacy_checks/storcli_pdisks.py index 5e8ba204fcb..892bebbcf18 100644 --- a/cmk/base/legacy_checks/storcli_pdisks.py +++ b/cmk/base/legacy_checks/storcli_pdisks.py @@ -52,6 +52,7 @@ def check_storcli_pdisks(item, params, parsed): check_info["storcli_pdisks"] = LegacyCheckDefinition( + name="storcli_pdisks", parse_function=parse_storcli_pdisks, service_name="RAID PDisk EID:Slot-Device %s", discovery_function=inventory_storcli_pdisks, diff --git a/cmk/base/legacy_checks/storeonce4x_alerts.py b/cmk/base/legacy_checks/storeonce4x_alerts.py index ed06561d824..324c9f96b90 100644 --- a/cmk/base/legacy_checks/storeonce4x_alerts.py +++ b/cmk/base/legacy_checks/storeonce4x_alerts.py @@ -56,6 +56,7 @@ def check_storeonce4x_alerts(_item, _param, parsed): check_info["storeonce4x_alerts"] = LegacyCheckDefinition( + name="storeonce4x_alerts", parse_function=parse_storeonce4x_alerts, service_name="Alerts", discovery_function=discover_storeonce4x_alerts, diff --git a/cmk/base/legacy_checks/storeonce4x_d2d_services.py b/cmk/base/legacy_checks/storeonce4x_d2d_services.py index f2a5990d8ea..8f448303fd5 100644 --- a/cmk/base/legacy_checks/storeonce4x_d2d_services.py +++ b/cmk/base/legacy_checks/storeonce4x_d2d_services.py @@ -41,6 +41,7 @@ def check_storeonce4x_d2d_services(_item, _params, parsed): check_info["storeonce4x_d2d_services"] = LegacyCheckDefinition( + name="storeonce4x_d2d_services", parse_function=parse_storeonce4x_d2d_services, service_name="D2D Services", discovery_function=discover_storeonce4x_d2d_services, diff --git a/cmk/base/legacy_checks/stormshield_cluster.py b/cmk/base/legacy_checks/stormshield_cluster.py index b540b7f44f2..f0940755ff1 100644 --- a/cmk/base/legacy_checks/stormshield_cluster.py +++ b/cmk/base/legacy_checks/stormshield_cluster.py @@ -56,6 +56,7 @@ def parse_stormshield_cluster(string_table: StringTable) -> StringTable | None: check_info["stormshield_cluster"] = LegacyCheckDefinition( + name="stormshield_cluster", parse_function=parse_stormshield_cluster, detect=all_of( any_of( diff --git a/cmk/base/legacy_checks/stormshield_cluster_node.py b/cmk/base/legacy_checks/stormshield_cluster_node.py index ddb029db8e5..76c9391f91d 100644 --- a/cmk/base/legacy_checks/stormshield_cluster_node.py +++ b/cmk/base/legacy_checks/stormshield_cluster_node.py @@ -91,6 +91,7 @@ def parse_stormshield_cluster_node(string_table: StringTable) -> StringTable: check_info["stormshield_cluster_node"] = LegacyCheckDefinition( + name="stormshield_cluster_node", parse_function=parse_stormshield_cluster_node, detect=all_of( any_of( diff --git a/cmk/base/legacy_checks/stormshield_cpu_temp.py b/cmk/base/legacy_checks/stormshield_cpu_temp.py index f7555f0e230..b24ea0f8dd4 100644 --- a/cmk/base/legacy_checks/stormshield_cpu_temp.py +++ b/cmk/base/legacy_checks/stormshield_cpu_temp.py @@ -29,6 +29,7 @@ def parse_stormshield_cpu_temp(string_table: StringTable) -> StringTable: check_info["stormshield_cpu_temp"] = LegacyCheckDefinition( + name="stormshield_cpu_temp", parse_function=parse_stormshield_cpu_temp, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_disk.py b/cmk/base/legacy_checks/stormshield_disk.py index c7aa90e0d8e..5e2b17ee65b 100644 --- a/cmk/base/legacy_checks/stormshield_disk.py +++ b/cmk/base/legacy_checks/stormshield_disk.py @@ -60,6 +60,7 @@ def check_stormshield_disk(item, params, parsed): check_info["stormshield_disk"] = LegacyCheckDefinition( + name="stormshield_disk", detect=DETECT_STORMSHIELD, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_info.py b/cmk/base/legacy_checks/stormshield_info.py index ef9a0e1aad2..0ce9aca59fc 100644 --- a/cmk/base/legacy_checks/stormshield_info.py +++ b/cmk/base/legacy_checks/stormshield_info.py @@ -35,6 +35,7 @@ def parse_stormshield_info(string_table: StringTable) -> StringTable | None: check_info["stormshield_info"] = LegacyCheckDefinition( + name="stormshield_info", parse_function=parse_stormshield_info, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_packets.py b/cmk/base/legacy_checks/stormshield_packets.py index c76a37fdd10..22dc08e62b1 100644 --- a/cmk/base/legacy_checks/stormshield_packets.py +++ b/cmk/base/legacy_checks/stormshield_packets.py @@ -52,6 +52,7 @@ def parse_stormshield_packets(string_table: StringTable) -> StringTable: check_info["stormshield_packets"] = LegacyCheckDefinition( + name="stormshield_packets", parse_function=parse_stormshield_packets, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_policy.py b/cmk/base/legacy_checks/stormshield_policy.py index 09f4cece486..05928147733 100644 --- a/cmk/base/legacy_checks/stormshield_policy.py +++ b/cmk/base/legacy_checks/stormshield_policy.py @@ -39,6 +39,7 @@ def parse_stormshield_policy(string_table: StringTable) -> StringTable: check_info["stormshield_policy"] = LegacyCheckDefinition( + name="stormshield_policy", parse_function=parse_stormshield_policy, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_route.py b/cmk/base/legacy_checks/stormshield_route.py index c770782a259..b807d0db57d 100644 --- a/cmk/base/legacy_checks/stormshield_route.py +++ b/cmk/base/legacy_checks/stormshield_route.py @@ -48,6 +48,7 @@ def parse_stormshield_route(string_table: StringTable) -> StringTable: check_info["stormshield_route"] = LegacyCheckDefinition( + name="stormshield_route", parse_function=parse_stormshield_route, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stormshield_updates.py b/cmk/base/legacy_checks/stormshield_updates.py index 6a3ad984f39..a6112a00c3c 100644 --- a/cmk/base/legacy_checks/stormshield_updates.py +++ b/cmk/base/legacy_checks/stormshield_updates.py @@ -34,6 +34,7 @@ def parse_stormshield_updates(string_table: StringTable) -> StringTable: check_info["stormshield_updates"] = LegacyCheckDefinition( + name="stormshield_updates", parse_function=parse_stormshield_updates, detect=DETECT_STORMSHIELD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/strem1_sensors.py b/cmk/base/legacy_checks/strem1_sensors.py index e6a31eac0e8..3ffb0c17b64 100644 --- a/cmk/base/legacy_checks/strem1_sensors.py +++ b/cmk/base/legacy_checks/strem1_sensors.py @@ -64,6 +64,7 @@ def parse_strem1_sensors(string_table: Sequence[StringTable]) -> Sequence[String check_info["strem1_sensors"] = LegacyCheckDefinition( + name="strem1_sensors", parse_function=parse_strem1_sensors, detect=contains(".1.3.6.1.2.1.1.1.0", "Sensatronics EM1"), fetch=[ diff --git a/cmk/base/legacy_checks/stulz_alerts.py b/cmk/base/legacy_checks/stulz_alerts.py index 36873013426..4e110bb04f9 100644 --- a/cmk/base/legacy_checks/stulz_alerts.py +++ b/cmk/base/legacy_checks/stulz_alerts.py @@ -29,6 +29,7 @@ def parse_stulz_alerts(string_table: StringTable) -> StringTable: check_info["stulz_alerts"] = LegacyCheckDefinition( + name="stulz_alerts", parse_function=parse_stulz_alerts, detect=DETECT_STULZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stulz_humidity.py b/cmk/base/legacy_checks/stulz_humidity.py index b76d94c21db..df80d221fc3 100644 --- a/cmk/base/legacy_checks/stulz_humidity.py +++ b/cmk/base/legacy_checks/stulz_humidity.py @@ -41,6 +41,7 @@ def parse_stulz_humidity(string_table: StringTable) -> StringTable: check_info["stulz_humidity"] = LegacyCheckDefinition( + name="stulz_humidity", parse_function=parse_stulz_humidity, detect=DETECT_STULZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stulz_powerstate.py b/cmk/base/legacy_checks/stulz_powerstate.py index 2afac273716..ecd296b896c 100644 --- a/cmk/base/legacy_checks/stulz_powerstate.py +++ b/cmk/base/legacy_checks/stulz_powerstate.py @@ -34,6 +34,7 @@ def parse_stulz_powerstate(string_table: StringTable) -> StringTable: check_info["stulz_powerstate"] = LegacyCheckDefinition( + name="stulz_powerstate", parse_function=parse_stulz_powerstate, detect=DETECT_STULZ, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/stulz_pump.py b/cmk/base/legacy_checks/stulz_pump.py index ab36005ca68..163d080389a 100644 --- a/cmk/base/legacy_checks/stulz_pump.py +++ b/cmk/base/legacy_checks/stulz_pump.py @@ -45,6 +45,7 @@ def parse_stulz_pump(string_table: Sequence[StringTable]) -> Sequence[StringTabl check_info["stulz_pump"] = LegacyCheckDefinition( + name="stulz_pump", parse_function=parse_stulz_pump, detect=DETECT_STULZ, fetch=[ diff --git a/cmk/base/legacy_checks/stulz_temp.py b/cmk/base/legacy_checks/stulz_temp.py index baff168bf27..59bcecd02b4 100644 --- a/cmk/base/legacy_checks/stulz_temp.py +++ b/cmk/base/legacy_checks/stulz_temp.py @@ -79,6 +79,7 @@ def check_stulz_temp(item, params, parsed): check_info["stulz_temp"] = LegacyCheckDefinition( + name="stulz_temp", detect=DETECT_STULZ, fetch=SNMPTree( base=".1.3.6.1.4.1.29462.10.2.1.1.1.1.1.1", diff --git a/cmk/base/legacy_checks/supermicro.py b/cmk/base/legacy_checks/supermicro.py index 14dbf55fe5f..59786c3d71f 100644 --- a/cmk/base/legacy_checks/supermicro.py +++ b/cmk/base/legacy_checks/supermicro.py @@ -74,6 +74,7 @@ def parse_supermicro(string_table: StringTable) -> StringTable: check_info["supermicro"] = LegacyCheckDefinition( + name="supermicro", parse_function=parse_supermicro, detect=DETECT_SUPERMICRO, fetch=SNMPTree( @@ -161,6 +162,7 @@ def parse_supermicro_sensors(string_table: StringTable) -> StringTable: check_info["supermicro_sensors"] = LegacyCheckDefinition( + name="supermicro_sensors", parse_function=parse_supermicro_sensors, detect=DETECT_SUPERMICRO, fetch=SNMPTree( @@ -209,6 +211,7 @@ def parse_supermicro_smart(string_table: StringTable) -> StringTable: check_info["supermicro_smart"] = LegacyCheckDefinition( + name="supermicro_smart", parse_function=parse_supermicro_smart, detect=DETECT_SUPERMICRO, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/superstack3_sensors.py b/cmk/base/legacy_checks/superstack3_sensors.py index 169ef3cbb79..1ac87b85ce4 100644 --- a/cmk/base/legacy_checks/superstack3_sensors.py +++ b/cmk/base/legacy_checks/superstack3_sensors.py @@ -30,6 +30,7 @@ def parse_superstack3_sensors(string_table: StringTable) -> StringTable: check_info["superstack3_sensors"] = LegacyCheckDefinition( + name="superstack3_sensors", parse_function=parse_superstack3_sensors, detect=contains(".1.3.6.1.2.1.1.1.0", "3com superstack 3"), fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/suseconnect.py b/cmk/base/legacy_checks/suseconnect.py index 4827afbe8f6..248d01c7e6f 100644 --- a/cmk/base/legacy_checks/suseconnect.py +++ b/cmk/base/legacy_checks/suseconnect.py @@ -115,6 +115,7 @@ def check_suseconnect( check_info["suseconnect"] = LegacyCheckDefinition( + name="suseconnect", service_name="SLES license", # section is migrated already!, discovery_function=inventory_suseconnect, diff --git a/cmk/base/legacy_checks/sylo.py b/cmk/base/legacy_checks/sylo.py index 94a59e143ee..fe36eb82bc1 100644 --- a/cmk/base/legacy_checks/sylo.py +++ b/cmk/base/legacy_checks/sylo.py @@ -109,6 +109,7 @@ def parse_sylo(string_table: StringTable) -> StringTable: check_info["sylo"] = LegacyCheckDefinition( + name="sylo", parse_function=parse_sylo, service_name="Sylo", discovery_function=inventory_sylo, diff --git a/cmk/base/legacy_checks/sym_brightmail_queues.py b/cmk/base/legacy_checks/sym_brightmail_queues.py index 71cbf82f73d..a961934f4ca 100644 --- a/cmk/base/legacy_checks/sym_brightmail_queues.py +++ b/cmk/base/legacy_checks/sym_brightmail_queues.py @@ -92,6 +92,7 @@ def check_sym_brightmail_queues(item, params, parsed): check_info["sym_brightmail_queues"] = LegacyCheckDefinition( + name="sym_brightmail_queues", detect=any_of(contains(".1.3.6.1.2.1.1.1.0", "el5_sms"), contains(".1.3.6.1.2.1.1.1.0", "el6")), fetch=SNMPTree( base=".1.3.6.1.4.1.393.200.130.2.2.1.1", diff --git a/cmk/base/legacy_checks/symantec_av_progstate.py b/cmk/base/legacy_checks/symantec_av_progstate.py index c615903742c..063e586f6e0 100644 --- a/cmk/base/legacy_checks/symantec_av_progstate.py +++ b/cmk/base/legacy_checks/symantec_av_progstate.py @@ -27,6 +27,7 @@ def parse_symantec_av_progstate(string_table: StringTable) -> StringTable: check_info["symantec_av_progstate"] = LegacyCheckDefinition( + name="symantec_av_progstate", parse_function=parse_symantec_av_progstate, service_name="AV Program Status", discovery_function=inventory_symantec_av_progstate, diff --git a/cmk/base/legacy_checks/symantec_av_quarantine.py b/cmk/base/legacy_checks/symantec_av_quarantine.py index 5f4544f2bfb..b926952321f 100644 --- a/cmk/base/legacy_checks/symantec_av_quarantine.py +++ b/cmk/base/legacy_checks/symantec_av_quarantine.py @@ -29,6 +29,7 @@ def parse_symantec_av_quarantine(string_table: StringTable) -> StringTable: check_info["symantec_av_quarantine"] = LegacyCheckDefinition( + name="symantec_av_quarantine", parse_function=parse_symantec_av_quarantine, service_name="AV Quarantine", discovery_function=inventory_symantec_av_quarantine, diff --git a/cmk/base/legacy_checks/symantec_av_updates.py b/cmk/base/legacy_checks/symantec_av_updates.py index 8f537517cd0..17534dcec4b 100644 --- a/cmk/base/legacy_checks/symantec_av_updates.py +++ b/cmk/base/legacy_checks/symantec_av_updates.py @@ -52,6 +52,7 @@ def parse_symantec_av_updates(string_table: StringTable) -> StringTable: check_info["symantec_av_updates"] = LegacyCheckDefinition( + name="symantec_av_updates", parse_function=parse_symantec_av_updates, service_name="AV Update Status", discovery_function=inventory_symantec_av_updates, diff --git a/cmk/base/legacy_checks/systemtime.py b/cmk/base/legacy_checks/systemtime.py index 67445584820..e321a46eb31 100644 --- a/cmk/base/legacy_checks/systemtime.py +++ b/cmk/base/legacy_checks/systemtime.py @@ -40,6 +40,7 @@ def check_systemtime(item, params, parsed): check_info["systemtime"] = LegacyCheckDefinition( + name="systemtime", service_name="System Time", discovery_function=discover_systemtime, check_function=check_systemtime, diff --git a/cmk/base/legacy_checks/teracom_tcw241_analog.py b/cmk/base/legacy_checks/teracom_tcw241_analog.py index d982fef6c68..0a0ee2fc45b 100644 --- a/cmk/base/legacy_checks/teracom_tcw241_analog.py +++ b/cmk/base/legacy_checks/teracom_tcw241_analog.py @@ -90,6 +90,7 @@ def discover_teracom_tcw241_analog(section): check_info["teracom_tcw241_analog"] = LegacyCheckDefinition( + name="teracom_tcw241_analog", detect=contains(".1.3.6.1.2.1.1.1.0", "Teracom"), fetch=[ *( diff --git a/cmk/base/legacy_checks/teracom_tcw241_digital.py b/cmk/base/legacy_checks/teracom_tcw241_digital.py index 8c65756cf72..6bf579f2372 100644 --- a/cmk/base/legacy_checks/teracom_tcw241_digital.py +++ b/cmk/base/legacy_checks/teracom_tcw241_digital.py @@ -68,6 +68,7 @@ def discover_teracom_tcw241_digital(section): check_info["teracom_tcw241_digital"] = LegacyCheckDefinition( + name="teracom_tcw241_digital", detect=contains(".1.3.6.1.2.1.1.1.0", "Teracom"), fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/tinkerforge.py b/cmk/base/legacy_checks/tinkerforge.py index a52af820ce5..cc842957944 100644 --- a/cmk/base/legacy_checks/tinkerforge.py +++ b/cmk/base/legacy_checks/tinkerforge.py @@ -138,6 +138,7 @@ def discover_tinkerforge(parsed): check_info["tinkerforge"] = LegacyCheckDefinition( + name="tinkerforge", parse_function=parse_tinkerforge, service_name="Master %s", discovery_function=discover_tinkerforge, @@ -150,6 +151,7 @@ def discover_tinkerforge_temperature(parsed): check_info["tinkerforge.temperature"] = LegacyCheckDefinition( + name="tinkerforge_temperature", service_name="Temperature %s", sections=["tinkerforge"], discovery_function=discover_tinkerforge_temperature, @@ -163,6 +165,7 @@ def discover_tinkerforge_ambient(parsed): check_info["tinkerforge.ambient"] = LegacyCheckDefinition( + name="tinkerforge_ambient", service_name="Ambient Light %s", sections=["tinkerforge"], discovery_function=discover_tinkerforge_ambient, @@ -177,6 +180,7 @@ def discover_tinkerforge_humidity(parsed): check_info["tinkerforge.humidity"] = LegacyCheckDefinition( + name="tinkerforge_humidity", service_name="Humidity %s", sections=["tinkerforge"], discovery_function=discover_tinkerforge_humidity, @@ -195,6 +199,7 @@ def discover_tinkerforge_motion(parsed): check_info["tinkerforge.motion"] = LegacyCheckDefinition( + name="tinkerforge_motion", service_name="Motion Detector %s", sections=["tinkerforge"], discovery_function=discover_tinkerforge_motion, diff --git a/cmk/base/legacy_checks/tplink_cpu.py b/cmk/base/legacy_checks/tplink_cpu.py index 96084c8e382..0305d6e8cb6 100644 --- a/cmk/base/legacy_checks/tplink_cpu.py +++ b/cmk/base/legacy_checks/tplink_cpu.py @@ -43,6 +43,7 @@ def parse_tplink_cpu(string_table: StringTable) -> StringTable: check_info["tplink_cpu"] = LegacyCheckDefinition( + name="tplink_cpu", parse_function=parse_tplink_cpu, detect=DETECT_TPLINK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/tplink_mem.py b/cmk/base/legacy_checks/tplink_mem.py index 764ef4fdb7c..0299256169b 100644 --- a/cmk/base/legacy_checks/tplink_mem.py +++ b/cmk/base/legacy_checks/tplink_mem.py @@ -44,6 +44,7 @@ def parse_tplink_mem(string_table: StringTable) -> StringTable: check_info["tplink_mem"] = LegacyCheckDefinition( + name="tplink_mem", parse_function=parse_tplink_mem, detect=DETECT_TPLINK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/tplink_poe_summary.py b/cmk/base/legacy_checks/tplink_poe_summary.py index eed3338f9cc..edcf3be6db0 100644 --- a/cmk/base/legacy_checks/tplink_poe_summary.py +++ b/cmk/base/legacy_checks/tplink_poe_summary.py @@ -28,6 +28,7 @@ def parse_tplink_poe_summary(string_table: StringTable) -> StringTable: check_info["tplink_poe_summary"] = LegacyCheckDefinition( + name="tplink_poe_summary", parse_function=parse_tplink_poe_summary, detect=DETECT_TPLINK, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/tsm_drives.py b/cmk/base/legacy_checks/tsm_drives.py index 30b88306e4c..ccee0b76ffd 100644 --- a/cmk/base/legacy_checks/tsm_drives.py +++ b/cmk/base/legacy_checks/tsm_drives.py @@ -84,6 +84,7 @@ def parse_tsm_drives(string_table: StringTable) -> StringTable: check_info["tsm_drives"] = LegacyCheckDefinition( + name="tsm_drives", parse_function=parse_tsm_drives, service_name="TSM Drive %s", discovery_function=inventory_tsm_drives, diff --git a/cmk/base/legacy_checks/tsm_paths.py b/cmk/base/legacy_checks/tsm_paths.py index f33aee73be0..b7c8fbd544b 100644 --- a/cmk/base/legacy_checks/tsm_paths.py +++ b/cmk/base/legacy_checks/tsm_paths.py @@ -27,6 +27,7 @@ def parse_tsm_paths(string_table: StringTable) -> StringTable: check_info["tsm_paths"] = LegacyCheckDefinition( + name="tsm_paths", parse_function=parse_tsm_paths, service_name="TSM Paths", discovery_function=inventory_tsm_paths, diff --git a/cmk/base/legacy_checks/tsm_scratch.py b/cmk/base/legacy_checks/tsm_scratch.py index 539362696fc..19dcc8ac0cc 100644 --- a/cmk/base/legacy_checks/tsm_scratch.py +++ b/cmk/base/legacy_checks/tsm_scratch.py @@ -51,6 +51,7 @@ def check_tsm_scratch(item, _no_params, parsed): check_info["tsm_scratch"] = LegacyCheckDefinition( + name="tsm_scratch", parse_function=parse_tsm_scratch, service_name="Scratch Pool %s", discovery_function=inventory_tsm_scratch, diff --git a/cmk/base/legacy_checks/tsm_sessions.py b/cmk/base/legacy_checks/tsm_sessions.py index 035884aa55a..1cc3d02d047 100644 --- a/cmk/base/legacy_checks/tsm_sessions.py +++ b/cmk/base/legacy_checks/tsm_sessions.py @@ -59,6 +59,7 @@ def parse_tsm_sessions(string_table: StringTable) -> StringTable: check_info["tsm_sessions"] = LegacyCheckDefinition( + name="tsm_sessions", parse_function=parse_tsm_sessions, service_name="tsm_sessions", discovery_function=inventory_tsm_sessions, diff --git a/cmk/base/legacy_checks/tsm_storagepools.py b/cmk/base/legacy_checks/tsm_storagepools.py index 58a6813734c..8ed92c7c833 100644 --- a/cmk/base/legacy_checks/tsm_storagepools.py +++ b/cmk/base/legacy_checks/tsm_storagepools.py @@ -63,6 +63,7 @@ def check_tsm_storagepools(item, _no_params, parsed): check_info["tsm_storagepools"] = LegacyCheckDefinition( + name="tsm_storagepools", parse_function=parse_tsm_storagepools, service_name="TSM Storagepool %s", discovery_function=inventory_tsm_storagepools, diff --git a/cmk/base/legacy_checks/ucd_cpu_util.py b/cmk/base/legacy_checks/ucd_cpu_util.py index 8b3d53a1cad..32eef45e1f8 100644 --- a/cmk/base/legacy_checks/ucd_cpu_util.py +++ b/cmk/base/legacy_checks/ucd_cpu_util.py @@ -91,6 +91,7 @@ def check_ucd_cpu_util(item, params, parsed): check_info["ucd_cpu_util"] = LegacyCheckDefinition( + name="ucd_cpu_util", detect=ucd_hr_detection.PREFER_HR_ELSE_UCD, fetch=SNMPTree( base=".1.3.6.1.4.1.2021.11", diff --git a/cmk/base/legacy_checks/ucd_disk.py b/cmk/base/legacy_checks/ucd_disk.py index 5b51be72190..5395f6d8c33 100644 --- a/cmk/base/legacy_checks/ucd_disk.py +++ b/cmk/base/legacy_checks/ucd_disk.py @@ -46,6 +46,7 @@ def parse_ucd_disk(string_table: StringTable) -> StringTable: check_info["ucd_disk"] = LegacyCheckDefinition( + name="ucd_disk", parse_function=parse_ucd_disk, detect=ucd_hr_detection.PREFER_HR_ELSE_UCD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ucd_mem.py b/cmk/base/legacy_checks/ucd_mem.py index 3b6d70cddeb..3513e6139ef 100644 --- a/cmk/base/legacy_checks/ucd_mem.py +++ b/cmk/base/legacy_checks/ucd_mem.py @@ -56,6 +56,7 @@ def check_ucd_mem(_no_item, params, parsed): # This check plug-in uses the migrated section in cmk/base/plugins/agent_based/ucd_mem.py! check_info["ucd_mem"] = LegacyCheckDefinition( + name="ucd_mem", service_name="Memory", discovery_function=inventory_ucd_mem, check_function=check_ucd_mem, diff --git a/cmk/base/legacy_checks/ucd_processes.py b/cmk/base/legacy_checks/ucd_processes.py index 341bbcb6cf3..8865b59bc1e 100644 --- a/cmk/base/legacy_checks/ucd_processes.py +++ b/cmk/base/legacy_checks/ucd_processes.py @@ -62,6 +62,7 @@ def parse_ucd_processes(string_table: StringTable) -> StringTable: check_info["ucd_processes"] = LegacyCheckDefinition( + name="ucd_processes", parse_function=parse_ucd_processes, detect=ucd_hr_detection.PREFER_HR_ELSE_UCD, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ucs_bladecenter_fans.py b/cmk/base/legacy_checks/ucs_bladecenter_fans.py index 1bdc1aa0623..e2e293909cc 100644 --- a/cmk/base/legacy_checks/ucs_bladecenter_fans.py +++ b/cmk/base/legacy_checks/ucs_bladecenter_fans.py @@ -84,6 +84,7 @@ def check_ucs_bladecenter_fans(item, _no_params, parsed): check_info["ucs_bladecenter_fans"] = LegacyCheckDefinition( + name="ucs_bladecenter_fans", parse_function=parse_ucs_bladecenter_fans, service_name="Fans %s", discovery_function=inventory_ucs_bladecenter_fans, @@ -125,6 +126,7 @@ def check_ucs_bladecenter_fans_temp(item, params, parsed): check_info["ucs_bladecenter_fans.temp"] = LegacyCheckDefinition( + name="ucs_bladecenter_fans_temp", service_name="Temperature %s", sections=["ucs_bladecenter_fans"], discovery_function=inventory_ucs_bladecenter_fans_temp, diff --git a/cmk/base/legacy_checks/ucs_bladecenter_faultinst.py b/cmk/base/legacy_checks/ucs_bladecenter_faultinst.py index 132d784379b..829a1dfd29c 100644 --- a/cmk/base/legacy_checks/ucs_bladecenter_faultinst.py +++ b/cmk/base/legacy_checks/ucs_bladecenter_faultinst.py @@ -49,6 +49,7 @@ def check_ucs_bladecenter_faultinst(_item, params, parsed): check_info["ucs_bladecenter_faultinst"] = LegacyCheckDefinition( + name="ucs_bladecenter_faultinst", parse_function=ucs_bladecenter.generic_parse, service_name="Fault Instances Blade", discovery_function=inventory_ucs_bladecenter_faultinst, diff --git a/cmk/base/legacy_checks/ucs_bladecenter_psu.py b/cmk/base/legacy_checks/ucs_bladecenter_psu.py index 01e99c7bfe5..388fa366347 100644 --- a/cmk/base/legacy_checks/ucs_bladecenter_psu.py +++ b/cmk/base/legacy_checks/ucs_bladecenter_psu.py @@ -86,6 +86,7 @@ def check_ucs_bladecenter_psu(item, params, parsed): check_info["ucs_bladecenter_psu"] = LegacyCheckDefinition( + name="ucs_bladecenter_psu", parse_function=ucs_bladecenter_psu_parse, service_name="Voltage %s", discovery_function=inventory_ucs_bladecenter_psu, @@ -132,6 +133,7 @@ def check_ucs_bladecenter_psu_switch_power(item, params, parsed): check_info["ucs_bladecenter_psu.switch_power"] = LegacyCheckDefinition( + name="ucs_bladecenter_psu_switch_power", service_name="Power Supply %s", sections=["ucs_bladecenter_psu"], discovery_function=inventory_ucs_bladecenter_psu_switch_power, @@ -167,6 +169,7 @@ def check_ucs_bladecenter_psu_chassis_temp(item, params, parsed): check_info["ucs_bladecenter_psu.chassis_temp"] = LegacyCheckDefinition( + name="ucs_bladecenter_psu_chassis_temp", service_name="Temperature %s", sections=["ucs_bladecenter_psu"], discovery_function=inventory_ucs_bladecenter_psu_chassis_temp, diff --git a/cmk/base/legacy_checks/ucs_bladecenter_topsystem.py b/cmk/base/legacy_checks/ucs_bladecenter_topsystem.py index 105b7333f67..1557bd77e88 100644 --- a/cmk/base/legacy_checks/ucs_bladecenter_topsystem.py +++ b/cmk/base/legacy_checks/ucs_bladecenter_topsystem.py @@ -29,6 +29,7 @@ def parse_ucs_bladecenter_topsystem(string_table: StringTable) -> StringTable: check_info["ucs_bladecenter_topsystem"] = LegacyCheckDefinition( + name="ucs_bladecenter_topsystem", parse_function=parse_ucs_bladecenter_topsystem, service_name="UCS TopSystem Info", discovery_function=inventory_ucs_bladecenter_topsystem, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_fans.py b/cmk/base/legacy_checks/ucs_c_rack_server_fans.py index 987a597cd62..62ec9847143 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_fans.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_fans.py @@ -55,6 +55,7 @@ def discover_ucs_c_rack_server_fans(section): check_info["ucs_c_rack_server_fans"] = LegacyCheckDefinition( + name="ucs_c_rack_server_fans", parse_function=parse_ucs_c_rack_server_fans, service_name="Fan %s", discovery_function=discover_ucs_c_rack_server_fans, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_faultinst.py b/cmk/base/legacy_checks/ucs_c_rack_server_faultinst.py index 931623e85ed..dfddfe4e823 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_faultinst.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_faultinst.py @@ -65,6 +65,7 @@ def discover_ucs_c_rack_server_faultinst(p): check_info["ucs_c_rack_server_faultinst"] = LegacyCheckDefinition( + name="ucs_c_rack_server_faultinst", service_name="Fault Instances Rack", discovery_function=discover_ucs_c_rack_server_faultinst, check_function=check_ucs_c_rack_server_faultinst, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_health.py b/cmk/base/legacy_checks/ucs_c_rack_server_health.py index 97e317d5bb7..ba3bdd115a7 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_health.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_health.py @@ -71,6 +71,7 @@ def check_ucs_c_rack_server_health(item, params, parsed): check_info["ucs_c_rack_server_health"] = LegacyCheckDefinition( + name="ucs_c_rack_server_health", parse_function=parse_ucs_c_rack_server_health, service_name="Health %s", discovery_function=inventory_ucs_c_rack_server_health, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_led.py b/cmk/base/legacy_checks/ucs_c_rack_server_led.py index 62d4ba8b3d2..dd48f8e1338 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_led.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_led.py @@ -30,6 +30,7 @@ def discover_ucs_c_rack_server_led(section): check_info["ucs_c_rack_server_led"] = LegacyCheckDefinition( + name="ucs_c_rack_server_led", service_name="LED %s", discovery_function=discover_ucs_c_rack_server_led, check_function=check_ucs_c_rack_server_led, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_power.py b/cmk/base/legacy_checks/ucs_c_rack_server_power.py index bd814a61419..0c7b4279997 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_power.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_power.py @@ -70,6 +70,7 @@ def discover_ucs_c_rack_server_power(section): check_info["ucs_c_rack_server_power"] = LegacyCheckDefinition( + name="ucs_c_rack_server_power", parse_function=parse_ucs_c_rack_server_power, service_name="Motherboard Power Statistics %s", discovery_function=discover_ucs_c_rack_server_power, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_psu.py b/cmk/base/legacy_checks/ucs_c_rack_server_psu.py index 6f0e88ead8d..2be02138857 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_psu.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_psu.py @@ -104,6 +104,7 @@ def check_ucs_c_rack_server_psu(item, _no_params, parsed): check_info["ucs_c_rack_server_psu"] = LegacyCheckDefinition( + name="ucs_c_rack_server_psu", parse_function=parse_ucs_c_rack_server_psu, service_name="Output Power %s", discovery_function=inventory_ucs_c_rack_server_psu, @@ -141,6 +142,7 @@ def check_ucs_c_rack_server_psu_voltage(item, _no_params, parsed): check_info["ucs_c_rack_server_psu.voltage"] = LegacyCheckDefinition( + name="ucs_c_rack_server_psu_voltage", service_name="Output Voltage %s", sections=["ucs_c_rack_server_psu"], discovery_function=inventory_ucs_c_rack_server_psu_voltage, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_temp.py b/cmk/base/legacy_checks/ucs_c_rack_server_temp.py index ce10d7a0d89..976b391fde3 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_temp.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_temp.py @@ -83,6 +83,7 @@ def discover_ucs_c_rack_server_temp(section): check_info["ucs_c_rack_server_temp"] = LegacyCheckDefinition( + name="ucs_c_rack_server_temp", parse_function=parse_ucs_c_rack_server_temp, service_name="Temperature %s", discovery_function=discover_ucs_c_rack_server_temp, diff --git a/cmk/base/legacy_checks/ucs_c_rack_server_topsystem.py b/cmk/base/legacy_checks/ucs_c_rack_server_topsystem.py index dcf21cf26ab..fc2b016670b 100644 --- a/cmk/base/legacy_checks/ucs_c_rack_server_topsystem.py +++ b/cmk/base/legacy_checks/ucs_c_rack_server_topsystem.py @@ -68,6 +68,7 @@ def check_ucs_c_rack_server_topsystem(item, _no_params, data): check_info["ucs_c_rack_server_topsystem"] = LegacyCheckDefinition( + name="ucs_c_rack_server_topsystem", parse_function=parse_ucs_c_rack_server_topsystem, service_name="UCS C-Series Rack Server TopSystem Info", discovery_function=inventory_ucs_c_rack_server_topsystem, diff --git a/cmk/base/legacy_checks/unitrends_backup.py b/cmk/base/legacy_checks/unitrends_backup.py index 2d88b4ff0d4..b14ce23ac35 100644 --- a/cmk/base/legacy_checks/unitrends_backup.py +++ b/cmk/base/legacy_checks/unitrends_backup.py @@ -60,6 +60,7 @@ def parse_unitrends_backup(string_table: StringTable) -> StringTable: check_info["unitrends_backup"] = LegacyCheckDefinition( + name="unitrends_backup", parse_function=parse_unitrends_backup, service_name="Schedule %s", discovery_function=inventory_unitrends_backup, diff --git a/cmk/base/legacy_checks/unitrends_replication.py b/cmk/base/legacy_checks/unitrends_replication.py index d5b67d6f9db..cbffce56b0b 100644 --- a/cmk/base/legacy_checks/unitrends_replication.py +++ b/cmk/base/legacy_checks/unitrends_replication.py @@ -40,6 +40,7 @@ def parse_unitrends_replication(string_table: StringTable) -> StringTable: check_info["unitrends_replication"] = LegacyCheckDefinition( + name="unitrends_replication", parse_function=parse_unitrends_replication, service_name="Replicaion %s", discovery_function=inventory_unitrends_replication, diff --git a/cmk/base/legacy_checks/ups_bat_temp.py b/cmk/base/legacy_checks/ups_bat_temp.py index 74f704eab6a..0b51785ef4b 100644 --- a/cmk/base/legacy_checks/ups_bat_temp.py +++ b/cmk/base/legacy_checks/ups_bat_temp.py @@ -56,6 +56,7 @@ def parse_ups_bat_temp(string_table: StringTable) -> StringTable: check_info["ups_bat_temp"] = LegacyCheckDefinition( + name="ups_bat_temp", parse_function=parse_ups_bat_temp, detect=DETECT_UPS_GENERIC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_cps_battery.py b/cmk/base/legacy_checks/ups_cps_battery.py index c5702dcb93f..1610e6c7c62 100644 --- a/cmk/base/legacy_checks/ups_cps_battery.py +++ b/cmk/base/legacy_checks/ups_cps_battery.py @@ -53,6 +53,7 @@ def check_ups_cps_battery_temp(item, params, parsed): check_info["ups_cps_battery.temp"] = LegacyCheckDefinition( + name="ups_cps_battery_temp", service_name="Temperature %s", sections=["ups_cps_battery"], discovery_function=inventory_ups_cps_battery_temp, @@ -108,6 +109,7 @@ def check_lower_levels(value, levels): check_info["ups_cps_battery"] = LegacyCheckDefinition( + name="ups_cps_battery", detect=DETECT_UPS_CPS, fetch=SNMPTree( base=".1.3.6.1.4.1.3808.1.1.1.2.2", diff --git a/cmk/base/legacy_checks/ups_cps_inphase.py b/cmk/base/legacy_checks/ups_cps_inphase.py index c8531613678..cff53604463 100644 --- a/cmk/base/legacy_checks/ups_cps_inphase.py +++ b/cmk/base/legacy_checks/ups_cps_inphase.py @@ -33,6 +33,7 @@ def inventory_ups_cps_inphase(parsed): check_info["ups_cps_inphase"] = LegacyCheckDefinition( + name="ups_cps_inphase", detect=DETECT_UPS_CPS, fetch=SNMPTree( base=".1.3.6.1.4.1.3808.1.1.1.3.2", diff --git a/cmk/base/legacy_checks/ups_cps_outphase.py b/cmk/base/legacy_checks/ups_cps_outphase.py index 840c38ecc3a..3136e0b8fce 100644 --- a/cmk/base/legacy_checks/ups_cps_outphase.py +++ b/cmk/base/legacy_checks/ups_cps_outphase.py @@ -45,6 +45,7 @@ def inventory_ups_cps_outphase(section: Section) -> Iterable[tuple[str, dict]]: check_info["ups_cps_outphase"] = LegacyCheckDefinition( + name="ups_cps_outphase", detect=DETECT_UPS_CPS, fetch=SNMPTree( base=".1.3.6.1.4.1.3808.1.1.1.4.2", diff --git a/cmk/base/legacy_checks/ups_eaton_enviroment.py b/cmk/base/legacy_checks/ups_eaton_enviroment.py index 287556d35c7..d30e1c46ae3 100644 --- a/cmk/base/legacy_checks/ups_eaton_enviroment.py +++ b/cmk/base/legacy_checks/ups_eaton_enviroment.py @@ -70,6 +70,7 @@ def parse_ups_eaton_enviroment(string_table: StringTable) -> StringTable: check_info["ups_eaton_enviroment"] = LegacyCheckDefinition( + name="ups_eaton_enviroment", parse_function=parse_ups_eaton_enviroment, detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.705.1.2"), diff --git a/cmk/base/legacy_checks/ups_in_freq.py b/cmk/base/legacy_checks/ups_in_freq.py index 9fe2939eae8..dcd45692a08 100644 --- a/cmk/base/legacy_checks/ups_in_freq.py +++ b/cmk/base/legacy_checks/ups_in_freq.py @@ -46,6 +46,7 @@ def check_ups_in_freq(item, params, parsed): check_info["ups_in_freq"] = LegacyCheckDefinition( + name="ups_in_freq", detect=DETECT_UPS_GENERIC, fetch=SNMPTree( base=".1.3.6.1.2.1.33.1.3.3.1", diff --git a/cmk/base/legacy_checks/ups_in_voltage.py b/cmk/base/legacy_checks/ups_in_voltage.py index 8be4a1a30db..3c31f30eeb6 100644 --- a/cmk/base/legacy_checks/ups_in_voltage.py +++ b/cmk/base/legacy_checks/ups_in_voltage.py @@ -21,6 +21,7 @@ def parse_ups_in_voltage(string_table: StringTable) -> StringTable: check_info["ups_in_voltage"] = LegacyCheckDefinition( + name="ups_in_voltage", parse_function=parse_ups_in_voltage, detect=DETECT_UPS_GENERIC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_modulys_alarms.py b/cmk/base/legacy_checks/ups_modulys_alarms.py index 9884438ce68..a891b3718e7 100644 --- a/cmk/base/legacy_checks/ups_modulys_alarms.py +++ b/cmk/base/legacy_checks/ups_modulys_alarms.py @@ -65,6 +65,7 @@ def parse_ups_modulys_alarms(string_table: StringTable) -> StringTable: check_info["ups_modulys_alarms"] = LegacyCheckDefinition( + name="ups_modulys_alarms", parse_function=parse_ups_modulys_alarms, detect=DETECT_UPS_MODULYS, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_modulys_inphase.py b/cmk/base/legacy_checks/ups_modulys_inphase.py index 5f030849fa3..b9f9b6ca954 100644 --- a/cmk/base/legacy_checks/ups_modulys_inphase.py +++ b/cmk/base/legacy_checks/ups_modulys_inphase.py @@ -43,6 +43,7 @@ def discover_ups_modulys_inphase(section): check_info["ups_modulys_inphase"] = LegacyCheckDefinition( + name="ups_modulys_inphase", detect=DETECT_UPS_MODULYS, fetch=SNMPTree( base=".1.3.6.1.4.1.2254.2.4.4", diff --git a/cmk/base/legacy_checks/ups_modulys_outphase.py b/cmk/base/legacy_checks/ups_modulys_outphase.py index 7517cf8940e..dd60ee74320 100644 --- a/cmk/base/legacy_checks/ups_modulys_outphase.py +++ b/cmk/base/legacy_checks/ups_modulys_outphase.py @@ -50,6 +50,7 @@ def discover_ups_modulys_outphase(section): check_info["ups_modulys_outphase"] = LegacyCheckDefinition( + name="ups_modulys_outphase", detect=DETECT_UPS_MODULYS, fetch=SNMPTree( base=".1.3.6.1.4.1.2254.2.4.5", diff --git a/cmk/base/legacy_checks/ups_out_voltage.py b/cmk/base/legacy_checks/ups_out_voltage.py index bc42ac4e131..8b1346c5b4a 100644 --- a/cmk/base/legacy_checks/ups_out_voltage.py +++ b/cmk/base/legacy_checks/ups_out_voltage.py @@ -23,6 +23,7 @@ def parse_ups_out_voltage(string_table: StringTable) -> StringTable: check_info["ups_out_voltage"] = LegacyCheckDefinition( + name="ups_out_voltage", parse_function=parse_ups_out_voltage, detect=DETECT_UPS_GENERIC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_socomec_capacity.py b/cmk/base/legacy_checks/ups_socomec_capacity.py index 404c094b9c2..bc5fe41fc52 100644 --- a/cmk/base/legacy_checks/ups_socomec_capacity.py +++ b/cmk/base/legacy_checks/ups_socomec_capacity.py @@ -81,6 +81,7 @@ def parse_ups_socomec_capacity(string_table: StringTable) -> StringTable: check_info["ups_socomec_capacity"] = LegacyCheckDefinition( + name="ups_socomec_capacity", parse_function=parse_ups_socomec_capacity, detect=DETECT_SOCOMEC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_socomec_in_voltage.py b/cmk/base/legacy_checks/ups_socomec_in_voltage.py index e14e4ae1333..cead7cd3df7 100644 --- a/cmk/base/legacy_checks/ups_socomec_in_voltage.py +++ b/cmk/base/legacy_checks/ups_socomec_in_voltage.py @@ -41,6 +41,7 @@ def parse_ups_socomec_in_voltage(string_table: StringTable) -> StringTable: check_info["ups_socomec_in_voltage"] = LegacyCheckDefinition( + name="ups_socomec_in_voltage", parse_function=parse_ups_socomec_in_voltage, detect=DETECT_SOCOMEC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_socomec_out_source.py b/cmk/base/legacy_checks/ups_socomec_out_source.py index 2de2ce34f89..ab81a7afd62 100644 --- a/cmk/base/legacy_checks/ups_socomec_out_source.py +++ b/cmk/base/legacy_checks/ups_socomec_out_source.py @@ -52,6 +52,7 @@ def parse_ups_socomec_out_source(string_table: StringTable) -> StringTable: check_info["ups_socomec_out_source"] = LegacyCheckDefinition( + name="ups_socomec_out_source", parse_function=parse_ups_socomec_out_source, detect=DETECT_SOCOMEC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_socomec_out_voltage.py b/cmk/base/legacy_checks/ups_socomec_out_voltage.py index f0dc3230e86..8880e851ef1 100644 --- a/cmk/base/legacy_checks/ups_socomec_out_voltage.py +++ b/cmk/base/legacy_checks/ups_socomec_out_voltage.py @@ -43,6 +43,7 @@ def parse_ups_socomec_out_voltage(string_table: StringTable) -> StringTable: check_info["ups_socomec_out_voltage"] = LegacyCheckDefinition( + name="ups_socomec_out_voltage", parse_function=parse_ups_socomec_out_voltage, detect=DETECT_SOCOMEC, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/ups_socomec_outphase.py b/cmk/base/legacy_checks/ups_socomec_outphase.py index b7cd2f99dee..5f197213266 100644 --- a/cmk/base/legacy_checks/ups_socomec_outphase.py +++ b/cmk/base/legacy_checks/ups_socomec_outphase.py @@ -35,6 +35,7 @@ def discover_ups_socomec_outphase(section): check_info["ups_socomec_outphase"] = LegacyCheckDefinition( + name="ups_socomec_outphase", detect=DETECT_SOCOMEC, fetch=SNMPTree( base=".1.3.6.1.4.1.4555.1.1.1.1.4.4.1", diff --git a/cmk/base/legacy_checks/varnish.py b/cmk/base/legacy_checks/varnish.py index c4d0b42a00e..6d8ad606cca 100644 --- a/cmk/base/legacy_checks/varnish.py +++ b/cmk/base/legacy_checks/varnish.py @@ -402,6 +402,7 @@ def check_varnish_uptime(_no_item, _no_params, parsed): check_info["varnish"] = LegacyCheckDefinition( + name="varnish", parse_function=parse_varnish, service_name="Varnish Uptime", discovery_function=inventory_varnish_uptime, @@ -436,6 +437,7 @@ def check_varnish_cache(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.cache"] = LegacyCheckDefinition( + name="varnish_cache", service_name="Varnish Cache", sections=["varnish"], discovery_function=discover_varnish_cache, @@ -472,6 +474,7 @@ def check_varnish_client(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.client"] = LegacyCheckDefinition( + name="varnish_client", service_name="Varnish Client", sections=["varnish"], discovery_function=discover_varnish_client, @@ -513,6 +516,7 @@ def check_varnish_backend(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.backend"] = LegacyCheckDefinition( + name="varnish_backend", service_name="Varnish Backend", sections=["varnish"], discovery_function=discover_varnish_backend, @@ -568,6 +572,7 @@ def check_varnish_fetch(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.fetch"] = LegacyCheckDefinition( + name="varnish_fetch", service_name="Varnish Fetch", sections=["varnish"], discovery_function=discover_varnish_fetch, @@ -602,6 +607,7 @@ def check_varnish_esi(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.esi"] = LegacyCheckDefinition( + name="varnish_esi", service_name="Varnish ESI", sections=["varnish"], discovery_function=discover_varnish_esi, @@ -638,6 +644,7 @@ def check_varnish_objects(item, params, parsed): # | |__/ | # '----------------------------------------------------------------------' check_info["varnish.objects"] = LegacyCheckDefinition( + name="varnish_objects", service_name="Varnish Objects", sections=["varnish"], discovery_function=discover_varnish_objects, @@ -677,6 +684,7 @@ def check_varnish_worker(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.worker"] = LegacyCheckDefinition( + name="varnish_worker", service_name="Varnish Worker", sections=["varnish"], discovery_function=discover_varnish_worker, @@ -703,6 +711,7 @@ def check_varnish_cache_hit_ratio(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.cache_hit_ratio"] = LegacyCheckDefinition( + name="varnish_cache_hit_ratio", service_name="Varnish Cache Hit Ratio", sections=["varnish"], discovery_function=discover_varnish_cache_hit_ratio, @@ -738,6 +747,7 @@ def check_varnish_backend_success_ratio(item, params, parsed): # | | # '----------------------------------------------------------------------' check_info["varnish.backend_success_ratio"] = LegacyCheckDefinition( + name="varnish_backend_success_ratio", service_name="Varnish Backend Success Ratio", sections=["varnish"], discovery_function=discover_varnish_backend_success_ratio, @@ -781,6 +791,7 @@ def discover_varnish_worker_thread_ratio(parsed): check_info["varnish.worker_thread_ratio"] = LegacyCheckDefinition( + name="varnish_worker_thread_ratio", service_name="Varnish Worker Thread Ratio", sections=["varnish"], discovery_function=discover_varnish_worker_thread_ratio, diff --git a/cmk/base/legacy_checks/vbox_guest.py b/cmk/base/legacy_checks/vbox_guest.py index de3cb6cc86c..5bb1eacd4ee 100644 --- a/cmk/base/legacy_checks/vbox_guest.py +++ b/cmk/base/legacy_checks/vbox_guest.py @@ -51,6 +51,7 @@ def parse_vbox_guest(string_table: StringTable) -> StringTable: check_info["vbox_guest"] = LegacyCheckDefinition( + name="vbox_guest", parse_function=parse_vbox_guest, service_name="VBox Guest Additions", discovery_function=inventory_vbox_guest, diff --git a/cmk/base/legacy_checks/veeam_client.py b/cmk/base/legacy_checks/veeam_client.py index 451dd535985..f2821391905 100644 --- a/cmk/base/legacy_checks/veeam_client.py +++ b/cmk/base/legacy_checks/veeam_client.py @@ -149,6 +149,7 @@ def check_veeam_client(item, params, parsed): # pylint: disable=too-many-branch check_info["veeam_client"] = LegacyCheckDefinition( + name="veeam_client", parse_function=parse_veeam_client, service_name="VEEAM Client %s", discovery_function=inventory_veeam_client, diff --git a/cmk/base/legacy_checks/veeam_tapejobs.py b/cmk/base/legacy_checks/veeam_tapejobs.py index e63fec34d57..ac81c083e8c 100644 --- a/cmk/base/legacy_checks/veeam_tapejobs.py +++ b/cmk/base/legacy_checks/veeam_tapejobs.py @@ -79,6 +79,7 @@ def check_veeam_tapejobs(item, params, parsed): check_info["veeam_tapejobs"] = LegacyCheckDefinition( + name="veeam_tapejobs", parse_function=parse_veeam_tapejobs, service_name="VEEAM Tape Job %s", discovery_function=inventory_veeam_tapejobs, diff --git a/cmk/base/legacy_checks/viprinet_firmware.py b/cmk/base/legacy_checks/viprinet_firmware.py index 73d802dacc6..341bc33db87 100644 --- a/cmk/base/legacy_checks/viprinet_firmware.py +++ b/cmk/base/legacy_checks/viprinet_firmware.py @@ -35,6 +35,7 @@ def discover_viprinet_firmware(section: StringTable) -> DiscoveryResult: check_info["viprinet_firmware"] = LegacyCheckDefinition( + name="viprinet_firmware", parse_function=parse_viprinet_firmware, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/viprinet_mem.py b/cmk/base/legacy_checks/viprinet_mem.py index d153e4cf606..a1ae2914f07 100644 --- a/cmk/base/legacy_checks/viprinet_mem.py +++ b/cmk/base/legacy_checks/viprinet_mem.py @@ -41,6 +41,7 @@ def check_viprinet_mem(_no_item, _no_params, info): check_info["viprinet_mem"] = LegacyCheckDefinition( + name="viprinet_mem", parse_function=parse_viprinet_mem, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/viprinet_power.py b/cmk/base/legacy_checks/viprinet_power.py index b46a9ce33a3..ff1ccc86406 100644 --- a/cmk/base/legacy_checks/viprinet_power.py +++ b/cmk/base/legacy_checks/viprinet_power.py @@ -32,6 +32,7 @@ def discover_viprinet_power(section: StringTable) -> DiscoveryResult: check_info["viprinet_power"] = LegacyCheckDefinition( + name="viprinet_power", parse_function=parse_viprinet_power, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/viprinet_router.py b/cmk/base/legacy_checks/viprinet_router.py index 8c339f5f0ed..01cf636729e 100644 --- a/cmk/base/legacy_checks/viprinet_router.py +++ b/cmk/base/legacy_checks/viprinet_router.py @@ -48,6 +48,7 @@ def discover_viprinet_router(section: StringTable) -> DiscoveryResult: check_info["viprinet_router"] = LegacyCheckDefinition( + name="viprinet_router", parse_function=parse_viprinet_router, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/viprinet_serial.py b/cmk/base/legacy_checks/viprinet_serial.py index 6ba1ae71690..6db372647d0 100644 --- a/cmk/base/legacy_checks/viprinet_serial.py +++ b/cmk/base/legacy_checks/viprinet_serial.py @@ -26,6 +26,7 @@ def parse_viprinet_serial(string_table: StringTable) -> StringTable: check_info["viprinet_serial"] = LegacyCheckDefinition( + name="viprinet_serial", parse_function=parse_viprinet_serial, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/viprinet_temp.py b/cmk/base/legacy_checks/viprinet_temp.py index 335b5309419..f34e442161c 100644 --- a/cmk/base/legacy_checks/viprinet_temp.py +++ b/cmk/base/legacy_checks/viprinet_temp.py @@ -28,6 +28,7 @@ def discover_viprinet_temp(section: StringTable) -> DiscoveryResult: check_info["viprinet_temp"] = LegacyCheckDefinition( + name="viprinet_temp", parse_function=parse_viprinet_temp, detect=DETECT_VIPRINET, fetch=SNMPTree( diff --git a/cmk/base/legacy_checks/vms_cpu.py b/cmk/base/legacy_checks/vms_cpu.py index 411a71fc3b8..d548bf00e1e 100644 --- a/cmk/base/legacy_checks/vms_cpu.py +++ b/cmk/base/legacy_checks/vms_cpu.py @@ -65,6 +65,7 @@ def check_vms_cpu(_no_item, params, parsed): check_info["vms_cpu"] = LegacyCheckDefinition( + name="vms_cpu", parse_function=parse_vms_cpu, service_name="CPU utilization", discovery_function=inventory_vms_cpu, diff --git a/cmk/base/legacy_checks/vms_queuejobs.py b/cmk/base/legacy_checks/vms_queuejobs.py index 56efa521e85..a58897df9da 100644 --- a/cmk/base/legacy_checks/vms_queuejobs.py +++ b/cmk/base/legacy_checks/vms_queuejobs.py @@ -53,6 +53,7 @@ def parse_vms_queuejobs(string_table: StringTable) -> StringTable: check_info["vms_queuejobs"] = LegacyCheckDefinition( + name="vms_queuejobs", parse_function=parse_vms_queuejobs, service_name="Queue Jobs", discovery_function=inventory_vms_queuejobs, diff --git a/cmk/base/legacy_checks/vms_system.py b/cmk/base/legacy_checks/vms_system.py index a93602cb5a1..dd964b7a142 100644 --- a/cmk/base/legacy_checks/vms_system.py +++ b/cmk/base/legacy_checks/vms_system.py @@ -24,6 +24,7 @@ def parse_vms_system(string_table: StringTable) -> StringTable: check_info["vms_system"] = LegacyCheckDefinition( + name="vms_system", parse_function=parse_vms_system, ) @@ -44,6 +45,7 @@ def check_vms_system_ios(_no_item, _no_params, info): check_info["vms_system.ios"] = LegacyCheckDefinition( + name="vms_system_ios", service_name="IOs", sections=["vms_system"], discovery_function=inventory_vms_system, @@ -65,6 +67,7 @@ def check_vms_system_procs(_no_item, params, info): check_info["vms_system.procs"] = LegacyCheckDefinition( + name="vms_system_procs", service_name="Number of processes", sections=["vms_system"], discovery_function=inventory_vms_system, diff --git a/cmk/base/legacy_checks/vms_users.py b/cmk/base/legacy_checks/vms_users.py index a5c626b959d..856db19dfa6 100644 --- a/cmk/base/legacy_checks/vms_users.py +++ b/cmk/base/legacy_checks/vms_users.py @@ -58,6 +58,7 @@ def parse_vms_users(string_table: StringTable) -> StringTable: check_info["vms_users"] = LegacyCheckDefinition( + name="vms_users", parse_function=parse_vms_users, service_name="VMS Users", discovery_function=inventory_vms_users, diff --git a/cmk/base/legacy_checks/vnx_version.py b/cmk/base/legacy_checks/vnx_version.py index e6e3ecc0708..26058a53cee 100644 --- a/cmk/base/legacy_checks/vnx_version.py +++ b/cmk/base/legacy_checks/vnx_version.py @@ -24,6 +24,7 @@ def parse_vnx_version(string_table: StringTable) -> StringTable: check_info["vnx_version"] = LegacyCheckDefinition( + name="vnx_version", parse_function=parse_vnx_version, service_name="VNX Version", discovery_function=inventory_vnx_version, diff --git a/cmk/base/legacy_checks/vutlan_ems_humidity.py b/cmk/base/legacy_checks/vutlan_ems_humidity.py index d683e7ded25..32fa6fac927 100644 --- a/cmk/base/legacy_checks/vutlan_ems_humidity.py +++ b/cmk/base/legacy_checks/vutlan_ems_humidity.py @@ -40,6 +40,7 @@ def check_vutlan_ems_humidity(item, params, parsed): check_info["vutlan_ems_humidity"] = LegacyCheckDefinition( + name="vutlan_ems_humidity", detect=DETECT_VUTLAN_EMS, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/vutlan_ems_leakage.py b/cmk/base/legacy_checks/vutlan_ems_leakage.py index 00619d5fcac..000be69b90c 100644 --- a/cmk/base/legacy_checks/vutlan_ems_leakage.py +++ b/cmk/base/legacy_checks/vutlan_ems_leakage.py @@ -43,6 +43,7 @@ def check_vutlan_ems_leakage(item, _no_params, parsed): check_info["vutlan_ems_leakage"] = LegacyCheckDefinition( + name="vutlan_ems_leakage", detect=DETECT_VUTLAN_EMS, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/vutlan_ems_temp.py b/cmk/base/legacy_checks/vutlan_ems_temp.py index 0315cdb6fd1..e267e4bcb87 100644 --- a/cmk/base/legacy_checks/vutlan_ems_temp.py +++ b/cmk/base/legacy_checks/vutlan_ems_temp.py @@ -44,6 +44,7 @@ def check_vutlan_ems_temp(item, params, parsed): check_info["vutlan_ems_temp"] = LegacyCheckDefinition( + name="vutlan_ems_temp", detect=DETECT_VUTLAN_EMS, fetch=[ SNMPTree( diff --git a/cmk/base/legacy_checks/vxvm_objstatus.py b/cmk/base/legacy_checks/vxvm_objstatus.py index 8724ef374f6..20f5c4058e7 100644 --- a/cmk/base/legacy_checks/vxvm_objstatus.py +++ b/cmk/base/legacy_checks/vxvm_objstatus.py @@ -65,6 +65,7 @@ def parse_vxvm_objstatus(string_table: StringTable) -> StringTable: check_info["vxvm_objstatus"] = LegacyCheckDefinition( + name="vxvm_objstatus", parse_function=parse_vxvm_objstatus, service_name="VXVM objstatus %s", discovery_function=inventory_vxvm_objstatus, diff --git a/cmk/base/legacy_checks/wagner_titanus_topsense.py b/cmk/base/legacy_checks/wagner_titanus_topsense.py index 39a7783a81a..3ce9380ead4 100644 --- a/cmk/base/legacy_checks/wagner_titanus_topsense.py +++ b/cmk/base/legacy_checks/wagner_titanus_topsense.py @@ -20,6 +20,7 @@ def parse_wagner_titanus_topsense( check_info["wagner_titanus_topsense"] = LegacyCheckDefinition( + name="wagner_titanus_topsense", parse_function=parse_wagner_titanus_topsense, detect=any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.34187.21501"), @@ -114,6 +115,7 @@ def check_wagner_titanus_topsense_info(item, _no_params, info): check_info["wagner_titanus_topsense.info"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_info", service_name="Topsense Info", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_info, @@ -149,6 +151,7 @@ def check_wagner_titanus_topsense_overall_status(item, _no_params, info): check_info["wagner_titanus_topsense.overall_status"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_overall_status", service_name="Overall Status", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_overall_status, @@ -200,6 +203,7 @@ def check_wagner_titanus_topsense_alarm(item, _no_params, info): check_info["wagner_titanus_topsense.alarm"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_alarm", service_name="Alarm Detector %s", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_alarm, @@ -243,6 +247,7 @@ def check_wagner_titanus_topsense_smoke(item, _no_params, info): check_info["wagner_titanus_topsense.smoke"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_smoke", service_name="Smoke Detector %s", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_smoke, @@ -280,6 +285,7 @@ def check_wagner_titanus_topsense_chamber_deviation(item, _no_params, info): check_info["wagner_titanus_topsense.chamber_deviation"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_chamber_deviation", service_name="Chamber Deviation Detector %s", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_chamber_deviation, @@ -321,6 +327,7 @@ def check_wagner_titanus_topsense_airflow_deviation(item, params, info): check_info["wagner_titanus_topsense.airflow_deviation"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_airflow_deviation", service_name="Airflow Deviation Detector %s", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_airflow_deviation, @@ -364,6 +371,7 @@ def check_wagner_titanus_topsense_temp(item, params, info): check_info["wagner_titanus_topsense.temp"] = LegacyCheckDefinition( + name="wagner_titanus_topsense_temp", service_name="Temperature %s", sections=["wagner_titanus_topsense"], discovery_function=inventory_wagner_titanus_topsense_temp, diff --git a/cmk/base/legacy_checks/watchdog_sensors.py b/cmk/base/legacy_checks/watchdog_sensors.py index 58be6a390b6..92b2f33da0f 100644 --- a/cmk/base/legacy_checks/watchdog_sensors.py +++ b/cmk/base/legacy_checks/watchdog_sensors.py @@ -145,6 +145,7 @@ def check_watchdog_sensors(item, params, parsed): check_info["watchdog_sensors"] = LegacyCheckDefinition( + name="watchdog_sensors", detect=any_of( startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21239.5.1"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.21239.42.1"), @@ -199,6 +200,7 @@ def check_watchdog_sensors_temp(item, params, parsed): check_info["watchdog_sensors.temp"] = LegacyCheckDefinition( + name="watchdog_sensors_temp", service_name="%s ", sections=["watchdog_sensors"], discovery_function=inventory_watchdog_sensors_temp, @@ -247,6 +249,7 @@ def check_watchdog_sensors_humidity(item, params, parsed): check_info["watchdog_sensors.humidity"] = LegacyCheckDefinition( + name="watchdog_sensors_humidity", service_name="%s", sections=["watchdog_sensors"], discovery_function=inventory_watchdog_sensors_humidity, @@ -290,6 +293,7 @@ def check_watchdog_sensors_dew(item, params, parsed): check_info["watchdog_sensors.dew"] = LegacyCheckDefinition( + name="watchdog_sensors_dew", service_name="%s", sections=["watchdog_sensors"], discovery_function=inventory_watchdog_sensors_dew, diff --git a/cmk/base/legacy_checks/win_license.py b/cmk/base/legacy_checks/win_license.py index afbd64a1359..fb9a2dc10de 100644 --- a/cmk/base/legacy_checks/win_license.py +++ b/cmk/base/legacy_checks/win_license.py @@ -76,6 +76,7 @@ def check_win_license(_item, params, parsed): check_info["win_license"] = LegacyCheckDefinition( + name="win_license", parse_function=parse_win_license, service_name="Windows License", discovery_function=inventory_win_license, diff --git a/cmk/base/legacy_checks/win_netstat.py b/cmk/base/legacy_checks/win_netstat.py index 4e0bd7a4bce..08d942406ad 100644 --- a/cmk/base/legacy_checks/win_netstat.py +++ b/cmk/base/legacy_checks/win_netstat.py @@ -68,6 +68,7 @@ def parse_win_netstat(string_table): check_info["win_netstat"] = LegacyCheckDefinition( + name="win_netstat", parse_function=parse_win_netstat, service_name="TCP Connection %s", check_function=check_netstat_generic, diff --git a/cmk/base/legacy_checks/win_printers.py b/cmk/base/legacy_checks/win_printers.py index 4c5b3e5985a..fe71f5b3c64 100644 --- a/cmk/base/legacy_checks/win_printers.py +++ b/cmk/base/legacy_checks/win_printers.py @@ -95,6 +95,7 @@ def check_win_printers( check_info["win_printers"] = LegacyCheckDefinition( + name="win_printers", parse_function=parse_win_printers, service_name="Printer %s", discovery_function=discover_win_printers, diff --git a/cmk/base/legacy_checks/windows_broadcom_bonding.py b/cmk/base/legacy_checks/windows_broadcom_bonding.py index f669c7b8d2b..4c1a4d22faf 100644 --- a/cmk/base/legacy_checks/windows_broadcom_bonding.py +++ b/cmk/base/legacy_checks/windows_broadcom_bonding.py @@ -42,6 +42,7 @@ def parse_windows_broadcom_bonding(string_table: StringTable) -> StringTable: check_info["windows_broadcom_bonding"] = LegacyCheckDefinition( + name="windows_broadcom_bonding", parse_function=parse_windows_broadcom_bonding, service_name="Bonding Interface %s", discovery_function=inventory_windows_broadcom_bonding, diff --git a/cmk/base/legacy_checks/windows_multipath.py b/cmk/base/legacy_checks/windows_multipath.py index 2fdb0116309..9c61abc10fd 100644 --- a/cmk/base/legacy_checks/windows_multipath.py +++ b/cmk/base/legacy_checks/windows_multipath.py @@ -57,6 +57,7 @@ def parse_windows_multipath(string_table: StringTable) -> StringTable: check_info["windows_multipath"] = LegacyCheckDefinition( + name="windows_multipath", parse_function=parse_windows_multipath, service_name="Multipath", discovery_function=inventory_windows_multipath, diff --git a/cmk/base/legacy_checks/winperf.py b/cmk/base/legacy_checks/winperf.py index 419a45a9b9f..244cea2cb66 100644 --- a/cmk/base/legacy_checks/winperf.py +++ b/cmk/base/legacy_checks/winperf.py @@ -120,11 +120,13 @@ def parse_winperf(string_table: StringTable) -> StringTable: check_info["winperf"] = LegacyCheckDefinition( + name="winperf", parse_function=parse_winperf, ) check_info["winperf.cpuusage"] = LegacyCheckDefinition( + name="winperf_cpuusage", service_name="CPU Usage", sections=["winperf"], discovery_function=inventory_win_cpuusage, @@ -132,6 +134,7 @@ def parse_winperf(string_table: StringTable) -> StringTable: ) check_info["winperf.diskstat"] = LegacyCheckDefinition( + name="winperf_diskstat", service_name="Disk IO", sections=["winperf"], discovery_function=inventory_win_diskstat, diff --git a/cmk/base/legacy_checks/winperf_mem.py b/cmk/base/legacy_checks/winperf_mem.py index 831a91a1127..6dfbfecd9a3 100644 --- a/cmk/base/legacy_checks/winperf_mem.py +++ b/cmk/base/legacy_checks/winperf_mem.py @@ -85,6 +85,7 @@ def parse_winperf_mem(string_table: StringTable) -> StringTable: check_info["winperf_mem"] = LegacyCheckDefinition( + name="winperf_mem", parse_function=parse_winperf_mem, service_name="Memory Pages", discovery_function=inventory_winperf_mem, diff --git a/cmk/base/legacy_checks/winperf_ts_sessions.py b/cmk/base/legacy_checks/winperf_ts_sessions.py index 3cea686291b..25cc9766528 100644 --- a/cmk/base/legacy_checks/winperf_ts_sessions.py +++ b/cmk/base/legacy_checks/winperf_ts_sessions.py @@ -61,6 +61,7 @@ def parse_winperf_ts_sessions(string_table: StringTable) -> StringTable: check_info["winperf_ts_sessions"] = LegacyCheckDefinition( + name="winperf_ts_sessions", parse_function=parse_winperf_ts_sessions, service_name="Sessions", discovery_function=inventory_winperf_ts_sessions, diff --git a/cmk/base/legacy_checks/wmi_webservices.py b/cmk/base/legacy_checks/wmi_webservices.py index e8a8d1d630c..4b14f7ce88a 100644 --- a/cmk/base/legacy_checks/wmi_webservices.py +++ b/cmk/base/legacy_checks/wmi_webservices.py @@ -24,6 +24,7 @@ def discover_wmi_webservices(p): check_info["wmi_webservices"] = LegacyCheckDefinition( + name="wmi_webservices", parse_function=parse_wmi_table, service_name="Web Service %s", discovery_function=discover_wmi_webservices, diff --git a/cmk/base/legacy_checks/wmic_process.py b/cmk/base/legacy_checks/wmic_process.py index da4f46a47fe..5c231c87c51 100644 --- a/cmk/base/legacy_checks/wmic_process.py +++ b/cmk/base/legacy_checks/wmic_process.py @@ -93,6 +93,7 @@ def parse_wmic_process(string_table: StringTable) -> StringTable: check_info["wmic_process"] = LegacyCheckDefinition( + name="wmic_process", parse_function=parse_wmic_process, service_name="Process %s", check_function=check_wmic_process, diff --git a/cmk/base/legacy_checks/wut_webtherm.py b/cmk/base/legacy_checks/wut_webtherm.py index 16c981dc657..a5d9bb12b9f 100644 --- a/cmk/base/legacy_checks/wut_webtherm.py +++ b/cmk/base/legacy_checks/wut_webtherm.py @@ -70,6 +70,7 @@ def check_wut_webtherm(item, params, parsed): check_info["wut_webtherm"] = LegacyCheckDefinition( + name="wut_webtherm", detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.5040.1.2."), fetch=[ SNMPTree( @@ -118,6 +119,7 @@ def check_wut_webtherm_pressure(item, _no_params, parsed): check_info["wut_webtherm.pressure"] = LegacyCheckDefinition( + name="wut_webtherm_pressure", service_name="Pressure %s", sections=["wut_webtherm"], discovery_function=inventory_wut_webtherm_pressure, @@ -146,6 +148,7 @@ def check_wut_webtherm_humidity(item, params, parsed): check_info["wut_webtherm.humidity"] = LegacyCheckDefinition( + name="wut_webtherm_humidity", service_name="Humidity %s", sections=["wut_webtherm"], discovery_function=inventory_wut_webtherm_humidity, diff --git a/cmk/base/modes/__init__.py b/cmk/base/modes/__init__.py index e27145c14ae..17d5b01ca47 100644 --- a/cmk/base/modes/__init__.py +++ b/cmk/base/modes/__init__.py @@ -19,6 +19,8 @@ from cmk.base.config import ConfigCache +from cmk import trace + OptionSpec = str Argument = str OptionName = str @@ -28,6 +30,8 @@ Options = list[tuple[OptionSpec, Argument]] Arguments = list[str] +tracer = trace.get_tracer() + class Modes: def __init__(self) -> None: @@ -52,7 +56,14 @@ def exists(self, opt: OptionName) -> bool: except KeyError: return False - def call(self, opt: str, arg: Argument | None, all_opts: Options, all_args: Arguments) -> int: + def call( + self, + opt: str, + arg: Argument | None, + all_opts: Options, + all_args: Arguments, + trace_context: trace.Context, + ) -> int: mode = self._get(opt) sub_options = mode.get_sub_options(all_opts) @@ -69,7 +80,15 @@ def call(self, opt: str, arg: Argument | None, all_opts: Options, all_args: Argu if handler is None: raise TypeError() - return handler(*handler_args) + with tracer.start_as_current_span( + f"mode[{mode.name()}]", + attributes={ + "cmk.base.mode.name": mode.name(), + "cmk.base.mode.args": repr(handler_args), + }, + context=trace_context, + ): + return handler(*handler_args) def _get(self, opt: str) -> Mode: opt_name = self._strip_dashes(opt) diff --git a/cmk/base/modes/check_mk.py b/cmk/base/modes/check_mk.py index 1a3920a1130..1a63f7a8ac5 100644 --- a/cmk/base/modes/check_mk.py +++ b/cmk/base/modes/check_mk.py @@ -53,6 +53,7 @@ from cmk.utils.structured_data import ( ImmutableTree, load_tree, + make_meta, MutableTree, RawIntervalFromConfig, TreeOrArchiveStore, @@ -130,12 +131,14 @@ from cmk.base.sources import make_parser, SNMPFetcherConfig from cmk.base.utils import register_sigint_handler -from cmk import piggyback +from cmk import piggyback, trace from cmk.agent_based.v1.value_store import set_value_store_manager from cmk.discover_plugins import discover_families, PluginGroup from ._localize import do_localize +tracer = trace.get_tracer() + # TODO: Investigate all modes and try to find out whether or not we can # set needs_checks=False for them. This would save a lot of IO/time for # these modes. @@ -341,7 +344,10 @@ def mode_list_hosts(options: dict, args: list[str]) -> None: # TODO: Does not care about internal group "check_mk" def _list_all_hosts( - config_cache: ConfigCache, ruleset_matcher: RulesetMatcher, hostgroups: list[str], options: dict + config_cache: ConfigCache, + ruleset_matcher: RulesetMatcher, + hostgroups: list[str], + options: dict, ) -> list[HostName]: hosts_config = config_cache.hosts_config hostnames: Iterable[HostName] @@ -470,7 +476,8 @@ def mode_list_checks() -> None: all_check_manuals = { n: man_pages.parse_man_page(n, p) for n, p in man_pages.make_man_page_path_map( - discover_families(raise_errors=cmk.ccc.debug.enabled()), PluginGroup.CHECKMAN.value + discover_families(raise_errors=cmk.ccc.debug.enabled()), + PluginGroup.CHECKMAN.value, ).items() } @@ -827,7 +834,7 @@ def mode_update_dns_cache() -> None: configured_ipv6_addresses=config.ipaddresses, configured_ipv4_addresses=config.ipv6addresses, simulation_mode=config.simulation_mode, - override_dns=HostAddress(config.fake_dns) if config.fake_dns is not None else None, + override_dns=(HostAddress(config.fake_dns) if config.fake_dns is not None else None), ) @@ -965,7 +972,9 @@ def _do_snmpwalk(options: _SNMPWalkOptions, *, backend: SNMPBackend) -> None: # TODO: What about SNMP management boards? try: _do_snmpwalk_on( - options, cmk.utils.paths.snmpwalks_dir + "/" + backend.hostname, backend=backend + options, + cmk.utils.paths.snmpwalks_dir + "/" + backend.hostname, + backend=backend, ) except Exception as e: console.error(f"Error walking {backend.hostname}: {e}", file=sys.stderr) @@ -1527,7 +1536,8 @@ def mode_man(options: Mapping[str, str], args: list[str]) -> None: from cmk.utils import man_pages # pylint: disable=import-outside-toplevel man_page_path_map = man_pages.make_man_page_path_map( - discover_families(raise_errors=cmk.ccc.debug.enabled()), PluginGroup.CHECKMAN.value + discover_families(raise_errors=cmk.ccc.debug.enabled()), + PluginGroup.CHECKMAN.value, ) if not args: man_pages.print_man_page_table(man_page_path_map) @@ -1598,7 +1608,8 @@ def mode_browse_man() -> None: man_pages.print_man_page_browser( man_pages.load_man_page_catalog( - discover_families(raise_errors=cmk.ccc.debug.enabled()), PluginGroup.CHECKMAN.value + discover_families(raise_errors=cmk.ccc.debug.enabled()), + PluginGroup.CHECKMAN.value, ) ) @@ -1645,7 +1656,15 @@ def mode_automation(args: list[str]) -> None: log.logger.addHandler(logging.NullHandler()) log.logger.setLevel(logging.INFO) - sys.exit(automations.automations.execute(args[0], args[1:])) + name, automation_args = args[0], args[1:] + with tracer.start_as_current_span( + f"mode_automation[{name}]", + attributes={ + "cmk.automation.name": name, + "cmk.automation.args": automation_args, + }, + ): + sys.exit(automations.automations.execute(name, automation_args)) modes.register( @@ -1862,7 +1881,9 @@ def register_mode_check_discovery( Mode( long_option="check-discovery", handler_function=partial( - mode_check_discovery, active_check_handler=active_check_handler, keepalive=keepalive + mode_check_discovery, + active_check_handler=active_check_handler, + keepalive=keepalive, ), argument=True, argument_descr="HOSTNAME", @@ -2108,7 +2129,9 @@ def mode_discover(options: _DiscoveryOptions, args: list[str]) -> None: ip_address_of=config.ConfiguredIPLookup( config_cache, error_handler=config.handle_ip_lookup_failure ), - mode=FetchMode.DISCOVERY if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS, + mode=( + FetchMode.DISCOVERY if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS + ), on_error=on_error, selected_sections=selected_sections, simulation_mode=config.simulation_mode, @@ -2126,7 +2149,9 @@ def mode_discover(options: _DiscoveryOptions, args: list[str]) -> None: ): def section_error_handling( - section_name: SectionName, raw_data: Sequence[object], host_name: HostName = hostname + section_name: SectionName, + raw_data: Sequence[object], + host_name: HostName = hostname, ) -> str: return create_section_crash_dump( operation="parsing", @@ -2269,7 +2294,9 @@ def mode_check( ip_address_of=config.ConfiguredIPLookup( config_cache, error_handler=config.handle_ip_lookup_failure ), - mode=FetchMode.CHECKING if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS, + mode=( + FetchMode.CHECKING if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS + ), on_error=OnError.RAISE, selected_sections=selected_sections, simulation_mode=config.simulation_mode, @@ -2352,7 +2379,7 @@ def mode_check( monitoring_core=config.monitoring_core, dry_run=dry_run, host_name=hostname, - perfdata_format="pnp" if config.perfdata_format == "pnp" else "standard", + perfdata_format=("pnp" if config.perfdata_format == "pnp" else "standard"), show_perfdata=options.get("perfdata", False), ), exit_spec=config_cache.exit_code_spec(hostname), @@ -2510,7 +2537,9 @@ def mode_inventory(options: _InventoryOptions, args: list[str]) -> None: ip_address_of=config.ConfiguredIPLookup( config_cache, error_handler=config.handle_ip_lookup_failure ), - mode=FetchMode.INVENTORY if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS, + mode=( + FetchMode.INVENTORY if selected_sections is NO_SELECTION else FetchMode.FORCE_SECTIONS + ), on_error=OnError.RAISE, selected_sections=selected_sections, simulation_mode=config.simulation_mode, @@ -2699,7 +2728,11 @@ def _execute_active_check_inventory( tree_or_archive_store.archive(host_name=host_name) if save_tree_actions.do_save: console.verbose("Save new inventory tree.") - tree_or_archive_store.save(host_name=host_name, tree=result.inventory_tree) + tree_or_archive_store.save( + host_name=host_name, + tree=result.inventory_tree, + meta=make_meta(do_archive=save_tree_actions.do_archive), + ) return result.check_result diff --git a/cmk/base/server_side_calls/__init__.py b/cmk/base/server_side_calls/__init__.py index 31363b81cdd..1327f2989b1 100644 --- a/cmk/base/server_side_calls/__init__.py +++ b/cmk/base/server_side_calls/__init__.py @@ -4,7 +4,7 @@ # conditions defined in the file COPYING, which is part of this source code package. from ._active_checks import ActiveCheck, ActiveServiceData -from ._commons import ConfigSet, SpecialAgentInfoFunctionResult, SSCRules +from ._commons import ConfigSet, ExecutableFinder, SpecialAgentInfoFunctionResult, SSCRules from ._loading import load_active_checks, load_special_agents from ._special_agents import SpecialAgent, SpecialAgentCommandLine @@ -18,4 +18,5 @@ "SpecialAgentInfoFunctionResult", "SSCRules", "ConfigSet", + "ExecutableFinder", ] diff --git a/cmk/base/server_side_calls/_active_checks.py b/cmk/base/server_side_calls/_active_checks.py index bee218b4ba8..bdfcecf678b 100644 --- a/cmk/base/server_side_calls/_active_checks.py +++ b/cmk/base/server_side_calls/_active_checks.py @@ -9,19 +9,18 @@ import cmk.ccc.debug -import cmk.utils.paths from cmk.utils import config_warnings, password_store from cmk.utils.hostaddress import HostName from cmk.utils.servicename import ServiceName -from cmk.discover_plugins import discover_executable, family_libexec_dir, PluginLocation +from cmk.discover_plugins import PluginLocation from cmk.server_side_calls.v1 import ActiveCheckCommand, ActiveCheckConfig, HostConfig from cmk.server_side_calls_backend.config_processing import ( process_configuration_to_parameters, ProxyConfig, ) -from ._commons import ConfigSet, replace_passwords, SSCRules +from ._commons import ConfigSet, ExecutableFinderProtocol, replace_passwords, SSCRules @dataclass(frozen=True) @@ -39,22 +38,24 @@ def __init__( plugins: Mapping[PluginLocation, ActiveCheckConfig], host_name: HostName, host_config: HostConfig, - host_attrs: Mapping[str, str], http_proxies: Mapping[str, Mapping[str, str]], service_name_finalizer: Callable[[ServiceName], ServiceName], stored_passwords: Mapping[str, str], password_store_file: Path, + finder: ExecutableFinderProtocol, + *, + ip_lookup_failed: bool, ): self._plugins = {p.name: p for p in plugins.values()} self._modules = {p.name: l.module for l, p in plugins.items()} self.host_name = host_name self.host_config = host_config - self.host_alias = host_attrs["alias"] - self.host_attrs = host_attrs self._http_proxies = http_proxies self._service_name_finalizer = service_name_finalizer self.stored_passwords = stored_passwords or {} self.password_store_file = password_store_file + self._finder = finder + self._ip_lookup_failed = ip_lookup_failed def get_active_service_data( self, active_checks_rules: Iterable[SSCRules] @@ -95,8 +96,7 @@ def _make_service( proxy_config: ProxyConfig, conf_dict: Mapping[str, object], ) -> ActiveServiceData: - if self.host_attrs["address"] in ["0.0.0.0", "::"]: - # these 'magic' addresses indicate that the lookup failed :-( + if self._ip_lookup_failed: executable = "check_always_crit" arguments: tuple[str, ...] = ( "'Failed to lookup IP address and no explicit IP address configured'", @@ -115,7 +115,7 @@ def _make_service( ), ) - detected_executable = _autodetect_plugin(executable, self._modules.get(active_check.name)) + detected_executable = self._finder(executable, self._modules.get(active_check.name)) return ActiveServiceData( plugin_name=active_check.name, @@ -153,15 +153,3 @@ def _deduplicate_service_descriptions( """ seen: dict[ServiceName, ActiveServiceData] = {} return [seen.setdefault(s.description, s) for s in services if s.description not in seen] - - -def _autodetect_plugin(command: str, module_name: str | None) -> str: - libexec_paths = (family_libexec_dir(module_name),) if module_name else () - nagios_paths = ( - cmk.utils.paths.local_lib_dir / "nagios/plugins", - Path(cmk.utils.paths.lib_dir, "nagios/plugins"), - ) - if (full_path := discover_executable(command, *libexec_paths, *nagios_paths)) is None: - return command - - return str(full_path) diff --git a/cmk/base/server_side_calls/_commons.py b/cmk/base/server_side_calls/_commons.py index bd3c7bc0f2f..3aeb220fa6c 100644 --- a/cmk/base/server_side_calls/_commons.py +++ b/cmk/base/server_side_calls/_commons.py @@ -12,6 +12,7 @@ from cmk.utils.hostaddress import HostAddress, HostName from cmk.utils.servicename import ServiceName +from cmk.discover_plugins import discover_executable, family_libexec_dir from cmk.server_side_calls.v1 import Secret CheckCommandArguments = Iterable[int | float | str | tuple[str, str, str]] @@ -38,7 +39,7 @@ class ActiveCheckError(Exception): # or agent pass -def commandline_arguments( +def legacy_commandline_arguments( hostname: HostName, description: ServiceName | None, commandline_args: SpecialAgentInfoFunctionResult, @@ -176,3 +177,16 @@ def replace_macros(string: str, macros: Mapping[str, str]) -> str: for macro, replacement in macros.items(): string = string.replace(macro, str(replacement)) return string + + +ExecutableFinderProtocol = Callable[[str, str | None], str] + + +class ExecutableFinder: + def __init__(self, local_search_path: Path, shipped_search_path: Path): + self._additional_search_paths = (local_search_path, shipped_search_path) + + def __call__(self, executable: str, module: str | None) -> str: + libexec_paths = () if module is None else (family_libexec_dir(module),) + full_path = discover_executable(executable, *libexec_paths, *self._additional_search_paths) + return str(full_path) if full_path else executable diff --git a/cmk/base/server_side_calls/_special_agents.py b/cmk/base/server_side_calls/_special_agents.py index 2de5ee7a803..01359774c00 100644 --- a/cmk/base/server_side_calls/_special_agents.py +++ b/cmk/base/server_side_calls/_special_agents.py @@ -7,13 +7,10 @@ from dataclasses import dataclass from pathlib import Path -import cmk.ccc.debug - -import cmk.utils.paths -from cmk.utils import config_warnings, password_store +from cmk.utils import password_store from cmk.utils.hostaddress import HostAddress, HostName -from cmk.discover_plugins import discover_executable, family_libexec_dir, PluginLocation +from cmk.discover_plugins import PluginLocation from cmk.server_side_calls.v1 import HostConfig, SpecialAgentConfig from cmk.server_side_calls_backend.config_processing import ( process_configuration_to_parameters, @@ -21,8 +18,9 @@ ) from ._commons import ( - commandline_arguments, + ExecutableFinderProtocol, InfoFunc, + legacy_commandline_arguments, replace_macros, replace_passwords, SpecialAgentInfoFunctionResult, @@ -54,6 +52,7 @@ def __init__( http_proxies: Mapping[str, Mapping[str, str]], stored_passwords: Mapping[str, str], password_store_file: Path, + finder: ExecutableFinderProtocol, ): self._plugins = {p.name: p for p in plugins.values()} self._modules = {p.name: l.module for l, p in plugins.items()} @@ -65,26 +64,18 @@ def __init__( self._http_proxies = http_proxies self.stored_passwords = stored_passwords self.password_store_file = password_store_file + self._finder = finder - def _make_source_path(self, agent_name: str) -> Path | str: - file_name = f"agent_{agent_name}" - - libexec_paths = ( - (family_libexec_dir(self._modules[agent_name]),) if agent_name in self._modules else () - ) - nagios_paths = ( - cmk.utils.paths.local_agents_dir / "special", - Path(cmk.utils.paths.agents_dir, "special"), - ) - return discover_executable(file_name, *libexec_paths, *nagios_paths) or file_name + def _make_source_path(self, agent_name: str) -> str: + return self._finder(f"agent_{agent_name}", self._modules.get(agent_name)) - def _make_special_agent_cmdline( + def _make_legacy_special_agent_cmdline( self, agent_name: str, agent_configuration: SpecialAgentInfoFunctionResult, ) -> str: path = self._make_source_path(agent_name) - args = commandline_arguments( + args = legacy_commandline_arguments( self.host_name, None, agent_configuration, @@ -98,7 +89,7 @@ def _iter_legacy_commands( ) -> Iterator[SpecialAgentCommandLine]: agent_configuration = info_func(params, self.host_name, self.host_address) - cmdline = self._make_special_agent_cmdline( + cmdline = self._make_legacy_special_agent_cmdline( agent_name, agent_configuration, ) @@ -132,16 +123,9 @@ def _iter_commands( def iter_special_agent_commands( self, agent_name: str, params: Mapping[str, object] | object ) -> Iterator[SpecialAgentCommandLine]: - try: - if (info_func := self._legacy_plugins.get(agent_name)) is not None: - yield from self._iter_legacy_commands(agent_name, info_func, params) - - if (special_agent := self._plugins.get(agent_name.replace("agent_", ""))) is not None: - params = _ensure_mapping_str_object(params) - yield from self._iter_commands(special_agent, params) - except Exception as e: - if cmk.ccc.debug.enabled(): - raise - config_warnings.warn( - f"Config creation for special agent {agent_name} failed on {self.host_name}: {e}" - ) + if (info_func := self._legacy_plugins.get(agent_name)) is not None: + yield from self._iter_legacy_commands(agent_name, info_func, params) + + if (special_agent := self._plugins.get(agent_name.replace("agent_", ""))) is not None: + params = _ensure_mapping_str_object(params) + yield from self._iter_commands(special_agent, params) diff --git a/cmk/checkengine/checking/__init__.py b/cmk/checkengine/checking/__init__.py index 001be054c84..026bb6a8b70 100644 --- a/cmk/checkengine/checking/__init__.py +++ b/cmk/checkengine/checking/__init__.py @@ -9,6 +9,7 @@ CheckPlugin, CheckPluginName, ConfiguredService, + merge_enforced_services, ServiceConfigurer, ServiceID, ) @@ -24,5 +25,6 @@ "execute_checkmk_checks", "make_timing_results", "ServiceConfigurer", + "merge_enforced_services", "ServiceID", ] diff --git a/cmk/checkengine/checking/_checking.py b/cmk/checkengine/checking/_checking.py index a264fb1780d..86f2f13a43d 100644 --- a/cmk/checkengine/checking/_checking.py +++ b/cmk/checkengine/checking/_checking.py @@ -17,7 +17,7 @@ from cmk.utils.resulttype import Result from cmk.utils.sectionname import SectionMap, SectionName from cmk.utils.servicename import ServiceName -from cmk.utils.structured_data import TreeStore +from cmk.utils.structured_data import make_meta, TreeStore from cmk.utils.timeperiod import check_timeperiod, TimeperiodName from cmk.snmplib import SNMPRawData @@ -140,7 +140,11 @@ def _do_inventory_actions_during_checking_for( ) if status_data_tree: - tree_store.save(host_name=host_name, tree=status_data_tree) + tree_store.save( + host_name=host_name, + tree=status_data_tree, + meta=make_meta(do_archive=False), + ) class PluginState(NamedTuple): diff --git a/cmk/checkengine/checking/_plugin.py b/cmk/checkengine/checking/_plugin.py index b2503b15878..d86b6361223 100644 --- a/cmk/checkengine/checking/_plugin.py +++ b/cmk/checkengine/checking/_plugin.py @@ -5,11 +5,13 @@ from __future__ import annotations +from collections import defaultdict from collections.abc import Callable, Iterable, Mapping, Sequence from dataclasses import dataclass from typing import Final, NamedTuple, Protocol -from cmk.utils.hostaddress import HostName +from cmk.utils.hostaddress import HostAddress, HostName +from cmk.utils.parameters import merge_parameters from cmk.utils.rulesets import RuleSetName from cmk.utils.servicename import Item, ServiceName from cmk.utils.validatedstr import ValidatedString @@ -25,6 +27,7 @@ "CheckPluginName", "ConfiguredService", "ServiceConfigurer", + "merge_enforced_services", "ServiceID", "AutocheckEntryProtocol", ] @@ -160,3 +163,32 @@ class CheckPlugin: default_parameters: Mapping[str, object] | None ruleset_name: RuleSetName | None discovery_ruleset_name: RuleSetName | None + + +def merge_enforced_services( + services: Mapping[HostAddress, Mapping[ServiceID, tuple[object, ConfiguredService]]], + appears_on_cluster: Callable[[HostAddress, ServiceName], bool], +) -> Iterable[ConfiguredService]: + """Aggregate services from multiple nodes""" + entries_by_id: dict[ServiceID, list[ConfiguredService]] = defaultdict(list) + for node, node_services in services.items(): + for sid, (_, service) in node_services.items(): + if appears_on_cluster(node, service.description): + entries_by_id[sid].append(service) + + return [ + ConfiguredService( + check_plugin_name=sid[0], + item=sid[1], + description=entries[0].description, + parameters=TimespecificParameters( + [ps for entry in entries for ps in entry.parameters.entries] + ), + # For consistency we merge the following two fields. At the time of writing, they are + # always empty for enforced services. + discovered_parameters=merge_parameters([e.discovered_parameters for e in entries], {}), + discovered_labels=merge_parameters([e.discovered_labels for e in entries], {}), + is_enforced=True, + ) + for sid, entries in entries_by_id.items() + ] diff --git a/cmk/checkengine/discovery/__init__.py b/cmk/checkengine/discovery/__init__.py index 15b10fd02c6..9421575a259 100644 --- a/cmk/checkengine/discovery/__init__.py +++ b/cmk/checkengine/discovery/__init__.py @@ -10,6 +10,7 @@ AutochecksManager, AutochecksStore, DiscoveredLabelsCache, + merge_cluster_autochecks, remove_autochecks_of_host, set_autochecks_for_effective_host, set_autochecks_of_cluster, @@ -62,4 +63,5 @@ "set_autochecks_of_cluster", "set_autochecks_of_real_hosts", "set_autochecks_for_effective_host", + "merge_cluster_autochecks", ] diff --git a/cmk/checkengine/discovery/_autochecks.py b/cmk/checkengine/discovery/_autochecks.py index d329c6809b1..04dcce5689a 100644 --- a/cmk/checkengine/discovery/_autochecks.py +++ b/cmk/checkengine/discovery/_autochecks.py @@ -5,6 +5,7 @@ from __future__ import annotations import ast +from collections import defaultdict from collections.abc import Callable, Iterable, Mapping, Sequence from pathlib import Path from typing import NamedTuple, TypedDict @@ -14,7 +15,7 @@ import cmk.utils.paths from cmk.utils.hostaddress import HostName -from cmk.utils.labels import ServiceLabel +from cmk.utils.labels import Labels from cmk.utils.servicename import Item, ServiceName from cmk.checkengine.checking import CheckPluginName, ConfiguredService, ServiceID @@ -141,6 +142,33 @@ def clear(self): pass +def merge_cluster_autochecks( + autochecks: Mapping[HostName, Sequence[AutocheckEntry]], + appears_on_cluster: Callable[[HostName, ServiceID], bool], +) -> Sequence[AutocheckEntry]: + # filter for cluster and flatten: + entries = [ + e + for node_name, entries in autochecks.items() + for e in entries + if appears_on_cluster(node_name, e.id()) + ] + + # group by service id and reverse order to make the first node win in merging + entries_by_id: dict[ServiceID, list[AutocheckEntry]] = defaultdict(list) + for entry in entries: + entries_by_id[entry.id()].insert(0, entry) + + return [ + AutocheckEntry( + *id, + parameters={k: v for e in entries for k, v in e.parameters.items()}, + service_labels={k: v for e in entries for k, v in e.service_labels.items()}, + ) + for id, entries in entries_by_id.items() + ] + + class AutochecksManager: """Read autochecks from the configuration @@ -333,33 +361,90 @@ def newer(discovered_item: DiscoveredItem[AutocheckEntry]) -> AutocheckEntry: class DiscoveredLabelsCache: - def __init__(self, get_autochecks: Callable[[HostName], Iterable[AutocheckEntry]]) -> None: + """Cache for discovered labels of services + + This is insane. + + We need this because we insist on looking up the labels of a service by its name. + Discovered labels are attached to the autocheck entry, which is identified by the + service ID (check plugin name and item). + We read all of the autochecks, compute all the service names, and then see if one + matches. + + Ironically, at the start we already knew the service ID. We just forgot about it. + """ + + def __init__( + self, + clusters: Mapping[HostName, Sequence[HostName]], + get_autochecks: Callable[[HostName], Sequence[AutocheckEntry]], + ) -> None: + self._clusters = clusters self._get_autochecks = get_autochecks - self._discovered_labels_of: dict[ - HostName, dict[ServiceName, Mapping[str, ServiceLabel]] - ] = {} + self._discovered_labels_of: dict[HostName, Mapping[ServiceName, Labels]] = {} def discovered_labels_of( self, hostname: HostName, service_desc: ServiceName, get_service_description: GetServiceDescription, - ) -> Mapping[str, ServiceLabel]: + get_effective_host: GetEffectiveHost, + ) -> Labels: # NOTE: this returns an empty labels object for non-existing services - if (loaded_labels := self._discovered_labels_of.get(hostname)) is not None: - return loaded_labels.get(service_desc, {}) - - hosts_labels = self._discovered_labels_of.setdefault(hostname, {}) - # Only read the raw autochecks here, do not compute the effective - # check parameters. The latter would involve ruleset matching which - # in turn would require already computed labels. - for autocheck_entry in self._get_autochecks(hostname): - hosts_labels[ - get_service_description( - hostname, autocheck_entry.check_plugin_name, autocheck_entry.item - ) - ] = {n: ServiceLabel(n, v) for n, v in autocheck_entry.service_labels.items()} - - if (labels := hosts_labels.get(service_desc)) is not None: - return labels - return {} + if (hosts_service_labels := self._discovered_labels_of.get(hostname)) is None: + hosts_service_labels = self._discovered_labels_of.setdefault( + hostname, + self._get_hosts_discovered_service_labels( + hostname, + get_service_description, + get_effective_host, + ), + ) + + return hosts_service_labels.get(service_desc, {}) + + def _get_hosts_discovered_service_labels( + self, + host_name: HostName, + get_service_description: GetServiceDescription, + get_effective_host: GetEffectiveHost, + ) -> Mapping[ServiceName, Labels]: + return ( + self._get_real_hosts_discovered_service_labels(host_name, get_service_description) + if (nodes := self._clusters.get(host_name)) is None + else self._get_clusters_discovered_service_labels( + host_name, nodes, get_service_description, get_effective_host + ) + ) + + def _get_real_hosts_discovered_service_labels( + self, + node_name: HostName, + get_service_description: GetServiceDescription, + ) -> Mapping[ServiceName, Labels]: + return { + get_service_description( + node_name, autocheck_entry.check_plugin_name, autocheck_entry.item + ): autocheck_entry.service_labels + for autocheck_entry in self._get_autochecks(node_name) + } + + def _get_clusters_discovered_service_labels( + self, + cluster_name: HostName, + nodes: Sequence[HostName], + get_service_description: GetServiceDescription, + get_effective_host: GetEffectiveHost, + ) -> Mapping[ServiceName, Labels]: + return { + get_service_description( + cluster_name, autocheck_entry.check_plugin_name, autocheck_entry.item + ): autocheck_entry.service_labels + for autocheck_entry in merge_cluster_autochecks( + {node: self._get_autochecks(node) for node in nodes}, + lambda node_name, service_id: ( + get_effective_host(node_name, get_service_description(node_name, *service_id)) + == cluster_name + ), + ) + } diff --git a/cmk/checkengine/discovery/_autodiscovery.py b/cmk/checkengine/discovery/_autodiscovery.py index 6f065ec64e0..06d92e6d472 100644 --- a/cmk/checkengine/discovery/_autodiscovery.py +++ b/cmk/checkengine/discovery/_autodiscovery.py @@ -41,6 +41,7 @@ AutocheckServiceWithNodes, AutochecksStore, DiscoveredService, + merge_cluster_autochecks, remove_autochecks_of_host, set_autochecks_of_cluster, set_autochecks_of_real_hosts, @@ -737,29 +738,24 @@ def _node_service_source( return "clustered_new" -def _reclassify_disabled_items( - host_name: HostName, - services: ServicesTable[_Transition], - ignore_service: Callable[[HostName, ServiceName], bool], - ignore_plugin: Callable[[HostName, CheckPluginName], bool], - get_service_description: Callable[[HostName, CheckPluginName, Item], ServiceName], -) -> Iterable[tuple[ServiceID, ServicesTableEntry]]: - """Handle disabled services -> 'ignored'""" - yield from ( - ( - DiscoveredService.id(service.autocheck), - ServicesTableEntry( - transition="ignored", - autocheck=service.autocheck, - hosts=[host_name], - ), - ) - for service in services.values() - if ignore_service( - host_name, get_service_description(host_name, *DiscoveredService.id(service.autocheck)) +def _make_cluster_table( + entries: QualifiedDiscovery[AutocheckEntry], + node_tables: Mapping[HostName, ServicesTable[_Transition]], + is_ignored_on_cluster: Callable[[ServiceID], bool], +) -> ServicesTable[_Transition]: + return { + sid: ServicesTableEntry( + transition="ignored" if is_ignored_on_cluster(sid) else service_transition, + autocheck=entry, + hosts=[ + hn + for hn, entries in node_tables.items() + if sid in entries and entries[sid].autocheck.new is not None + ], ) - or ignore_plugin(host_name, DiscoveredService.check_plugin_name(service.autocheck)) - ) + for service_transition, entry in entries.chain_with_transition() + for sid in (DiscoveredService.id(entry),) + } def _group_by_transition( @@ -785,246 +781,58 @@ def _get_cluster_services( get_effective_host: Callable[[HostName, ServiceName], HostName], get_service_description: Callable[[HostName, CheckPluginName, Item], ServiceName], ) -> dict[HostName, ServicesTable[_Transition]]: - cluster_items: dict[ - HostName, ServicesTable[_Transition] - ] = {} # actually _BasicTransition but typing... - cluster_items[host_name] = {} + # should/can we move these up the stack? + def is_ignored(hn: HostName, service_id: ServiceID, service_description: ServiceName) -> bool: + if ignore_plugin(hn, service_id[0]): + return True + return ignore_service(hn, service_description) + + def appears_on_cluster(hn: HostName, service_id: ServiceID) -> bool: + service_description = get_service_description(hn, *service_id) + return ( + not is_ignored(hn, service_id, service_description) + and get_effective_host(hn, service_description) == host_name + ) - for node in cluster_nodes: - entries = analyse_services( + nodes_discovery_results = { + node: analyse_services( existing_services=existing_services[node], discovered_services=discovered_services[node], run_plugin_names=EVERYTHING, forget_existing=False, keep_vanished=False, ) - - cluster_items[node] = { - **make_table( - node, - entries, - ignore_service=ignore_service, - ignore_plugin=ignore_plugin, - get_effective_host=get_effective_host, - get_service_description=get_service_description, - ) - } - for check_source, entry in entries.chain_with_transition(): - cluster_items[host_name].update( - _cluster_service_entry( - node_transition=check_source, - host_name=host_name, - node_name=node, - services_cluster=get_effective_host( - node, get_service_description(node, *DiscoveredService.id(entry)) - ), - entry=entry, - current_recorded_entry=cluster_items[host_name].get( - DiscoveredService.id(entry) - ), - ) - ) - cluster_items[host_name].update( - _reclassify_disabled_items( - host_name, - cluster_items[host_name], - ignore_service, - ignore_plugin, - get_service_description, + for node in cluster_nodes + } + node_tables = { + hn: make_table( + hn, + entries, + ignore_service=ignore_service, + ignore_plugin=ignore_plugin, + get_effective_host=get_effective_host, + get_service_description=get_service_description, ) + for hn, entries in nodes_discovery_results.items() + } + clusters_discovery_result = QualifiedDiscovery( + preexisting=merge_cluster_autochecks( + {hn: q.preexisting for hn, q in nodes_discovery_results.items()}, + appears_on_cluster, + ), + current=merge_cluster_autochecks( + {hn: q.current for hn, q in nodes_discovery_results.items()}, + appears_on_cluster, + ), ) - return cluster_items - - -def _cluster_service_entry( - *, - node_transition: _BasicTransition, - host_name: HostName, - node_name: HostName, - services_cluster: HostName, - entry: DiscoveredItem[AutocheckEntry], - current_recorded_entry: ServicesTableEntry[_Transition] | None, -) -> Iterable[tuple[ServiceID, ServicesTableEntry[_Transition]]]: - """ - The purpose of this function is to determine the service transition (and autocheck) in a - cumulative way by going through all nodes where the service is present - - To keep in mind: - * the order of the nodes is always the same - - Variables: - * entry: - the service representation of the node we are currently investigating - * current_recorded_entry: - the cumulative service representation based on all previously iterated nodes - - Example for understanding: - * cluster consists of 2 nodes: node1 and node2 - * node1 has a service with transition "vanished" - * node2 has a service with transition "new" - * the order of nodes is always the same: first we inspect node1 and then node2 - * from a cluster perspective the service is neither new nor vanished - * vanished assumes that the service existed before in the previous run - * new assumes that the service does still exist in the current run - --> from a cluster perspective it is therefore changed/unchanged it only moved from one - node to another - - Service labels for clustered services: - * cluster service should inherit the labels of services from all of its nodes - * label values take priority according to the order of the nodes: first come first serve - * we assume that the order of the node never changes - * we must merge labels for both the new and old autochecks - - """ - if host_name != services_cluster: - return # not part of this host - - if current_recorded_entry is None: - # first encounter of the service - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=node_transition, - autocheck=entry, - hosts=[node_name], + return { + host_name: _make_cluster_table( + clusters_discovery_result, + node_tables, + is_ignored_on_cluster=lambda sid: is_ignored( + host_name, sid, get_service_description(host_name, *sid) ), - ) - return - - nodes_with_service = current_recorded_entry.hosts - if node_name not in nodes_with_service: - nodes_with_service.append(node_name) - - existing_autocheck_entry = current_recorded_entry.autocheck - accumulated_transition = current_recorded_entry.transition - match accumulated_transition, node_transition: - case "unchanged" | "changed", _not_relevant: - # unchanged/changed always preconditions a service's preexistence - # we only update the labels - assert existing_autocheck_entry.new is not None - assert existing_autocheck_entry.previous is not None - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=accumulated_transition, - autocheck=DiscoveredItem[AutocheckEntry]( - new=_autocheck_with_merged_labels(existing_autocheck_entry.new, entry.new), - previous=_autocheck_with_merged_labels( - existing_autocheck_entry.previous, entry.previous - ), - ), - hosts=nodes_with_service, - ), - ) - return - case "new", "unchanged" | "changed" | "vanished": - # turns out the service already existed and is not really new - # Understanding example: - # Current run: node1 (new service), node2 (unchanged service --> existed before) - # --> have to compare new service state to previous state of node2 service due to next - # run, if we simply take node2 service state (e.g. unchanged), then we potentially jump - # over any potential changes relative to the next run - # Next run: node1 (unchanged service), node2 (unchanged service) - # --> node1 service will be taken (first node appearance wins) - assert existing_autocheck_entry.new is not None - assert entry.previous is not None - assert existing_autocheck_entry.new is not None - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=( - "changed" - if _changed_service(existing_autocheck_entry.new, entry.previous) - else "unchanged" - ), - autocheck=DiscoveredItem[AutocheckEntry]( - new=_autocheck_with_merged_labels(existing_autocheck_entry.new, entry.new), - previous=existing_autocheck_entry.previous, - ), - hosts=nodes_with_service, - ), - ) - case "new", "new": - # still new, first new node appearance wins so we keep the existing entry - # we only update the labels of the new entry - assert existing_autocheck_entry.new is not None - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=accumulated_transition, - autocheck=DiscoveredItem[AutocheckEntry]( - new=_autocheck_with_merged_labels(existing_autocheck_entry.new, entry.new), - previous=existing_autocheck_entry.previous, - ), - hosts=nodes_with_service, - ), - ) - return - case "vanished", "unchanged" | "changed" | "new": - # turns out the service is not vanished but moved to another node or was already - # present before - assert current_recorded_entry.autocheck.previous is not None - assert entry.new is not None - assert existing_autocheck_entry.previous is not None - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=( - "changed" - if _changed_service(current_recorded_entry.autocheck.previous, entry.new) - else "unchanged" - ), - autocheck=DiscoveredItem[AutocheckEntry]( - new=entry.new, - previous=_autocheck_with_merged_labels( - existing_autocheck_entry.previous, entry.previous - ), - ), - hosts=nodes_with_service, - ), - ) - case "vanished", "vanished": - # still vanished, first vanished node appearance wins so we keep the existing entry but - # look for new labels - assert existing_autocheck_entry.previous is not None - yield ( - DiscoveredService.id(entry), - ServicesTableEntry( - transition=accumulated_transition, - autocheck=DiscoveredItem[AutocheckEntry]( - new=existing_autocheck_entry.new, - previous=_autocheck_with_merged_labels( - existing_autocheck_entry.previous, entry.previous - ), - ), - hosts=nodes_with_service, - ), - ) - return - - -def _autocheck_with_merged_labels( - governing_autocheck: AutocheckEntry, completing_autocheck: AutocheckEntry | None -) -> AutocheckEntry: - """Merge service labels of two autochecks - - The service labels of the preceding autocheck are merged with the service labels of the current - where the first appearance of a label wins. - """ - if completing_autocheck is None: - return governing_autocheck - - return AutocheckEntry( - check_plugin_name=governing_autocheck.check_plugin_name, - item=governing_autocheck.item, - parameters=governing_autocheck.parameters, - service_labels={ - **completing_autocheck.service_labels, - **governing_autocheck.service_labels, - }, - ) - - -def _changed_service(service: AutocheckEntry, compare_service: AutocheckEntry) -> bool: - return service.comparator() != compare_service.comparator() + ), + **node_tables, + } diff --git a/cmk/checkengine/discovery/_utils.py b/cmk/checkengine/discovery/_utils.py index f2174d23531..afd20519cba 100644 --- a/cmk/checkengine/discovery/_utils.py +++ b/cmk/checkengine/discovery/_utils.py @@ -137,6 +137,9 @@ def __init__( preexisting: Sequence[_DiscoveredItem], current: Sequence[_DiscoveredItem], ) -> None: + self.preexisting: Final = preexisting + self.current: Final = current + current_dict = {v.id(): v for v in current} preexisting_dict = {v.id(): v for v in preexisting} @@ -181,6 +184,7 @@ def new(self) -> list[_DiscoveredItem]: @property def present(self) -> list[_DiscoveredItem]: + # not quite like 'current'! return self.old + self.new def chain_with_transition( diff --git a/cmk/fetchers/_piggyback.py b/cmk/fetchers/_piggyback.py index 4b53534cfbf..712c7d03fff 100644 --- a/cmk/fetchers/_piggyback.py +++ b/cmk/fetchers/_piggyback.py @@ -14,7 +14,7 @@ from cmk.utils.log import VERBOSE from cmk.utils.paths import omd_root -from cmk.piggyback import get_piggyback_raw_data, PiggybackMessage +from cmk.piggyback import get_messages_for, PiggybackMessage from cmk.piggyback.config import Config as PiggybackConfig from ._abstract import Fetcher, Mode @@ -117,4 +117,4 @@ def _get_source_labels_section(self) -> bytearray | bytes: @staticmethod def _raw_data(hostname: HostAddress) -> Sequence[PiggybackMessage]: - return get_piggyback_raw_data(hostname, omd_root) + return get_messages_for(hostname, omd_root) diff --git a/cmk/gui/autocompleters.py b/cmk/gui/autocompleters.py index 152aea9f56b..09f1bd4b100 100644 --- a/cmk/gui/autocompleters.py +++ b/cmk/gui/autocompleters.py @@ -8,9 +8,6 @@ from livestatus import LivestatusColumn, MultiSiteConnection -import cmk.ccc.version as cmk_version - -from cmk.utils import paths from cmk.utils.regex import regex from cmk.gui import sites @@ -96,25 +93,6 @@ def monitored_hostname_autocompleter(value: str, params: dict) -> Choices: return _sorted_unique_lq(query, 200, value, params) -def sites_autocompleter( - value: str, params: dict, sites_options: Callable[[], list[tuple[str, str]]] -) -> Choices: - """Return the matching list of dropdown choices - Called by the webservice with the current input field value and the completions_params to get the list of choices - """ - - choices: Choices = [v for v in sites_options() if _matches_id_or_title(value, v)] - # CME sort order is already in place - if cmk_version.edition(paths.omd_root) is not cmk_version.Edition.CME: - choices.sort(key=lambda a: a[1].lower()) - - # This part should not exists as the optional(not enforce) would better be not having the filter at all - if not params.get("strict"): - empty_choice: Choices = [("", "All Sites")] - choices = empty_choice + choices - return choices - - def hostgroup_autocompleter(value: str, params: dict) -> Choices: """Return the matching list of dropdown choices Called by the webservice with the current input field value and the completions_params to get the list of choices diff --git a/cmk/gui/background_job/_app.py b/cmk/gui/background_job/_app.py index fc95673fd96..d68773ac3fd 100644 --- a/cmk/gui/background_job/_app.py +++ b/cmk/gui/background_job/_app.py @@ -6,19 +6,19 @@ import os -from flask import Flask - +from cmk.gui.features import Features +from cmk.gui.flask_app import CheckmkFlaskApp from cmk.gui.http import Request, Response from cmk.gui.session import FileBasedSession -class BackgroundJobFlaskApp(Flask): +class BackgroundJobFlaskApp(CheckmkFlaskApp): request_class = Request response_class = Response - session_interface = FileBasedSession() def __init__( self, + features: Features, static_url_path: str | None = None, static_folder: str | os.PathLike[str] | None = "static", static_host: str | None = None, @@ -31,6 +31,8 @@ def __init__( ): super().__init__( import_name=__name__, + session_interface=FileBasedSession(), + features=features, static_url_path=static_url_path, static_folder=static_folder, static_host=static_host, diff --git a/cmk/gui/background_job/_process.py b/cmk/gui/background_job/_process.py index 4c1a0f37b12..1dbe73a4cc0 100644 --- a/cmk/gui/background_job/_process.py +++ b/cmk/gui/background_job/_process.py @@ -27,6 +27,7 @@ from cmk.ccc import store from cmk.ccc.exceptions import MKTerminate from cmk.ccc.site import get_omd_config, omd_site +from cmk.ccc.version import edition from cmk.utils import paths from cmk.utils.log import VERBOSE @@ -34,6 +35,7 @@ from cmk.gui import log from cmk.gui.crash_handler import create_gui_crash_report +from cmk.gui.features import features_registry from cmk.gui.i18n import _ from cmk.gui.session import SuperUserContext, UserContext from cmk.gui.single_global_setting import load_gui_log_levels @@ -148,8 +150,14 @@ def gui_job_context_manager(user: str | None) -> Callable[[], ContextManager[Non @contextmanager def gui_job_context() -> Iterator[None]: _load_ui() + + try: + features = features_registry[str(edition(paths.omd_root))] + except KeyError: + raise ValueError(f"Invalid edition: {edition}") + with ( - BackgroundJobFlaskApp().test_request_context("/"), + BackgroundJobFlaskApp(features).test_request_context("/"), SuperUserContext() if user is None else UserContext(UserId(user)), ): yield None diff --git a/cmk/gui/bi/view.py b/cmk/gui/bi/view.py index 1e8e4d9de1c..9964811ae30 100644 --- a/cmk/gui/bi/view.py +++ b/cmk/gui/bi/view.py @@ -41,7 +41,6 @@ from cmk.gui.utils.escaping import escape_attribute from cmk.gui.utils.html import HTML from cmk.gui.utils.output_funnel import output_funnel -from cmk.gui.utils.speaklater import LazyString from cmk.gui.utils.urls import makeuri, urlencode_vars from cmk.gui.valuespec import DropdownChoice, ValueSpec from cmk.gui.view_utils import CellSpec, CSVExportError @@ -1126,91 +1125,74 @@ def sort_index(self) -> int: return 10 -class CommandFreezeAggregation(Command): - @property - def ident(self) -> str: - return "freeze_aggregation" +def command_freeze_aggregation_render(what: str) -> None: + html.open_div(class_="group") + html.button(_button_name(), _("Freeze selected"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def title(self) -> str: - return _("Freeze aggregations") - @property - def confirm_title(self) -> str: - return _("Freeze aggregation?") - - @property - def confirm_button(self) -> LazyString: - return _l("Freeze") - - @property - def icon_name(self): - return "bi_freeze" - - @property - def is_shortcut(self) -> bool: - return True - - @property - def is_suggested(self) -> bool: - return True - - @property - def permission(self) -> Permission: - return PermissionFreezeAggregation - - @property - def group(self) -> type[CommandGroup]: - return CommandGroupAggregations - - @property - def tables(self) -> list[str]: - return ["aggr"] - - @property - def only_view(self) -> str | None: - """View name to show a view exclusive command for""" - return "aggr_frozen_diff" - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button(self._button_name, _("Freeze selected"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: - return HTML.without_escaping( - _("Affected %s: %s") - % ( - ungettext( - "aggregation", - "aggregations", - len_action_rows, - ), +def command_freeze_aggregation_affected( + len_action_rows: int, cmdtag: Literal["HOST", "SVC"] +) -> HTML: + return HTML.without_escaping( + _("Affected %s: %s") + % ( + ungettext( + "aggregation", + "aggregations", len_action_rows, - ) + ), + len_action_rows, ) + ) - @property - def _button_name(self) -> str: - return "_freeze_aggregations" - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if not request.has_var(self._button_name): - return None +def _button_name() -> str: + return "_freeze_aggregations" - if (compiled_aggregation := row.get("aggr_compiled_aggregation")) is not None: - if compiled_aggregation.frozen_info: - return ( - [compiled_aggregation.frozen_info.based_on_branch_title], - self.confirm_dialog_options(cmdtag, row, len(action_rows)), - ) +def command_freeze_aggregation_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if not request.has_var(_button_name()): return None - def executor(self, command: CommandSpec, site: SiteId | None) -> None: - """Function that is called to execute this action""" - assert isinstance(command, CommandSpecWithoutSite) - (frozen_aggregations_dir / Path(command).name).unlink(missing_ok=True) + if (compiled_aggregation := row.get("aggr_compiled_aggregation")) is not None: + if compiled_aggregation.frozen_info: + return ( + [compiled_aggregation.frozen_info.based_on_branch_title], + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + + return None + + +def command_freeze_aggregation_executor(command: CommandSpec, site: SiteId | None) -> None: + """Function that is called to execute this action""" + assert isinstance(command, CommandSpecWithoutSite) + (frozen_aggregations_dir / Path(command).name).unlink(missing_ok=True) + + +CommandFreezeAggregation = Command( + ident="freeze_aggregation", + title=_l("Freeze aggregations"), + confirm_title=_l("Freeze aggregation?"), + confirm_button=_l("Freeze"), + icon_name="bi_freeze", + is_shortcut=True, + is_suggested=True, + permission=PermissionFreezeAggregation, + group=CommandGroupAggregations, + tables=["aggr"], + only_view="aggr_frozen_diff", + render=command_freeze_aggregation_render, + action=command_freeze_aggregation_action, + affected_output_cb=command_freeze_aggregation_affected, + executor=command_freeze_aggregation_executor, +) diff --git a/cmk/gui/crash_reporting/views.py b/cmk/gui/crash_reporting/views.py index 86229726f50..4316f22c5ce 100644 --- a/cmk/gui/crash_reporting/views.py +++ b/cmk/gui/crash_reporting/views.py @@ -21,10 +21,14 @@ from cmk.gui.permissions import Permission, permission_registry from cmk.gui.type_defs import ColumnName, Row, Rows, SingleInfos, VisualContext from cmk.gui.utils.html import HTML -from cmk.gui.utils.speaklater import LazyString from cmk.gui.utils.urls import makeuri_contextless from cmk.gui.view_utils import CellSpec -from cmk.gui.views.command import Command, CommandActionResult, PermissionSectionAction +from cmk.gui.views.command import ( + Command, + CommandActionResult, + CommandGroupVarious, + PermissionSectionAction, +) from cmk.gui.views.sorter import cmp_simple_number, Sorter from cmk.gui.visuals.filter import Filter @@ -323,59 +327,52 @@ def cmp(self, r1: Row, r2: Row, parameters: Mapping[str, Any] | None) -> int: ) -class CommandDeleteCrashReports(Command): - @property - def ident(self) -> str: - return "delete_crash_reports" - - @property - def title(self) -> str: - return _("Delete crash reports") - - @property - def confirm_title(self) -> str: - return _("Delete crash reports?") - - @property - def confirm_button(self) -> LazyString: - return _l("Delete") - - @property - def permission(self) -> Permission: - return PermissionActionDeleteCrashReport - - @property - def tables(self) -> list[str]: - return ["crash"] - - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: - return HTML.without_escaping( - _("Affected %s: %s") - % ( - ungettext( - "crash report", - "crash reports", - len_action_rows, - ), +def command_delete_crash_report_affected( + len_action_rows: int, cmdtag: Literal["HOST", "SVC"] +) -> HTML: + return HTML.without_escaping( + _("Affected %s: %s") + % ( + ungettext( + "crash report", + "crash reports", len_action_rows, - ) + ), + len_action_rows, ) + ) - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_delete_crash_reports", _("Delete"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - def _action( - self, - cmdtag: Literal["HOST", "SVC"], - spec: str, - row: dict, - row_index: int, - action_rows: Rows, - ) -> CommandActionResult: - if request.has_var("_delete_crash_reports"): - commands = [("DEL_CRASH_REPORT;%s" % row["crash_id"])] - return commands, self.confirm_dialog_options(cmdtag, row, len(action_rows)) - return None +def command_delete_crash_report_render(what: str) -> None: + html.open_div(class_="group") + html.button("_delete_crash_reports", _("Delete"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_delete_crash_report_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: dict, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.has_var("_delete_crash_reports"): + commands = [("DEL_CRASH_REPORT;%s" % row["crash_id"])] + return commands, command.confirm_dialog_options(cmdtag, row, action_rows) + return None + + +CommandDeleteCrashReports = Command( + ident="delete_crash_reports", + title=_l("Delete crash reports"), + confirm_title=_l("Delete crash reports?"), + confirm_button=_l("Delete"), + permission=PermissionActionDeleteCrashReport, + group=CommandGroupVarious, + tables=["crash"], + render=command_delete_crash_report_render, + action=command_delete_crash_report_action, + affected_output_cb=command_delete_crash_report_affected, +) diff --git a/cmk/gui/cre/registration.py b/cmk/gui/cre/registration.py index 82ced4dbcd6..1487852605a 100644 --- a/cmk/gui/cre/registration.py +++ b/cmk/gui/cre/registration.py @@ -5,21 +5,60 @@ """Raw edition and only raw edition specific registrations""" +from cmk.ccc.version import edition + +from cmk.utils import paths + import cmk.gui.graphing._graph_images as graph_images import cmk.gui.graphing._html_render as html_render import cmk.gui.pages -from cmk.gui.i18n import _ +from cmk.gui import hooks, sidebar, visuals +from cmk.gui.background_job import job_registry +from cmk.gui.backup.registration import backup_register +from cmk.gui.custom_icons.registration import custom_icons_register +from cmk.gui.dashboard import dashlet_registry +from cmk.gui.data_source import data_source_registry +from cmk.gui.features import Features, features_registry +from cmk.gui.main_menu import mega_menu_registry from cmk.gui.metrics import PageGraphDashlet, PageHostServiceGraphPopup -from cmk.gui.painter.v0 import painters -from cmk.gui.painter.v0.base import Cell, painter_registry -from cmk.gui.type_defs import Row -from cmk.gui.view_utils import CellSpec +from cmk.gui.mkeventd import registration as mkeventd_registration +from cmk.gui.mkeventd.helpers import save_active_config +from cmk.gui.openapi import endpoint_registry +from cmk.gui.pages import page_registry +from cmk.gui.painter.v0.base import painter_registry +from cmk.gui.permissions import permission_registry, permission_section_registry +from cmk.gui.quick_setup.v0_unstable._registry import quick_setup_registry +from cmk.gui.sidebar import snapin_registry +from cmk.gui.sites import site_choices +from cmk.gui.valuespec import autocompleter_registry from cmk.gui.views import graph -from cmk.gui.wato import notification_parameter_registry, NotificationParameterMail - - -def painter_downtime_recurring_renderer(row: Row, cell: Cell) -> CellSpec: - return "", _("(not supported)") +from cmk.gui.views.command import command_registry +from cmk.gui.views.icon import icon_and_action_registry +from cmk.gui.views.sorter import sorter_registry +from cmk.gui.visuals import default_site_filter_heading_info +from cmk.gui.visuals.filter import filter_registry +from cmk.gui.visuals.info import visual_info_registry +from cmk.gui.wato import ( + default_user_menu_topics, + notification_parameter_registry, + NotificationParameterMail, +) +from cmk.gui.wato import registration as wato_registration +from cmk.gui.watolib.analyze_configuration import ac_test_registry +from cmk.gui.watolib.automation_commands import automation_command_registry +from cmk.gui.watolib.config_domain_name import ( + config_domain_registry, + config_variable_group_registry, + config_variable_registry, + sample_config_generator_registry, +) +from cmk.gui.watolib.config_sync import replication_path_registry +from cmk.gui.watolib.groups import contact_group_usage_finder_registry +from cmk.gui.watolib.main_menu import main_module_registry, main_module_topic_registry +from cmk.gui.watolib.mode import mode_registry +from cmk.gui.watolib.rulespecs import rulespec_group_registry, rulespec_registry +from cmk.gui.watolib.search import match_item_generator_registry +from cmk.gui.watolib.timeperiods import timeperiod_usage_finder_registry def register_pages() -> None: @@ -37,11 +76,95 @@ def register_painters() -> None: painter_registry.register(graph.PainterSvcPnpgraph) painter_registry.register(graph.PainterHostPnpgraph) - painters.PainterDowntimeRecurring.renderer = painter_downtime_recurring_renderer - painter_registry.register(painters.PainterDowntimeRecurring) - def register() -> None: + features_registry.register( + Features( + edition(paths.omd_root), + livestatus_only_sites_postprocess=lambda x: list(x) if x else None, + ) + ) + visuals.register( + page_registry, + visual_info_registry, + filter_registry, + autocompleter_registry, + site_choices, + default_site_filter_heading_info, + ) + sidebar.register( + page_registry, + permission_section_registry, + snapin_registry, + dashlet_registry, + mega_menu_registry, + view_menu_topics=sidebar.default_view_menu_topics, + ) + wato_registration.register( + page_registry, + painter_registry, + sorter_registry, + icon_and_action_registry, + automation_command_registry, + job_registry, + filter_registry, + mode_registry, + quick_setup_registry, + permission_section_registry, + permission_registry, + main_module_topic_registry, + main_module_registry, + rulespec_group_registry, + config_domain_registry, + config_variable_registry, + config_variable_group_registry, + snapin_registry, + match_item_generator_registry, + mega_menu_registry, + ac_test_registry, + contact_group_usage_finder_registry, + notification_parameter_registry, + replication_path_registry, + default_user_menu_topics, + edition_supports_ldap=True, + edition_supports_managing_roles=True, + ) notification_parameter_registry.register(NotificationParameterMail) register_pages() register_painters() + backup_register( + page_registry, + mode_registry, + main_module_registry, + ) + mkeventd_registration.register( + permission_section_registry, + permission_registry, + data_source_registry, + painter_registry, + command_registry, + sorter_registry, + icon_and_action_registry, + config_domain_registry, + sample_config_generator_registry, + mode_registry, + main_module_registry, + config_variable_group_registry, + config_variable_registry, + rulespec_group_registry, + rulespec_registry, + autocompleter_registry, + filter_registry, + notification_parameter_registry, + snapin_registry, + contact_group_usage_finder_registry, + timeperiod_usage_finder_registry, + endpoint_registry, + replication_path_registry, + ) + hooks.register_builtin("mkeventd-activate-changes", save_active_config) + custom_icons_register( + mode_registry, + main_module_registry, + permission_registry, + ) diff --git a/cmk/gui/cron.py b/cmk/gui/cron.py index 1d023626574..0c6058a2112 100644 --- a/cmk/gui/cron.py +++ b/cmk/gui/cron.py @@ -5,6 +5,7 @@ import time from collections.abc import Callable +from functools import partial from pathlib import Path from typing import Any @@ -20,7 +21,7 @@ from cmk.gui.pages import PageRegistry from cmk.gui.session import SuperUserContext -multisite_cronjobs = [] +multisite_cronjobs: list[Callable[[], Any] | partial] = [] def register(page_registry: PageRegistry) -> None: @@ -97,7 +98,9 @@ def page_run_cron() -> None: for cron_job in multisite_cronjobs: try: - job_name = cron_job.__name__ + job_name = ( + cron_job.func.__name__ if isinstance(cron_job, partial) else cron_job.__name__ + ) logger.debug("Starting [%s]", job_name) cron_job() diff --git a/cmk/gui/dashboard/dashlet/dashlets/view.py b/cmk/gui/dashboard/dashlet/dashlets/view.py index 651e3d838d7..95814449910 100644 --- a/cmk/gui/dashboard/dashlet/dashlets/view.py +++ b/cmk/gui/dashboard/dashlet/dashlets/view.py @@ -223,7 +223,11 @@ def _show_view_as_dashlet(self, view_spec: ViewSpec | ViewDashletConfig) -> None view.only_sites = get_only_sites_from_context(context) view.user_sorters = get_user_sorters(view.spec["sorters"], view.row_cells) - process_view(GUIViewRenderer(view, show_buttons=False)) + process_view( + GUIViewRenderer( + view, show_buttons=False, page_menu_dropdowns_callback=lambda x, y, z: None + ) + ) html.close_div() diff --git a/cmk/gui/data_source/datasources.py b/cmk/gui/data_source/datasources.py index c41b22f719b..a460b463579 100644 --- a/cmk/gui/data_source/datasources.py +++ b/cmk/gui/data_source/datasources.py @@ -303,7 +303,7 @@ def keys(self): @property def id_keys(self): - return ["comment_id"] + return ["site", "comment_id"] class DataSourceDowntimes(DataSourceLivestatus): diff --git a/cmk/gui/features.py b/cmk/gui/features.py new file mode 100644 index 00000000000..6257fe57dba --- /dev/null +++ b/cmk/gui/features.py @@ -0,0 +1,26 @@ +#!/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 Callable, Sequence +from dataclasses import dataclass + +from livestatus import SiteId + +from cmk.ccc.plugin_registry import Registry +from cmk.ccc.version import Edition + + +@dataclass(frozen=True) +class Features: + edition: Edition + livestatus_only_sites_postprocess: Callable[[Sequence[SiteId] | None], list[SiteId] | None] + + +class FeaturesRegistry(Registry[Features]): + def plugin_name(self, instance: Features) -> str: + return str(instance.edition) + + +features_registry = FeaturesRegistry() diff --git a/cmk/gui/flask_app.py b/cmk/gui/flask_app.py new file mode 100644 index 00000000000..54347659d78 --- /dev/null +++ b/cmk/gui/flask_app.py @@ -0,0 +1,54 @@ +#!/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. + +import os + +from flask import current_app as current_flask_app +from flask import Flask +from flask.sessions import SessionInterface + +from cmk.gui import http +from cmk.gui.features import Features + + +class CheckmkFlaskApp(Flask): + request_class = http.Request + response_class = http.Response + + def __init__( + self, + import_name: str, + session_interface: SessionInterface, + features: Features, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name, + static_url_path, + static_folder, + static_host, + host_matching, + subdomain_matching, + template_folder, + instance_path, + instance_relative_config, + root_path, + ) + self.session_interface = session_interface + self.features = features + + +def current_app() -> CheckmkFlaskApp: + app = current_flask_app + assert isinstance(app, CheckmkFlaskApp) + return app diff --git a/cmk/gui/form_specs/private/__init__.py b/cmk/gui/form_specs/private/__init__.py index 9e2695b3660..841b64027d2 100644 --- a/cmk/gui/form_specs/private/__init__.py +++ b/cmk/gui/form_specs/private/__init__.py @@ -14,6 +14,8 @@ from .dictionary_extended import DictionaryExtended from .list_extended import ListExtended from .list_of_strings import ListOfStrings +from .monitored_host_extended import MonitoredHostExtended +from .multiple_choice import AdaptiveMultipleChoice, AdaptiveMultipleChoiceLayout from .optional_choice import OptionalChoice from .string_autocompleter import StringAutocompleter from .validators import not_empty @@ -32,4 +34,7 @@ "OptionalChoice", "UnknownFormSpec", "not_empty", + "AdaptiveMultipleChoice", + "AdaptiveMultipleChoiceLayout", + "MonitoredHostExtended", ] diff --git a/cmk/gui/form_specs/private/catalog.py b/cmk/gui/form_specs/private/catalog.py index 92b38d392a8..6ab1e0ded54 100644 --- a/cmk/gui/form_specs/private/catalog.py +++ b/cmk/gui/form_specs/private/catalog.py @@ -8,11 +8,13 @@ from cmk.rulesets.v1 import form_specs from cmk.rulesets.v1.form_specs import Dictionary +from .dictionary_extended import DictionaryExtended + @dataclass(frozen=True, kw_only=True) class Topic: ident: str - dictionary: Dictionary + dictionary: Dictionary | DictionaryExtended @dataclass(frozen=True, kw_only=True) diff --git a/cmk/gui/form_specs/private/monitored_host_extended.py b/cmk/gui/form_specs/private/monitored_host_extended.py new file mode 100644 index 00000000000..5ac5f2cf183 --- /dev/null +++ b/cmk/gui/form_specs/private/monitored_host_extended.py @@ -0,0 +1,13 @@ +#!/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 dataclasses import dataclass + +from cmk.rulesets.v1.form_specs import DefaultValue, FormSpec + + +@dataclass(frozen=True, kw_only=True) +class MonitoredHostExtended(FormSpec[str]): + prefill: DefaultValue[str] diff --git a/cmk/gui/form_specs/private/multiple_choice.py b/cmk/gui/form_specs/private/multiple_choice.py new file mode 100644 index 00000000000..9f887c18c15 --- /dev/null +++ b/cmk/gui/form_specs/private/multiple_choice.py @@ -0,0 +1,21 @@ +#!/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 dataclasses import dataclass +from enum import Enum + +from cmk.rulesets.v1.form_specs._composed import MultipleChoice + + +@dataclass(frozen=True, kw_only=True) +class AdaptiveMultipleChoiceLayout(str, Enum): + auto = "auto" + dual_list = "dual_list" + checkbox_list = "checkbox_list" + + +@dataclass(frozen=True, kw_only=True) +class AdaptiveMultipleChoice(MultipleChoice): + layout: AdaptiveMultipleChoiceLayout = AdaptiveMultipleChoiceLayout.auto diff --git a/cmk/gui/form_specs/private/validators.py b/cmk/gui/form_specs/private/validators.py index 3fa7ce7fc18..d219a0bdfd0 100644 --- a/cmk/gui/form_specs/private/validators.py +++ b/cmk/gui/form_specs/private/validators.py @@ -62,5 +62,10 @@ def __call__(self, value: typing.Any) -> None: raise ValidationError(self.error_msg) -def not_empty() -> LengthInRange: - return LengthInRange(min_value=1, error_msg=Message("An empty value is not allowed here")) +def not_empty(error_msg: Message | None = None) -> LengthInRange: + return LengthInRange( + min_value=1, + error_msg=error_msg + if error_msg is not None + else Message("An empty value is not allowed here"), + ) diff --git a/cmk/gui/form_specs/vue/form_spec_visitor.py b/cmk/gui/form_specs/vue/form_spec_visitor.py index 67e59716be3..4aaae4d548a 100644 --- a/cmk/gui/form_specs/vue/form_spec_visitor.py +++ b/cmk/gui/form_specs/vue/form_spec_visitor.py @@ -16,6 +16,7 @@ from cmk.gui.exceptions import MKUserError from cmk.gui.form_specs.converter import SimplePassword, TransformForLegacyData, Tuple from cmk.gui.form_specs.private import ( + AdaptiveMultipleChoice, Catalog, CommentTextArea, DictionaryExtended, @@ -32,6 +33,7 @@ recompose_dictionary, recompose_host_state, recompose_list, + recompose_multiple_choice, recompose_percentage, recompose_regular_expression, recompose_service_state, @@ -132,7 +134,7 @@ def register_form_specs(): register_visitor_class(DataSize, DataSizeVisitor) register_visitor_class(Catalog, CatalogVisitor) register_visitor_class(ListExtended, ListVisitor) - register_visitor_class(MultipleChoice, MultipleChoiceVisitor) + register_visitor_class(TimeSpan, TimeSpanVisitor) register_visitor_class(TransformForLegacyData, TransformVisitor) register_visitor_class(Tuple, TupleVisitor) @@ -140,6 +142,8 @@ def register_form_specs(): register_visitor_class(SimplePassword, SimplePasswordVisitor) register_visitor_class(StringAutocompleter, StringVisitor) register_visitor_class(ListOfStrings, ListOfStringsVisitor) + register_visitor_class(AdaptiveMultipleChoice, MultipleChoiceVisitor) + register_visitor_class(MultipleChoice, MultipleChoiceVisitor, recompose_multiple_choice) # Recomposed register_visitor_class(String, StringVisitor, recompose_string) diff --git a/cmk/gui/form_specs/vue/shared_type_defs.py b/cmk/gui/form_specs/vue/shared_type_defs.py index 712e499e8be..40ee812b09b 100644 --- a/cmk/gui/form_specs/vue/shared_type_defs.py +++ b/cmk/gui/form_specs/vue/shared_type_defs.py @@ -79,7 +79,7 @@ class DictionaryLayout(str, Enum): @dataclass(kw_only=True) class SingleChoiceElement: - name: Any + name: str title: str @@ -89,6 +89,19 @@ class MultipleChoiceElement: title: str +@dataclass(kw_only=True) +class DualListChoiceI18n: + add: str + remove: str + add_all: str + remove_all: str + available_options: str + selected_options: str + selected: str + no_elements_available: str + no_elements_selected: str + + class CascadingChoiceLayout(str, Enum): vertical = "vertical" horizontal = "horizontal" @@ -147,39 +160,6 @@ class ValidationMessage: invalid_value: Any -@dataclass(kw_only=True) -class FallbackWarningI18n: - title: str - message: str - setup_link_title: str - do_not_show_again_title: str - - -@dataclass(kw_only=True) -class NotificationStatsI18n: - sent_notifications: str - failed_notifications: str - sent_notifications_link_title: str - failed_notifications_link_title: str - - -@dataclass(kw_only=True) -class CoreStatsI18n: - title: str - sites_column_title: str - status_column_title: str - ok_msg: str - warning_msg: str - disabled_msg: str - - -@dataclass(kw_only=True) -class Rule: - i18n: str - count: str - link: str - - @dataclass(kw_only=True) class FormSpec: type: str @@ -261,7 +241,7 @@ class Dictionary(FormSpec): @dataclass(kw_only=True) class SingleChoice(FormSpec): frozen: bool - input_hint: Any + input_hint: str type: str = "single_choice" elements: list[SingleChoiceElement] = field(default_factory=lambda: []) no_elements_text: Optional[str] = None @@ -269,10 +249,17 @@ class SingleChoice(FormSpec): @dataclass(kw_only=True) -class MultipleChoice(FormSpec): - type: str = "multiple_choice" - elements: list[MultipleChoiceElement] = field(default_factory=lambda: []) - show_toggle_all: bool = False +class DualListChoice(FormSpec): + i18n: DualListChoiceI18n + elements: Optional[list[MultipleChoiceElement]] = field(default_factory=lambda: []) + show_toggle_all: Optional[bool] = False + type: str = "dual_list_choice" + + +@dataclass(kw_only=True) +class CheckboxListChoice(FormSpec): + type: str = "checkbox_list_choice" + elements: Optional[list[MultipleChoiceElement]] = field(default_factory=lambda: []) @dataclass(kw_only=True) @@ -398,7 +385,8 @@ class ListOfStrings(FormSpec): Password, DataSize, Catalog, - MultipleChoice, + DualListChoice, + CheckboxListChoice, TimeSpan, Tuple, OptionalChoice, @@ -407,51 +395,7 @@ class ListOfStrings(FormSpec): ] -@dataclass(kw_only=True) -class FallbackWarning: - i18n: FallbackWarningI18n - user_id: str - setup_link: str - do_not_show_again_link: str - - -@dataclass(kw_only=True) -class NotificationStats: - num_sent_notifications: int - num_failed_notifications: int - sent_notification_link: str - failed_notification_link: str - i18n: NotificationStatsI18n - - -@dataclass(kw_only=True) -class CoreStats: - sites: list[str] - i18n: CoreStatsI18n - - -@dataclass(kw_only=True) -class RuleTopic: - i18n: str - rules: list[Rule] - - -@dataclass(kw_only=True) -class RuleSection: - i18n: str - topics: list[RuleTopic] - - -@dataclass(kw_only=True) -class Notifications: - notification_stats: NotificationStats - core_stats: CoreStats - rule_sections: list[RuleSection] - fallback_warning: Optional[FallbackWarning] = None - - @dataclass(kw_only=True) class VueFormspecComponents: components: Optional[Components] = None validation_message: Optional[ValidationMessage] = None - notifications: Optional[Notifications] = None diff --git a/cmk/gui/form_specs/vue/visitors/_registry.py b/cmk/gui/form_specs/vue/visitors/_registry.py index 2ebedc08cae..d3039802785 100644 --- a/cmk/gui/form_specs/vue/visitors/_registry.py +++ b/cmk/gui/form_specs/vue/visitors/_registry.py @@ -7,12 +7,10 @@ from cmk.gui.form_specs.private import UnknownFormSpec from cmk.gui.form_specs.vue.visitors._base import FormSpecVisitor from cmk.gui.form_specs.vue.visitors._type_defs import VisitorOptions -from cmk.gui.utils.rule_specs.loader import LoadedRuleSpec from cmk.rulesets.v1.form_specs import FormSpec from cmk.rulesets.v1.form_specs._base import ModelT -form_spec_registry: dict[str, LoadedRuleSpec] = {} RecomposerFunction = Callable[[FormSpec[Any]], FormSpec[Any]] form_specs_visitor_registry: dict[ type[FormSpec[Any]], tuple[type[FormSpecVisitor[FormSpec[Any], Any]], RecomposerFunction | None] diff --git a/cmk/gui/form_specs/vue/visitors/_utils.py b/cmk/gui/form_specs/vue/visitors/_utils.py index 92f93a63022..fda4bbda4f8 100644 --- a/cmk/gui/form_specs/vue/visitors/_utils.py +++ b/cmk/gui/form_specs/vue/visitors/_utils.py @@ -83,15 +83,13 @@ def get_prefill_default(prefill: _PrefillTypes[ModelT]) -> ModelT | EmptyValue: return prefill.value -def compute_title_input_hint(prefill: _PrefillTypes[ModelT]) -> ModelT | str | None: +def compute_title_input_hint(prefill: DefaultValue[ModelT] | InputHint[Title]) -> str | None: # InputHint[Title] is only used by SingleChoice and CascadingSingleChoice # in all other cases you should use compute_input_hint - if not isinstance(prefill, InputHint): - return None - - if isinstance(prefill.value, Title): + if isinstance(prefill, InputHint): return prefill.value.localize(translate_to_current_language) - return prefill.value + + return None def compute_input_hint(prefill: Prefill[ModelT]) -> ModelT | None: diff --git a/cmk/gui/form_specs/vue/visitors/catalog.py b/cmk/gui/form_specs/vue/visitors/catalog.py index 7d493a8f990..e2c8649a3dd 100644 --- a/cmk/gui/form_specs/vue/visitors/catalog.py +++ b/cmk/gui/form_specs/vue/visitors/catalog.py @@ -3,13 +3,13 @@ # 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 dataclasses import dataclass -from typing import Any, cast, Mapping, Sequence +from typing import Any, cast, Mapping, Self, Sequence from cmk.ccc.exceptions import MKGeneralException +from cmk.ccc.i18n import _ from cmk.gui.form_specs.private.catalog import Catalog, Topic from cmk.gui.form_specs.vue import shared_type_defs -from cmk.gui.valuespec import Dictionary as ValueSpecDictionary from cmk.rulesets.v1 import Title from cmk.rulesets.v1.form_specs import DictElement @@ -74,6 +74,13 @@ def _validate( for topic in self.form_spec.topics: if topic.ident not in parsed_value: + validations.append( + shared_type_defs.ValidationMessage( + location=[topic.ident], + message=_("Missing catalog topic."), + invalid_value=None, + ) + ) continue element_visitor = get_visitor(topic.dictionary, self.options) @@ -93,7 +100,7 @@ def _to_disk( disk_values = {} for topic in self.form_spec.topics: element_visitor = get_visitor(topic.dictionary, self.options) - if topic_value := parsed_value.get(topic.ident): + if (topic_value := parsed_value.get(topic.ident)) is not None: disk_values[topic.ident] = element_visitor.to_disk(topic_value) return disk_values @@ -106,15 +113,8 @@ class Dict2CatalogConverter: catalog: Catalog @classmethod - def build_from_dictionary( - cls, dictionary: ValueSpecDictionary | FormSpecDictionary, headers: Headers - ) -> "Dict2CatalogConverter": - if isinstance(dictionary, ValueSpecDictionary): - return cls._build_from_valuespec_dictionary(dictionary, headers) - - if isinstance(dictionary, FormSpecDictionary): - return cls._build_from_formspec_dictionary(dictionary, headers) - raise MKGeneralException(f"invalid dictionary type {type(dictionary)}") + def build_from_dictionary(cls, dictionary: FormSpecDictionary, headers: Headers) -> Self: + return cls._build_from_formspec_dictionary(dictionary, headers) @staticmethod def _normalize_header( @@ -133,7 +133,7 @@ def _normalize_header( @classmethod def _build_from_formspec_dictionary( cls, dictionary: FormSpecDictionary, headers: Headers - ) -> "Dict2CatalogConverter": + ) -> Self: topic_elements: dict[str, dict[str, DictElement[Any]]] = {} topic_title: dict[str, Title] = {} element_to_topic: dict[str, str] = {} @@ -167,14 +167,8 @@ def _build_from_formspec_dictionary( return cls(catalog=Catalog(topics=topics)) - @classmethod - def _build_from_valuespec_dictionary( - cls, dictionary: ValueSpecDictionary, headers: Headers - ) -> "Dict2CatalogConverter": - raise NotImplementedError() - def convert_flat_to_catalog_config( - self, flat_config: dict[str, dict[str, object]] + self, flat_config: dict[str, object] ) -> Mapping[str, dict[str, object]]: topic_for_ident: dict[str, str] = {} for topic in self.catalog.topics: @@ -190,3 +184,8 @@ def convert_flat_to_catalog_config( catalog_config.setdefault(target_topic, {})[ident] = value return catalog_config + + def convert_catalog_to_flat_config( + self, config: dict[str, dict[str, object]] + ) -> dict[str, object]: + return {k: v for values in config.values() for k, v in values.items()} diff --git a/cmk/gui/form_specs/vue/visitors/dictionary.py b/cmk/gui/form_specs/vue/visitors/dictionary.py index c223468f3e3..e7034a5a738 100644 --- a/cmk/gui/form_specs/vue/visitors/dictionary.py +++ b/cmk/gui/form_specs/vue/visitors/dictionary.py @@ -5,6 +5,8 @@ import ast from typing import Mapping +from cmk.ccc.i18n import _ + from cmk.gui.form_specs.private.dictionary_extended import DictionaryExtended from cmk.gui.form_specs.vue import shared_type_defs @@ -89,9 +91,9 @@ def _to_vue( else: group = shared_type_defs.DictionaryGroup( - title=localize(self.form_spec.title), - help=localize(self.form_spec.help_text), - key=localize(self.form_spec.title) + localize(self.form_spec.help_text), + title=localize(dict_element.group.title), + help=localize(dict_element.group.help_text), + key=repr(dict_element.group.title) + repr(dict_element.group.help_text), ) if is_active: @@ -131,6 +133,14 @@ def _validate( ] for key_name, dict_element in self.form_spec.elements.items(): if key_name not in parsed_value: + if dict_element.required: + element_validations.append( + shared_type_defs.ValidationMessage( + location=[key_name], + message=_("Required field missing"), + invalid_value=None, + ) + ) continue element_visitor = get_visitor(dict_element.parameter_form, self.options) diff --git a/cmk/gui/form_specs/vue/visitors/fixed_value.py b/cmk/gui/form_specs/vue/visitors/fixed_value.py index a8b0ee2feab..0d1fa350d2f 100644 --- a/cmk/gui/form_specs/vue/visitors/fixed_value.py +++ b/cmk/gui/form_specs/vue/visitors/fixed_value.py @@ -40,7 +40,7 @@ def _to_vue( shared_type_defs.FixedValue( title=title, help=help_text, - label=localize(self.form_spec.label), + label=localize(self.form_spec.label) if self.form_spec.label is not None else None, value=parsed_value, validators=build_vue_validators(compute_validators(self.form_spec)), ), diff --git a/cmk/gui/form_specs/vue/visitors/multiple_choice.py b/cmk/gui/form_specs/vue/visitors/multiple_choice.py index 2978b45fe40..6b62b539214 100644 --- a/cmk/gui/form_specs/vue/visitors/multiple_choice.py +++ b/cmk/gui/form_specs/vue/visitors/multiple_choice.py @@ -5,6 +5,10 @@ from typing import Sequence, TypeVar +from cmk.gui.form_specs.private.multiple_choice import ( + AdaptiveMultipleChoice, + AdaptiveMultipleChoiceLayout, +) from cmk.gui.form_specs.vue import shared_type_defs from cmk.gui.form_specs.vue.validators import build_vue_validators from cmk.gui.form_specs.vue.visitors._base import FormSpecVisitor @@ -16,15 +20,14 @@ get_prefill_default, get_title_and_help, ) -from cmk.gui.i18n import translate_to_current_language +from cmk.gui.i18n import _, translate_to_current_language from cmk.rulesets.v1 import Title -from cmk.rulesets.v1.form_specs import MultipleChoice T = TypeVar("T") -class MultipleChoiceVisitor(FormSpecVisitor[MultipleChoice, Sequence[str]]): +class MultipleChoiceVisitor(FormSpecVisitor[AdaptiveMultipleChoice, Sequence[str]]): def _is_valid_choice(self, value: str) -> bool: return value in [x.name for x in self.form_spec.elements] @@ -48,7 +51,9 @@ def _parse_value(self, raw_value: object) -> Sequence[str] | EmptyValue: def _to_vue( self, raw_value: object, parsed_value: Sequence[str] | EmptyValue - ) -> tuple[shared_type_defs.MultipleChoice, Sequence[str]]: + ) -> tuple[ + shared_type_defs.DualListChoice | shared_type_defs.CheckboxListChoice, Sequence[str] + ]: title, help_text = get_title_and_help(self.form_spec) elements = [ @@ -59,13 +64,37 @@ def _to_vue( for element in self.form_spec.elements ] + if self.form_spec.layout.value == AdaptiveMultipleChoiceLayout.dual_list or ( + self.form_spec.layout.value == AdaptiveMultipleChoiceLayout.auto and len(elements) > 15 + ): + return ( + shared_type_defs.DualListChoice( + title=title, + help=help_text, + elements=elements, + validators=build_vue_validators(compute_validators(self.form_spec)), + i18n=shared_type_defs.DualListChoiceI18n( + add_all=_("Add all >>"), + remove_all=_("<< Remove all"), + add=_("Add >"), + remove=_("< Remove"), + available_options=_("Available options"), + selected_options=_("Selected options"), + selected=_("Selected"), + no_elements_available=_("No elements available"), + no_elements_selected=_("No elements selected"), + ), + show_toggle_all=self.form_spec.show_toggle_all, + ), + [] if isinstance(parsed_value, EmptyValue) else parsed_value, + ) + # checkbox list or auto with <= 15 elements return ( - shared_type_defs.MultipleChoice( + shared_type_defs.CheckboxListChoice( title=title, help=help_text, elements=elements, validators=build_vue_validators(compute_validators(self.form_spec)), - show_toggle_all=self.form_spec.show_toggle_all, ), [] if isinstance(parsed_value, EmptyValue) else parsed_value, ) diff --git a/cmk/gui/form_specs/vue/visitors/password.py b/cmk/gui/form_specs/vue/visitors/password.py index 4856da7817d..1e50b6163fc 100644 --- a/cmk/gui/form_specs/vue/visitors/password.py +++ b/cmk/gui/form_specs/vue/visitors/password.py @@ -126,6 +126,10 @@ def _validate( for x in optional_validation(compute_validators(self.form_spec), parsed_value[2][1]) if x is not None ] + if parsed_value[1] == "stored_password": + if not parsed_value[2][0]: + return create_validation_error("", Title("No password selected")) + return [] def _to_disk(self, raw_value: object, parsed_value: ParsedPassword) -> object: diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/__init__.py b/cmk/gui/form_specs/vue/visitors/recomposers/__init__.py index 0ca3ff26d86..bda1ea3a5b8 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/__init__.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/__init__.py @@ -6,6 +6,7 @@ from .dictionary import recompose as recompose_dictionary from .host_state import recompose as recompose_host_state from .list import recompose as recompose_list +from .multiple_choice import recompose as recompose_multiple_choice from .percentage import recompose as recompose_percentage from .regular_expression import recompose as recompose_regular_expression from .service_state import recompose as recompose_service_state @@ -23,4 +24,5 @@ "recompose_host_state", "recompose_service_state", "recompose_string", + "recompose_multiple_choice", ] diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/dictionary.py b/cmk/gui/form_specs/vue/visitors/recomposers/dictionary.py index 908c2507633..65c29569fe0 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/dictionary.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/dictionary.py @@ -22,6 +22,7 @@ def recompose(form_spec: FormSpec[Any]) -> DictionaryExtended: return DictionaryExtended( title=form_spec.title, help_text=form_spec.help_text, + custom_validate=form_spec.custom_validate, elements=form_spec.elements, no_elements_text=form_spec.no_elements_text, ignored_elements=form_spec.ignored_elements, diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/list.py b/cmk/gui/form_specs/vue/visitors/recomposers/list.py index b0d1fac7051..bbb6220d673 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/list.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/list.py @@ -21,6 +21,7 @@ def recompose(form_spec: FormSpec[Any]) -> ListExtended[Any]: return ListExtended( title=form_spec.title, help_text=form_spec.help_text, + custom_validate=form_spec.custom_validate, element_template=form_spec.element_template, add_element_label=form_spec.add_element_label, remove_element_label=form_spec.remove_element_label, diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/multiple_choice.py b/cmk/gui/form_specs/vue/visitors/recomposers/multiple_choice.py new file mode 100644 index 00000000000..6da7d25b482 --- /dev/null +++ b/cmk/gui/form_specs/vue/visitors/recomposers/multiple_choice.py @@ -0,0 +1,32 @@ +#!/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 typing import Any + +from cmk.ccc.exceptions import MKGeneralException + +from cmk.gui.form_specs.private import AdaptiveMultipleChoice, AdaptiveMultipleChoiceLayout + +from cmk.rulesets.v1.form_specs import FormSpec, MultipleChoice + + +def recompose(form_spec: FormSpec[Any]) -> AdaptiveMultipleChoice: + if not isinstance(form_spec, MultipleChoice): + raise MKGeneralException( + f"Cannot recompose form spec. Expected a MultipleChoice form spec, got {type(form_spec)}" + ) + + return AdaptiveMultipleChoice( + # FormSpec + title=form_spec.title, + help_text=form_spec.help_text, + custom_validate=form_spec.custom_validate, + migrate=form_spec.migrate, + # MultipleChoice + elements=form_spec.elements, + show_toggle_all=form_spec.show_toggle_all, + prefill=form_spec.prefill, + # AdaptiveMultipleChoice + layout=AdaptiveMultipleChoiceLayout.auto, + ) diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/percentage.py b/cmk/gui/form_specs/vue/visitors/recomposers/percentage.py index c134dd30c75..20b7e933851 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/percentage.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/percentage.py @@ -19,6 +19,7 @@ def recompose(form_spec: FormSpec[Any]) -> FormSpec[Any]: return Float( title=form_spec.title, help_text=form_spec.help_text, + custom_validate=form_spec.custom_validate, label=form_spec.label, prefill=form_spec.prefill, unit_symbol="%", diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/regular_expression.py b/cmk/gui/form_specs/vue/visitors/recomposers/regular_expression.py index 04481fbed6e..f19fb5bd6e5 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/regular_expression.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/regular_expression.py @@ -55,8 +55,8 @@ def recompose(form_spec: FormSpec[str]) -> String: return String( title=form_spec.title, help_text=combined_help, + custom_validate=form_spec.custom_validate, label=form_spec.label, migrate=form_spec.migrate, prefill=form_spec.prefill, - custom_validate=form_spec.custom_validate, ) diff --git a/cmk/gui/form_specs/vue/visitors/recomposers/string.py b/cmk/gui/form_specs/vue/visitors/recomposers/string.py index 0c777b2c492..ac93f3db675 100644 --- a/cmk/gui/form_specs/vue/visitors/recomposers/string.py +++ b/cmk/gui/form_specs/vue/visitors/recomposers/string.py @@ -21,8 +21,8 @@ def recompose(form_spec: FormSpec[Any]) -> StringAutocompleter: # FormSpec title=form_spec.title, help_text=form_spec.help_text, - label=form_spec.label, custom_validate=form_spec.custom_validate, + label=form_spec.label, # String macro_support=form_spec.macro_support, prefill=form_spec.prefill, diff --git a/cmk/gui/form_specs/vue/visitors/single_choice.py b/cmk/gui/form_specs/vue/visitors/single_choice.py index 1573141d417..c59d39aaf64 100644 --- a/cmk/gui/form_specs/vue/visitors/single_choice.py +++ b/cmk/gui/form_specs/vue/visitors/single_choice.py @@ -2,19 +2,19 @@ # 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 typing import Generic, Literal, TypeVar +import hashlib +from typing import Generic, TypeVar from cmk.gui.form_specs import private from cmk.gui.form_specs.vue import shared_type_defs from cmk.gui.form_specs.vue.validators import build_vue_validators -from cmk.gui.i18n import translate_to_current_language +from cmk.gui.i18n import _, translate_to_current_language from cmk.rulesets.v1 import Message from cmk.rulesets.v1.form_specs import InvalidElementMode from ._base import FormSpecVisitor -from ._type_defs import DefaultValue, EMPTY_VALUE, EmptyValue +from ._type_defs import DataOrigin, DefaultValue, EMPTY_VALUE, EmptyValue from ._utils import ( compute_title_input_hint, compute_validation_errors, @@ -27,6 +27,8 @@ T = TypeVar("T") +NO_SELECTION = "" + class SingleChoiceVisitor(Generic[T], FormSpecVisitor[private.SingleChoiceExtended[T], T]): def _is_valid_choice(self, value: T | EmptyValue) -> bool: @@ -34,6 +36,10 @@ def _is_valid_choice(self, value: T | EmptyValue) -> bool: return False return value in [x.name for x in self.form_spec.elements] + @classmethod + def option_id(cls, val: object) -> str: + return "%s" % hashlib.sha256(repr(val).encode()).hexdigest() + def _parse_value(self, raw_value: object) -> T | EmptyValue: if isinstance(raw_value, DefaultValue): if isinstance( @@ -42,6 +48,16 @@ def _parse_value(self, raw_value: object) -> T | EmptyValue: return prefill_default raw_value = prefill_default + if self.options.data_origin == DataOrigin.FRONTEND: + # Decode option send from frontend + for option in self.form_spec.elements: + if self.option_id(option.name) == raw_value: + raw_value = option.name + break + else: + # Found no matching option + return EMPTY_VALUE + if not isinstance(raw_value, self.form_spec.type): return EMPTY_VALUE @@ -69,12 +85,12 @@ def _parse_value(self, raw_value: object) -> T | EmptyValue: def _to_vue( self, raw_value: object, parsed_value: T | EmptyValue - ) -> tuple[shared_type_defs.SingleChoice, Literal[""] | T]: + ) -> tuple[shared_type_defs.SingleChoice, str]: title, help_text = get_title_and_help(self.form_spec) elements = [ shared_type_defs.SingleChoiceElement( - name=element.name, + name=self.option_id(element.name), title=element.title.localize(translate_to_current_language), ) for element in self.form_spec.elements @@ -87,6 +103,8 @@ def _to_vue( if invalid_validation and invalid_validation.display: input_hint = localize(invalid_validation.display) + # Note: All valid values have at least some kind of str content, + # since self._option_id uses repr() to generate the id return ( shared_type_defs.SingleChoice( title=title, @@ -95,9 +113,9 @@ def _to_vue( label=localize(self.form_spec.label), validators=build_vue_validators(compute_validators(self.form_spec)), frozen=self.form_spec.frozen and isinstance(raw_value, self.form_spec.type), - input_hint=input_hint, + input_hint=input_hint or _("Please choose"), ), - "" if isinstance(parsed_value, EmptyValue) else parsed_value, + NO_SELECTION if isinstance(parsed_value, EmptyValue) else self.option_id(parsed_value), ) def _compute_invalid_value_display_message(self, raw_value: object) -> str: @@ -109,6 +127,8 @@ def _compute_invalid_value_display_message(self, raw_value: object) -> str: ) or Message("Invalid choice %r") message_localized = localize(message) if "%s" in message_localized or "%r" in message_localized: + if raw_value == NO_SELECTION: + return message_localized.replace("%s", "").replace("%r", "") return message_localized % (raw_value,) return message_localized diff --git a/cmk/gui/graphing/__init__.py b/cmk/gui/graphing/__init__.py index 5dc033f4279..2abd206b871 100644 --- a/cmk/gui/graphing/__init__.py +++ b/cmk/gui/graphing/__init__.py @@ -10,16 +10,16 @@ from . import _perfometer from ._autocompleter import graph_templates_autocompleter, metrics_autocompleter from ._explicit_graphs import ExplicitGraphSpecification -from ._graph_specification import ( - graph_specification_registry, +from ._graph_specification import graph_specification_registry +from ._graph_templates import TemplateGraphSpecification +from ._legacy import perfometer_info, PerfometerSpec +from ._metric_operation import ( metric_operation_registry, MetricOpConstant, MetricOpConstantNA, MetricOpOperator, MetricOpRRDSource, ) -from ._graph_templates import TemplateGraphSpecification -from ._legacy import perfometer_info, PerfometerSpec from ._perfometer import get_first_matching_perfometer, parse_perfometer from ._settings import ConfigVariableGraphTimeranges from ._valuespecs import PageVsAutocomplete diff --git a/cmk/gui/graphing/_artwork.py b/cmk/gui/graphing/_artwork.py index 5b36827f0d0..825182892a6 100644 --- a/cmk/gui/graphing/_artwork.py +++ b/cmk/gui/graphing/_artwork.py @@ -36,9 +36,8 @@ MinimalVerticalRange, ) from ._legacy import get_unit_info, LegacyUnitSpecification, UnitInfo +from ._metric_operation import clean_time_series_point, LineType, RRDData from ._rrd_fetch import fetch_rrd_data_for_graph -from ._timeseries import clean_time_series_point -from ._type_defs import LineType, RRDData from ._unit import user_specific_unit, UserSpecificUnit from ._utils import SizeEx @@ -246,11 +245,6 @@ def _layout_graph_curves(curves: Sequence[Curve]) -> tuple[list[LayoutedCurve], # For areas we put (lower, higher) as point into the list of points. # For lines simply the values. For mirrored values from is >= to. - def mirror_point(p: TimeSeriesValue) -> TimeSeriesValue: - if p is None: - return p - return -p - def _positive_line_type(line_type: LineType) -> Literal["line", "area", "stack"]: if line_type == "-line": return "line" @@ -270,7 +264,7 @@ def _positive_line_type(line_type: LineType) -> Literal["line", "area", "stack"] continue if line_type[0] == "-": - raw_points = list(map(mirror_point, raw_points)) + raw_points = [None if p is None else -p for p in raw_points] line_type = _positive_line_type(line_type) mirrored = True stack_nr = 0 @@ -747,11 +741,6 @@ def _compute_graph_v_axis( return v_axis -def _apply_mirrored(min_value: float, max_value: float) -> tuple[float, float]: - abs_limit = max(abs(min_value), abs(max_value)) - return -abs_limit, abs_limit - - def _compute_min_max( explicit_vertical_range: FixedVerticalRange | MinimalVerticalRange | None, layouted_curves: Sequence[LayoutedCurve], @@ -827,7 +816,9 @@ def _compute_v_axis_min_max( # In case the graph is mirrored, the 0 line is always exactly in the middle if mirrored: - min_value, max_value = _apply_mirrored(min_value, max_value) + abs_limit = max(abs(min_value), abs(max_value)) + min_value = -abs_limit + max_value = abs_limit # Make sure we have a non-zero range. This avoids math errors for # silly graphs. diff --git a/cmk/gui/graphing/_explicit_graphs.py b/cmk/gui/graphing/_explicit_graphs.py index 2bfc63d74aa..7af281b16a7 100644 --- a/cmk/gui/graphing/_explicit_graphs.py +++ b/cmk/gui/graphing/_explicit_graphs.py @@ -14,7 +14,7 @@ HorizontalRule, ) from ._legacy import LegacyUnitSpecification -from ._type_defs import GraphConsolidationFunction +from ._metric_operation import GraphConsolidationFunction from ._unit import ConvertibleUnitSpecification diff --git a/cmk/gui/graphing/_formatter.py b/cmk/gui/graphing/_formatter.py index 7291789cffc..33c80da024c 100644 --- a/cmk/gui/graphing/_formatter.py +++ b/cmk/gui/graphing/_formatter.py @@ -110,7 +110,7 @@ def _stringify_formatted_value(self, value: int | float) -> str: return str(value) @abc.abstractmethod - def _compose(self, formatted: Formatted) -> str: ... + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: ... def _postformat( self, @@ -128,11 +128,13 @@ def _postformat( ) ) results.append( - self._compose( - Formatted( - text.rstrip("0").rstrip(".") if "." in text else text, - formatted.prefix, - formatted.symbol, + _join_numerical_value_and_unit( + *self._make_rendered_numerical_value_and_unit( + Formatted( + text.rstrip("0").rstrip(".") if "." in text else text, + formatted.prefix, + formatted.symbol, + ) ) ).strip() ) @@ -200,6 +202,19 @@ def render_y_labels( ] +def _join_numerical_value_and_unit( + numerical_value: str, + unit: str, +) -> str: + """ + >>> _join_numerical_value_and_unit("1", "s") + '1 s' + >>> _join_numerical_value_and_unit("1", "/s") + '1/s' + """ + return f"{numerical_value}{unit}" if unit.startswith("/") else f"{numerical_value} {unit}" + + _BASIC_DECIMAL_ATOMS: Final = [1, 2, 5, 10, 20, 50] @@ -244,10 +259,13 @@ def _stringify_formatted_value(self, value: int | float) -> str: # '1e-05' sign = "" if value > 0 else "-" return f"{sign}{_stringify_small_decimal_number(abs(value))}" - return str(value) + return f"{value:,}".replace( + ",", + "\N{THIN SPACE}", + ) - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text} {formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return formatted.text, formatted.symbol def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) @@ -312,8 +330,8 @@ def _preformat_large_number( return [Preformatted(value / pow(1000, power), prefix, self.symbol)] return [Preformatted(value, "", self.symbol)] - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text} {formatted.prefix}{formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return formatted.text, f"{formatted.prefix}{formatted.symbol}" def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) @@ -361,8 +379,8 @@ def _preformat_large_number( return [Preformatted(value / pow(1024, power), prefix, self.symbol)] return [Preformatted(value, "", self.symbol)] - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text} {formatted.prefix}{formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return formatted.text, f"{formatted.prefix}{formatted.symbol}" def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) @@ -393,8 +411,8 @@ def _preformat_large_number( exponent = math.floor(math.log10(value)) return [Preformatted(value / pow(10, exponent), f"e+{exponent}", self.symbol)] - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text}{formatted.prefix} {formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return f"{formatted.text}{formatted.prefix}", formatted.symbol def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) @@ -425,8 +443,8 @@ def _preformat_large_number( exponent = math.floor(math.log10(value) // 3) * 3 return [Preformatted(value / pow(10, exponent), f"e+{exponent}", self.symbol)] - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text}{formatted.prefix} {formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return f"{formatted.text}{formatted.prefix}", formatted.symbol def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) @@ -528,8 +546,8 @@ def _preformat_large_number( formatted_parts.append(Preformatted(value, "", "s")) return formatted_parts - def _compose(self, formatted: Formatted) -> str: - return f"{formatted.text} {formatted.prefix}{formatted.symbol}" + def _make_rendered_numerical_value_and_unit(self, formatted: Formatted) -> tuple[str, str]: + return formatted.text, f"{formatted.prefix}{formatted.symbol}" def _compute_small_y_label_atoms(self, max_y: int | float) -> Sequence[int | float]: factor = pow(10, math.floor(math.log10(max_y)) - 1) diff --git a/cmk/gui/graphing/_graph_specification.py b/cmk/gui/graphing/_graph_specification.py index c5663900314..85edf9dd03d 100644 --- a/cmk/gui/graphing/_graph_specification.py +++ b/cmk/gui/graphing/_graph_specification.py @@ -6,9 +6,7 @@ from __future__ import annotations from abc import ABC, abstractmethod -from collections.abc import Iterator, Mapping, Sequence -from dataclasses import dataclass -from itertools import chain +from collections.abc import Mapping, Sequence from typing import Annotated, final, Literal from pydantic import ( @@ -20,20 +18,16 @@ SerializeAsAny, ) -from livestatus import SiteId - from cmk.ccc.plugin_registry import Registry -from cmk.utils.hostaddress import HostName -from cmk.utils.metrics import MetricName -from cmk.utils.servicename import ServiceName - -from cmk.gui.time_series import TimeSeries - from ._graph_render_config import GraphRenderOptions from ._legacy import LegacyUnitSpecification -from ._timeseries import AugmentedTimeSeries, derive_num_points_twindow, time_series_math -from ._type_defs import GraphConsolidationFunction, LineType, Operators, RRDData, RRDDataKey +from ._metric_operation import ( + GraphConsolidationFunction, + LineType, + MetricOperation, + parse_metric_operation, +) from ._unit import ConvertibleUnitSpecification, NonConvertibleUnitSpecification @@ -44,152 +38,6 @@ class HorizontalRule(BaseModel, frozen=True): title: str -@dataclass(frozen=True) -class TranslationKey: - host_name: HostName - service_name: ServiceName - - -class MetricOperation(BaseModel, ABC, frozen=True): - @staticmethod - @abstractmethod - def operation_name() -> str: ... - - @abstractmethod - def keys(self) -> Iterator[TranslationKey | RRDDataKey]: ... - - @abstractmethod - def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: ... - - def fade_odd_color(self) -> bool: - return True - - # mypy does not support other decorators on top of @property: - # https://github.com/python/mypy/issues/14461 - # https://docs.pydantic.dev/2.0/usage/computed_fields (mypy warning) - @computed_field # type: ignore[prop-decorator] - @property - @final - def ident(self) -> str: - return self.operation_name() - - -class MetricOperationRegistry(Registry[type[MetricOperation]]): - def plugin_name(self, instance: type[MetricOperation]) -> str: - return instance.operation_name() - - -metric_operation_registry = MetricOperationRegistry() - - -def parse_metric_operation(raw: object) -> MetricOperation: - match raw: - case MetricOperation(): - return raw - case {"ident": str(ident), **rest}: - return metric_operation_registry[ident].model_validate(rest) - case dict(): - raise ValueError("Missing 'ident' key in metric operation") - raise TypeError(raw) - - -class MetricOpConstant(MetricOperation, frozen=True): - value: float - - @staticmethod - def operation_name() -> Literal["constant"]: - return "constant" - - def keys(self) -> Iterator[TranslationKey | RRDDataKey]: - yield from () - - def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: - num_points, twindow = derive_num_points_twindow(rrd_data) - return [AugmentedTimeSeries(data=TimeSeries([self.value] * num_points, twindow))] - - -class MetricOpConstantNA(MetricOperation, frozen=True): - @staticmethod - def operation_name() -> Literal["constant_na"]: - return "constant_na" - - def keys(self) -> Iterator[TranslationKey | RRDDataKey]: - yield from () - - def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: - num_points, twindow = derive_num_points_twindow(rrd_data) - return [AugmentedTimeSeries(data=TimeSeries([None] * num_points, twindow))] - - -class MetricOpOperator(MetricOperation, frozen=True): - operator_name: Operators - operands: Sequence[ - Annotated[SerializeAsAny[MetricOperation], PlainValidator(parse_metric_operation)] - ] = [] - - @staticmethod - def operation_name() -> Literal["operator"]: - return "operator" - - def keys(self) -> Iterator[TranslationKey | RRDDataKey]: - yield from (k for o in self.operands for k in o.keys()) - - def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: - if result := time_series_math( - self.operator_name, - [ - operand_evaluated.data - for operand_evaluated in chain.from_iterable( - operand.compute_time_series(rrd_data) for operand in self.operands - ) - ], - ): - return [AugmentedTimeSeries(data=result)] - return [] - - -class MetricOpRRDSource(MetricOperation, frozen=True): - site_id: SiteId - host_name: HostName - service_name: ServiceName - metric_name: MetricName - consolidation_func_name: GraphConsolidationFunction | None - scale: float - - @staticmethod - def operation_name() -> Literal["rrd"]: - return "rrd" - - def keys(self) -> Iterator[TranslationKey | RRDDataKey]: - yield RRDDataKey( - self.site_id, - self.host_name, - self.service_name, - self.metric_name, - self.consolidation_func_name, - self.scale, - ) - - def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: - if ( - key := RRDDataKey( - self.site_id, - self.host_name, - self.service_name, - self.metric_name, - self.consolidation_func_name, - self.scale, - ) - ) in rrd_data: - return [AugmentedTimeSeries(data=rrd_data[key])] - - num_points, twindow = derive_num_points_twindow(rrd_data) - return [AugmentedTimeSeries(data=TimeSeries([None] * num_points, twindow))] - - -MetricOpOperator.model_rebuild() - - class GraphMetric(BaseModel, frozen=True): title: str line_type: LineType diff --git a/cmk/gui/graphing/_graph_templates.py b/cmk/gui/graphing/_graph_templates.py index eba5a570ee9..2da6e2a0b09 100644 --- a/cmk/gui/graphing/_graph_templates.py +++ b/cmk/gui/graphing/_graph_templates.py @@ -26,7 +26,18 @@ from cmk.graphing.v1 import graphs as graphs_api from cmk.graphing.v1 import metrics as metrics_api -from ._expression import ( +from ._from_api import graphs_from_api +from ._graph_specification import ( + FixedVerticalRange, + graph_specification_registry, + GraphMetric, + GraphRecipe, + GraphSpecification, + HorizontalRule, + MinimalVerticalRange, +) +from ._legacy import get_render_function, graph_info, LegacyUnitSpecification, RawGraphTemplate +from ._metric_expression import ( Average, BaseMetricExpression, Constant, @@ -48,22 +59,14 @@ Sum, WarningOf, ) -from ._from_api import graphs_from_api -from ._graph_specification import ( - FixedVerticalRange, - graph_specification_registry, - GraphMetric, - GraphRecipe, - GraphSpecification, - HorizontalRule, +from ._metric_operation import ( + GraphConsolidationFunction, + LineType, MetricOpConstant, MetricOpOperator, MetricOpRRDSource, - MinimalVerticalRange, ) -from ._legacy import get_render_function, graph_info, LegacyUnitSpecification, RawGraphTemplate from ._translated_metrics import translated_metrics_from_row, TranslatedMetric -from ._type_defs import GraphConsolidationFunction, LineType from ._unit import ConvertibleUnitSpecification from ._utils import get_graph_data_from_livestatus diff --git a/cmk/gui/graphing/_expression.py b/cmk/gui/graphing/_metric_expression.py similarity index 99% rename from cmk/gui/graphing/_expression.py rename to cmk/gui/graphing/_metric_expression.py index 88f371ae2d4..ff3c4d8c27c 100644 --- a/cmk/gui/graphing/_expression.py +++ b/cmk/gui/graphing/_metric_expression.py @@ -22,9 +22,9 @@ from ._formatter import AutoPrecision, StrictPrecision from ._from_api import parse_unit_from_api from ._legacy import get_unit_info, unit_info, UnitInfo +from ._metric_operation import GraphConsolidationFunction, line_type_mirror, LineType from ._metrics import get_metric_spec from ._translated_metrics import TranslatedMetric -from ._type_defs import GraphConsolidationFunction, line_type_mirror, LineType from ._unit import ConvertibleUnitSpecification, DecimalNotation # TODO CMK-15246 Checkmk 2.4: Remove legacy objects/RPNs diff --git a/cmk/gui/graphing/_metric_operation.py b/cmk/gui/graphing/_metric_operation.py new file mode 100644 index 00000000000..8a9e476608f --- /dev/null +++ b/cmk/gui/graphing/_metric_operation.py @@ -0,0 +1,342 @@ +#!/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 __future__ import annotations + +import functools +import operator +from abc import ABC, abstractmethod +from collections.abc import Iterator, Mapping, Sequence +from dataclasses import dataclass +from itertools import chain +from typing import Annotated, assert_never, Callable, final, Literal, TypeVar + +from pydantic import BaseModel, computed_field, PlainValidator, SerializeAsAny + +from livestatus import SiteId + +from cmk.ccc.exceptions import MKGeneralException +from cmk.ccc.plugin_registry import Registry + +from cmk.utils.hostaddress import HostName +from cmk.utils.metrics import MetricName +from cmk.utils.servicename import ServiceName + +from cmk.gui.i18n import _ +from cmk.gui.time_series import TimeSeries, TimeSeriesValues +from cmk.gui.utils import escaping + +GraphConsolidationFunction = Literal["max", "min", "average"] +LineType = Literal["line", "area", "stack", "-line", "-area", "-stack"] + + +def line_type_mirror(line_type: LineType) -> LineType: + match line_type: + case "line": + return "-line" + case "-line": + return "line" + case "area": + return "-area" + case "-area": + return "area" + case "stack": + return "-stack" + case "-stack": + return "stack" + case other: + assert_never(other) + + +Operators = Literal["+", "*", "-", "/", "MAX", "MIN", "AVERAGE", "MERGE"] + + +@dataclass(frozen=True) +class RRDDataKey: + site_id: SiteId + host_name: HostName + service_name: ServiceName + metric_name: str + consolidation_function: GraphConsolidationFunction | None + scale: float + + +RRDData = Mapping[RRDDataKey, TimeSeries] + + +def _derive_num_points_twindow(rrd_data: RRDData) -> tuple[int, tuple[int, int, int]]: + if rrd_data: + sample_data = next(iter(rrd_data.values())) + return len(sample_data), sample_data.twindow + # no data, default clean graph, use for pure scalars on custom graphs + return 1, (0, 60, 60) + + +_TOperatorReturn = TypeVar("_TOperatorReturn") + + +def op_func_wrapper( + op_func: Callable[[TimeSeries | TimeSeriesValues], _TOperatorReturn], + tsp: TimeSeries | TimeSeriesValues, +) -> _TOperatorReturn | None: + if tsp.count(None) < len(tsp): # At least one non-None value + try: + return op_func(tsp) + except ZeroDivisionError: + pass + return None + + +def clean_time_series_point(tsp: TimeSeries | TimeSeriesValues) -> list[float]: + """removes "None" entries from input list""" + return [x for x in tsp if x is not None] + + +def _time_series_operator_sum(tsp: TimeSeries | TimeSeriesValues) -> float: + return sum(clean_time_series_point(tsp)) + + +def _time_series_operator_product(tsp: TimeSeries | TimeSeriesValues) -> float | None: + if None in tsp: + return None + return functools.reduce(operator.mul, tsp, 1) + + +def _time_series_operator_difference(tsp: TimeSeries | TimeSeriesValues) -> float | None: + if None in tsp: + return None + assert tsp[0] is not None + assert tsp[1] is not None + return tsp[0] - tsp[1] + + +def _time_series_operator_fraction(tsp: TimeSeries | TimeSeriesValues) -> float | None: + if None in tsp or tsp[1] == 0: + return None + assert tsp[0] is not None + assert tsp[1] is not None + return tsp[0] / tsp[1] + + +def _time_series_operator_maximum(tsp: TimeSeries | TimeSeriesValues) -> float: + return max(clean_time_series_point(tsp)) + + +def _time_series_operator_minimum(tsp: TimeSeries | TimeSeriesValues) -> float: + return min(clean_time_series_point(tsp)) + + +def _time_series_operator_average(tsp: TimeSeries | TimeSeriesValues) -> float: + tsp_clean = clean_time_series_point(tsp) + return sum(tsp_clean) / len(tsp_clean) + + +def time_series_operators() -> ( + dict[ + Operators, + tuple[ + str, + Callable[[TimeSeries | TimeSeriesValues], float | None], + ], + ] +): + return { + "+": (_("Sum"), _time_series_operator_sum), + "*": (_("Product"), _time_series_operator_product), + "-": (_("Difference"), _time_series_operator_difference), + "/": (_("Fraction"), _time_series_operator_fraction), + "MAX": (_("Maximum"), _time_series_operator_maximum), + "MIN": (_("Minimum"), _time_series_operator_minimum), + "AVERAGE": (_("Average"), _time_series_operator_average), + "MERGE": ("First non None", lambda x: next(iter(clean_time_series_point(x)))), + } + + +@dataclass(frozen=True) +class TranslationKey: + host_name: HostName + service_name: ServiceName + + +@dataclass(frozen=True) +class TimeSeriesMetaData: + title: str | None = None + color: str | None = None + line_type: LineType | Literal["ref"] | None = None + + +@dataclass(frozen=True) +class AugmentedTimeSeries: + data: TimeSeries + metadata: TimeSeriesMetaData = TimeSeriesMetaData() + + +class MetricOperation(BaseModel, ABC, frozen=True): + @staticmethod + @abstractmethod + def operation_name() -> str: ... + + @abstractmethod + def keys(self) -> Iterator[TranslationKey | RRDDataKey]: ... + + @abstractmethod + def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: ... + + def fade_odd_color(self) -> bool: + return True + + # mypy does not support other decorators on top of @property: + # https://github.com/python/mypy/issues/14461 + # https://docs.pydantic.dev/2.0/usage/computed_fields (mypy warning) + @computed_field # type: ignore[prop-decorator] + @property + @final + def ident(self) -> str: + return self.operation_name() + + +class MetricOperationRegistry(Registry[type[MetricOperation]]): + def plugin_name(self, instance: type[MetricOperation]) -> str: + return instance.operation_name() + + +metric_operation_registry = MetricOperationRegistry() + + +def parse_metric_operation(raw: object) -> MetricOperation: + match raw: + case MetricOperation(): + return raw + case {"ident": str(ident), **rest}: + return metric_operation_registry[ident].model_validate(rest) + case dict(): + raise ValueError("Missing 'ident' key in metric operation") + raise TypeError(raw) + + +class MetricOpConstant(MetricOperation, frozen=True): + value: float + + @staticmethod + def operation_name() -> Literal["constant"]: + return "constant" + + def keys(self) -> Iterator[TranslationKey | RRDDataKey]: + yield from () + + def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: + num_points, twindow = _derive_num_points_twindow(rrd_data) + return [AugmentedTimeSeries(data=TimeSeries([self.value] * num_points, twindow))] + + +class MetricOpConstantNA(MetricOperation, frozen=True): + @staticmethod + def operation_name() -> Literal["constant_na"]: + return "constant_na" + + def keys(self) -> Iterator[TranslationKey | RRDDataKey]: + yield from () + + def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: + num_points, twindow = _derive_num_points_twindow(rrd_data) + return [AugmentedTimeSeries(data=TimeSeries([None] * num_points, twindow))] + + +def _time_series_math( + operator_id: Operators, + operands_evaluated: list[TimeSeries], +) -> TimeSeries | None: + operators = time_series_operators() + if operator_id not in operators: + raise MKGeneralException( + _("Undefined operator '%s' in graph expression") + % escaping.escape_attribute(operator_id) + ) + # Test for correct arity on FOUND[evaluated] data + if any( + ( + operator_id in ["-", "/"] and len(operands_evaluated) != 2, + len(operands_evaluated) < 1, + ) + ): + # raise MKGeneralException(_("Incorrect amount of data to correctly evaluate expression")) + # Silently return so to get an empty graph slot + return None + + _op_title, op_func = operators[operator_id] + twindow = operands_evaluated[0].twindow + + return TimeSeries( + [op_func_wrapper(op_func, list(tsp)) for tsp in zip(*operands_evaluated)], twindow + ) + + +class MetricOpOperator(MetricOperation, frozen=True): + operator_name: Operators + operands: Sequence[ + Annotated[SerializeAsAny[MetricOperation], PlainValidator(parse_metric_operation)] + ] = [] + + @staticmethod + def operation_name() -> Literal["operator"]: + return "operator" + + def keys(self) -> Iterator[TranslationKey | RRDDataKey]: + yield from (k for o in self.operands for k in o.keys()) + + def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: + if result := _time_series_math( + self.operator_name, + [ + operand_evaluated.data + for operand_evaluated in chain.from_iterable( + operand.compute_time_series(rrd_data) for operand in self.operands + ) + ], + ): + return [AugmentedTimeSeries(data=result)] + return [] + + +MetricOpOperator.model_rebuild() + + +class MetricOpRRDSource(MetricOperation, frozen=True): + site_id: SiteId + host_name: HostName + service_name: ServiceName + metric_name: MetricName + consolidation_func_name: GraphConsolidationFunction | None + scale: float + + @staticmethod + def operation_name() -> Literal["rrd"]: + return "rrd" + + def keys(self) -> Iterator[TranslationKey | RRDDataKey]: + yield RRDDataKey( + self.site_id, + self.host_name, + self.service_name, + self.metric_name, + self.consolidation_func_name, + self.scale, + ) + + def compute_time_series(self, rrd_data: RRDData) -> Sequence[AugmentedTimeSeries]: + if ( + key := RRDDataKey( + self.site_id, + self.host_name, + self.service_name, + self.metric_name, + self.consolidation_func_name, + self.scale, + ) + ) in rrd_data: + return [AugmentedTimeSeries(data=rrd_data[key])] + + num_points, twindow = _derive_num_points_twindow(rrd_data) + return [AugmentedTimeSeries(data=TimeSeries([None] * num_points, twindow))] diff --git a/cmk/gui/graphing/_perfometer.py b/cmk/gui/graphing/_perfometer.py index ada84fd8193..3f21749da9e 100644 --- a/cmk/gui/graphing/_perfometer.py +++ b/cmk/gui/graphing/_perfometer.py @@ -23,13 +23,6 @@ from cmk.graphing.v1 import perfometers as perfometers_api from ._color import parse_color_from_api -from ._expression import ( - BaseMetricExpression, - Constant, - parse_legacy_base_expression, - parse_legacy_conditional_expression, - parse_legacy_simple_expression, -) from ._from_api import parse_unit_from_api, perfometers_from_api from ._legacy import ( DualPerfometerSpec, @@ -44,6 +37,13 @@ unit_info, UnitInfo, ) +from ._metric_expression import ( + BaseMetricExpression, + Constant, + parse_legacy_base_expression, + parse_legacy_conditional_expression, + parse_legacy_simple_expression, +) from ._translated_metrics import TranslatedMetric from ._unit import ConvertibleUnitSpecification, user_specific_unit diff --git a/cmk/gui/graphing/_rrd_fetch.py b/cmk/gui/graphing/_rrd_fetch.py index 6014343f86d..1ed922e70d2 100644 --- a/cmk/gui/graphing/_rrd_fetch.py +++ b/cmk/gui/graphing/_rrd_fetch.py @@ -34,10 +34,15 @@ get_unit_info, LegacyUnitSpecification, ) +from ._metric_operation import ( + GraphConsolidationFunction, + op_func_wrapper, + RRDData, + RRDDataKey, + time_series_operators, +) from ._metrics import get_metric_spec -from ._timeseries import op_func_wrapper, time_series_operators from ._translated_metrics import find_matching_translation, TranslationSpec -from ._type_defs import GraphConsolidationFunction, RRDData, RRDDataKey def fetch_rrd_data_for_graph( diff --git a/cmk/gui/graphing/_timeseries.py b/cmk/gui/graphing/_timeseries.py deleted file mode 100644 index 9f2f579bd9f..00000000000 --- a/cmk/gui/graphing/_timeseries.py +++ /dev/null @@ -1,148 +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. - -import functools -import operator -from collections.abc import Callable -from dataclasses import dataclass -from typing import Literal, TypeVar - -from cmk.ccc.exceptions import MKGeneralException - -from cmk.gui.i18n import _ -from cmk.gui.time_series import TimeSeries, TimeSeriesValues -from cmk.gui.utils import escaping - -from ._type_defs import LineType, Operators, RRDData - - -@dataclass(frozen=True) -class TimeSeriesMetaData: - title: str | None = None - color: str | None = None - line_type: LineType | Literal["ref"] | None = None - - -@dataclass(frozen=True) -class AugmentedTimeSeries: - data: TimeSeries - metadata: TimeSeriesMetaData = TimeSeriesMetaData() - - -def derive_num_points_twindow(rrd_data: RRDData) -> tuple[int, tuple[int, int, int]]: - if rrd_data: - sample_data = next(iter(rrd_data.values())) - return len(sample_data), sample_data.twindow - # no data, default clean graph, use for pure scalars on custom graphs - return 1, (0, 60, 60) - - -def time_series_math( - operator_id: Operators, - operands_evaluated: list[TimeSeries], -) -> TimeSeries | None: - operators = time_series_operators() - if operator_id not in operators: - raise MKGeneralException( - _("Undefined operator '%s' in graph expression") - % escaping.escape_attribute(operator_id) - ) - # Test for correct arity on FOUND[evaluated] data - if any( - ( - operator_id in ["-", "/"] and len(operands_evaluated) != 2, - len(operands_evaluated) < 1, - ) - ): - # raise MKGeneralException(_("Incorrect amount of data to correctly evaluate expression")) - # Silently return so to get an empty graph slot - return None - - _op_title, op_func = operators[operator_id] - twindow = operands_evaluated[0].twindow - - return TimeSeries( - [op_func_wrapper(op_func, list(tsp)) for tsp in zip(*operands_evaluated)], twindow - ) - - -_TOperatorReturn = TypeVar("_TOperatorReturn") - - -def op_func_wrapper( - op_func: Callable[[TimeSeries | TimeSeriesValues], _TOperatorReturn], - tsp: TimeSeries | TimeSeriesValues, -) -> _TOperatorReturn | None: - if tsp.count(None) < len(tsp): # At least one non-None value - try: - return op_func(tsp) - except ZeroDivisionError: - pass - return None - - -def clean_time_series_point(tsp: TimeSeries | TimeSeriesValues) -> list[float]: - """removes "None" entries from input list""" - return [x for x in tsp if x is not None] - - -def _time_series_operator_sum(tsp: TimeSeries | TimeSeriesValues) -> float: - return sum(clean_time_series_point(tsp)) - - -def _time_series_operator_product(tsp: TimeSeries | TimeSeriesValues) -> float | None: - if None in tsp: - return None - return functools.reduce(operator.mul, tsp, 1) - - -def _time_series_operator_difference(tsp: TimeSeries | TimeSeriesValues) -> float | None: - if None in tsp: - return None - assert tsp[0] is not None - assert tsp[1] is not None - return tsp[0] - tsp[1] - - -def _time_series_operator_fraction(tsp: TimeSeries | TimeSeriesValues) -> float | None: - if None in tsp or tsp[1] == 0: - return None - assert tsp[0] is not None - assert tsp[1] is not None - return tsp[0] / tsp[1] - - -def _time_series_operator_maximum(tsp: TimeSeries | TimeSeriesValues) -> float: - return max(clean_time_series_point(tsp)) - - -def _time_series_operator_minimum(tsp: TimeSeries | TimeSeriesValues) -> float: - return min(clean_time_series_point(tsp)) - - -def _time_series_operator_average(tsp: TimeSeries | TimeSeriesValues) -> float: - tsp_clean = clean_time_series_point(tsp) - return sum(tsp_clean) / len(tsp_clean) - - -def time_series_operators() -> ( - dict[ - Operators, - tuple[ - str, - Callable[[TimeSeries | TimeSeriesValues], float | None], - ], - ] -): - return { - "+": (_("Sum"), _time_series_operator_sum), - "*": (_("Product"), _time_series_operator_product), - "-": (_("Difference"), _time_series_operator_difference), - "/": (_("Fraction"), _time_series_operator_fraction), - "MAX": (_("Maximum"), _time_series_operator_maximum), - "MIN": (_("Minimum"), _time_series_operator_minimum), - "AVERAGE": (_("Average"), _time_series_operator_average), - "MERGE": ("First non None", lambda x: next(iter(clean_time_series_point(x)))), - } diff --git a/cmk/gui/graphing/_type_defs.py b/cmk/gui/graphing/_type_defs.py deleted file mode 100644 index 146b8bf3c2b..00000000000 --- a/cmk/gui/graphing/_type_defs.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (C) 2023 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 -from dataclasses import dataclass -from typing import assert_never, Literal - -from livestatus import SiteId - -from cmk.utils.hostaddress import HostName -from cmk.utils.servicename import ServiceName - -from cmk.gui.time_series import TimeSeries - -GraphConsolidationFunction = Literal["max", "min", "average"] -GraphPresentation = Literal["lines", "stacked", "sum", "average", "min", "max"] -Operators = Literal["+", "*", "-", "/", "MAX", "MIN", "AVERAGE", "MERGE"] -LineType = Literal["line", "area", "stack", "-line", "-area", "-stack"] - - -def line_type_mirror(line_type: LineType) -> LineType: - match line_type: - case "line": - return "-line" - case "-line": - return "line" - case "area": - return "-area" - case "-area": - return "area" - case "stack": - return "-stack" - case "-stack": - return "stack" - case other: - assert_never(other) - - -@dataclass(frozen=True) -class RRDDataKey: - site_id: SiteId - host_name: HostName - service_name: ServiceName - metric_name: str - consolidation_function: GraphConsolidationFunction | None - scale: float - - -RRDData = Mapping[RRDDataKey, TimeSeries] diff --git a/cmk/gui/help_menu.py b/cmk/gui/help_menu.py new file mode 100644 index 00000000000..e2a905080a4 --- /dev/null +++ b/cmk/gui/help_menu.py @@ -0,0 +1,183 @@ +#!/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.ccc.version import __version__, Edition, edition + +from cmk.utils import paths +from cmk.utils.licensing.registry import get_license_message + +from cmk.gui.htmllib.generator import HTMLWriter +from cmk.gui.http import request +from cmk.gui.i18n import _, _l +from cmk.gui.logged_in import user +from cmk.gui.main_menu import MegaMenuRegistry +from cmk.gui.type_defs import MegaMenu, TopicMenuItem, TopicMenuTopic +from cmk.gui.utils.html import HTML +from cmk.gui.utils.urls import doc_reference_url, DocReference, makeuri_contextless + +if edition(paths.omd_root) is Edition.CSE: + from cmk.gui.cse.utils.roles import user_may_see_saas_onboarding + + +def register(mega_menu_registry: MegaMenuRegistry) -> None: + mega_menu_registry.register( + MegaMenu( + name="help_links", + title=_l("Help"), + icon="main_help", + sort_index=18, + topics=_help_menu_topics, + info_line=lambda: f"{edition(paths.omd_root).title} {__version__}{_license_status()}", + ) + ) + + +def _help_menu_topics() -> list[TopicMenuTopic]: + learning_items = [ + TopicMenuItem( + name="beginners_guide", + title=_("Beginner's guide"), + url=doc_reference_url(DocReference.INTRO_WELCOME), + target="_blank", + sort_index=20, + icon="learning_beginner", + ), + TopicMenuItem( + name="user_manual", + title=_("User manual"), + url=doc_reference_url(), + target="_blank", + sort_index=30, + icon="learning_guide", + ), + TopicMenuItem( + name="video_tutorials", + title=_("Video tutorials"), + url="https://www.youtube.com/playlist?list=PL8DfRO2DvOK1slgjfTu0hMOnepf1F7ssh", + target="_blank", + sort_index=40, + icon="learning_video_tutorials", + ), + TopicMenuItem( + name="community_forum", + title=_("Community forum"), + url="https://forum.checkmk.com/", + target="_blank", + sort_index=50, + icon="learning_forum", + ), + ] + + if edition(paths.omd_root) == Edition.CSE and user_may_see_saas_onboarding(user.id): + learning_items.append( + TopicMenuItem( + name="getting_started", title=_("Getting started"), sort_index=10, url="" + ), + ) + + return [ + TopicMenuTopic( + name="learning_checkmk", + title=_("Learning Checkmk"), + icon="learning_checkmk", + items=learning_items, + ), + TopicMenuTopic( + name="developer_resources", + title=_("Developer resources"), + icon="developer_resources", + items=[ + TopicMenuItem( + name="plugin_api_introduction", + title=_("Check plug-in API introduction"), + url=doc_reference_url(DocReference.DEVEL_CHECK_PLUGINS), + target="_blank", + sort_index=10, + icon={ + "icon": "services_green", + "emblem": "api", + }, + ), + TopicMenuItem( + name="plugin_api_reference", + title=_("Plug-in API references"), + url="plugin-api/", + target="_blank", + sort_index=20, + icon={ + "icon": "services_green", + "emblem": "api", + }, + ), + TopicMenuItem( + name="rest_api_introduction", + title=_("REST API introduction"), + url=doc_reference_url(DocReference.REST_API), + target="_blank", + sort_index=30, + icon={ + "icon": "global_settings", + "emblem": "api", + }, + ), + TopicMenuItem( + name="rest_api_documentation", + title=_("REST API documentation"), + url="openapi/", + target="_blank", + sort_index=40, + icon={ + "icon": "global_settings", + "emblem": "api", + }, + ), + TopicMenuItem( + name="rest_api_interactive_gui", + title=_("REST API interactive GUI"), + url="api/1.0/ui/", + target="_blank", + sort_index=50, + icon={ + "icon": "global_settings", + "emblem": "api", + }, + ), + ], + ), + TopicMenuTopic( + name="about_checkmk", + title=_("About Checkmk"), + icon="about_checkmk", + items=[ + TopicMenuItem( + name="info", + title=_("Info"), + url="info.py", + sort_index=10, + icon="checkmk_logo_min", + ), + TopicMenuItem( + name="change_log", + title=_("Change log (Werks)"), + url="change_log.py", + sort_index=20, + icon="checkmk_logo_min", + ), + ], + ), + ] + + +def _license_status() -> HTML | str: + status_message: HTML | str = get_license_message() + if not status_message: + return "" + if user.may("wato.licensing"): + status_message = HTMLWriter.render_a( + status_message, + makeuri_contextless(request, [("mode", "licensing")], filename="wato.py"), + target="main", + ) + return HTMLWriter.render_br() + status_message diff --git a/cmk/gui/hooks.py b/cmk/gui/hooks.py index e2e9b1dc8bd..659a96f8852 100644 --- a/cmk/gui/hooks.py +++ b/cmk/gui/hooks.py @@ -84,6 +84,9 @@ def call(name: str, *args: Any) -> None: try: hook.handler(*args) except Exception as e: + # for builtin hooks do not change exception handling + if hook.is_builtin: + raise t, v, tb = sys.exc_info() msg = "".join(traceback.format_exception(t, v, tb, None)) raise MKGeneralException(msg) from e diff --git a/cmk/gui/inventory/__init__.py b/cmk/gui/inventory/__init__.py index 49528141925..b5f053b0d96 100644 --- a/cmk/gui/inventory/__init__.py +++ b/cmk/gui/inventory/__init__.py @@ -21,7 +21,7 @@ import cmk.utils.paths from cmk.utils.hostaddress import HostAddress, HostName -from cmk.utils.structured_data import SDRawTree +from cmk.utils.structured_data import SDRawTree, serialize_tree from cmk.gui import sites from cmk.gui.config import active_config @@ -185,11 +185,10 @@ def _inventory_of_host(host_name: HostName, api_request: dict[str, Any]) -> SDRa tree = load_filtered_and_merged_tree(get_status_data_via_livestatus(site, host_name)) if "paths" in api_request: - return tree.filter( - make_filter_choices_from_api_request_paths(api_request["paths"]) - ).serialize() - - return tree.serialize() + return serialize_tree( + tree.filter(make_filter_choices_from_api_request_paths(api_request["paths"])) + ) + return serialize_tree(tree) def _write_json(resp): diff --git a/cmk/gui/inventory/_history.py b/cmk/gui/inventory/_history.py index ec755363ce7..c0e9fbf11e7 100644 --- a/cmk/gui/inventory/_history.py +++ b/cmk/gui/inventory/_history.py @@ -6,21 +6,28 @@ from collections.abc import Callable, Sequence from dataclasses import dataclass, field from pathlib import Path -from typing import NamedTuple from cmk.ccc import store from cmk.ccc.exceptions import MKGeneralException import cmk.utils.paths from cmk.utils.hostaddress import HostName -from cmk.utils.structured_data import ImmutableDeltaTree, ImmutableTree, load_tree, SDFilterChoice +from cmk.utils.structured_data import ( + deserialize_delta_tree, + ImmutableDeltaTree, + ImmutableTree, + load_tree, + SDFilterChoice, + serialize_delta_tree, +) from cmk.gui.i18n import _ from ._tree import _get_permitted_inventory_paths, make_filter_choices_from_permitted_paths -class InventoryHistoryPath(NamedTuple): +@dataclass(frozen=True) +class InventoryHistoryPath: path: Path timestamp: int | None @@ -29,7 +36,8 @@ def short(self) -> Path: return self.path.relative_to(cmk.utils.paths.omd_root) -class HistoryEntry(NamedTuple): +@dataclass(frozen=True) +class HistoryEntry: timestamp: int | None new: int changed: int @@ -37,7 +45,8 @@ class HistoryEntry(NamedTuple): delta_tree: ImmutableDeltaTree -class FilteredInventoryHistoryPaths(NamedTuple): +@dataclass(frozen=True) +class FilteredInventoryHistoryPaths: start_tree_path: InventoryHistoryPath tree_paths: Sequence[InventoryHistoryPath] @@ -262,7 +271,7 @@ def get_cached_entry(self) -> HistoryEntry | None: new, changed, removed, - ImmutableDeltaTree.deserialize(raw_delta_tree), + deserialize_delta_tree(raw_delta_tree), ) def get_calculated_or_store_entry( @@ -278,7 +287,7 @@ def get_calculated_or_store_entry( if new or changed or removed: store.save_text_to_file( self._path, - repr((new, changed, removed, delta_tree.serialize())), + repr((new, changed, removed, serialize_delta_tree(delta_tree))), ) return self._make_history_entry(new, changed, removed, delta_tree) return None diff --git a/cmk/gui/inventory/_tree.py b/cmk/gui/inventory/_tree.py index 3b2dd23b958..77cbde3f4b7 100644 --- a/cmk/gui/inventory/_tree.py +++ b/cmk/gui/inventory/_tree.py @@ -15,6 +15,7 @@ import cmk.utils.paths from cmk.utils.hostaddress import HostName from cmk.utils.structured_data import ( + deserialize_tree, ImmutableTree, load_tree, parse_visible_raw_path, @@ -195,9 +196,7 @@ def load_filtered_and_merged_tree(row: Row) -> ImmutableTree: host_name = row.get("host_name") inventory_tree = _load_tree_from_file(tree_type="inventory", host_name=host_name) if raw_status_data_tree := row.get("host_structured_status"): - status_data_tree = ImmutableTree.deserialize( - ast.literal_eval(raw_status_data_tree.decode("utf-8")) - ) + status_data_tree = deserialize_tree(ast.literal_eval(raw_status_data_tree.decode("utf-8"))) else: status_data_tree = _load_tree_from_file(tree_type="status_data", host_name=host_name) diff --git a/cmk/gui/main_menu.py b/cmk/gui/main_menu.py index e93e8647cca..e8d66978aab 100644 --- a/cmk/gui/main_menu.py +++ b/cmk/gui/main_menu.py @@ -9,21 +9,8 @@ """ from cmk.ccc.plugin_registry import Registry -from cmk.ccc.version import __version__, Edition, edition -from cmk.utils import paths -from cmk.utils.licensing.registry import get_license_message - -if edition(paths.omd_root) is Edition.CSE: - from cmk.gui.cse.utils.roles import user_may_see_saas_onboarding - -from cmk.gui.htmllib.generator import HTMLWriter -from cmk.gui.http import request -from cmk.gui.i18n import _, _l -from cmk.gui.logged_in import user -from cmk.gui.type_defs import MegaMenu, TopicMenuItem, TopicMenuTopic -from cmk.gui.utils.html import HTML -from cmk.gui.utils.urls import doc_reference_url, DocReference, makeuri_contextless +from cmk.gui.type_defs import MegaMenu, TopicMenuTopic def any_show_more_items(topics: list[TopicMenuTopic]) -> bool: @@ -75,164 +62,3 @@ def menu_user(self) -> MegaMenu: mega_menu_registry = MegaMenuRegistry() - - -def _help_menu_topics() -> list[TopicMenuTopic]: - learning_items = [ - TopicMenuItem( - name="beginners_guide", - title=_("Beginner's guide"), - url=doc_reference_url(DocReference.INTRO_WELCOME), - target="_blank", - sort_index=20, - icon="learning_beginner", - ), - TopicMenuItem( - name="user_manual", - title=_("User manual"), - url=doc_reference_url(), - target="_blank", - sort_index=30, - icon="learning_guide", - ), - TopicMenuItem( - name="video_tutorials", - title=_("Video tutorials"), - url="https://www.youtube.com/playlist?list=PL8DfRO2DvOK1slgjfTu0hMOnepf1F7ssh", - target="_blank", - sort_index=40, - icon="learning_video_tutorials", - ), - TopicMenuItem( - name="community_forum", - title=_("Community forum"), - url="https://forum.checkmk.com/", - target="_blank", - sort_index=50, - icon="learning_forum", - ), - ] - - if edition(paths.omd_root) == Edition.CSE and user_may_see_saas_onboarding(user.id): - learning_items.append( - TopicMenuItem( - name="getting_started", title=_("Getting started"), sort_index=10, url="" - ), - ) - - return [ - TopicMenuTopic( - name="learning_checkmk", - title=_("Learning Checkmk"), - icon="learning_checkmk", - items=learning_items, - ), - TopicMenuTopic( - name="developer_resources", - title=_("Developer resources"), - icon="developer_resources", - items=[ - TopicMenuItem( - name="plugin_api_introduction", - title=_("Check plug-in API introduction"), - url=doc_reference_url(DocReference.DEVEL_CHECK_PLUGINS), - target="_blank", - sort_index=10, - icon={ - "icon": "services_green", - "emblem": "api", - }, - ), - TopicMenuItem( - name="plugin_api_reference", - title=_("Plug-in API references"), - url="plugin-api/", - target="_blank", - sort_index=20, - icon={ - "icon": "services_green", - "emblem": "api", - }, - ), - TopicMenuItem( - name="rest_api_introduction", - title=_("REST API introduction"), - url=doc_reference_url(DocReference.REST_API), - target="_blank", - sort_index=30, - icon={ - "icon": "global_settings", - "emblem": "api", - }, - ), - TopicMenuItem( - name="rest_api_documentation", - title=_("REST API documentation"), - url="openapi/", - target="_blank", - sort_index=40, - icon={ - "icon": "global_settings", - "emblem": "api", - }, - ), - TopicMenuItem( - name="rest_api_interactive_gui", - title=_("REST API interactive GUI"), - url="api/1.0/ui/", - target="_blank", - sort_index=50, - icon={ - "icon": "global_settings", - "emblem": "api", - }, - ), - ], - ), - TopicMenuTopic( - name="about_checkmk", - title=_("About Checkmk"), - icon="about_checkmk", - items=[ - TopicMenuItem( - name="info", - title=_("Info"), - url="info.py", - sort_index=10, - icon="checkmk_logo_min", - ), - TopicMenuItem( - name="change_log", - title=_("Change log (Werks)"), - url="change_log.py", - sort_index=20, - icon="checkmk_logo_min", - ), - ], - ), - ] - - -mega_menu_registry.register( - MegaMenu( - name="help_links", - title=_l("Help"), - icon="main_help", - sort_index=18, - topics=_help_menu_topics, - info_line=lambda: f"{edition(paths.omd_root).title} {__version__}{license_status()}", - ) -) - - -def license_status() -> HTML | str: - status_message: HTML | str = get_license_message() - if not status_message: - return "" - if user.may("wato.licensing"): - status_message = HTMLWriter.render_a( - status_message, - makeuri_contextless(request, [("mode", "licensing")], filename="wato.py"), - target="main", - ) - return HTMLWriter.render_br() + status_message diff --git a/cmk/gui/mkeventd/_filters.py b/cmk/gui/mkeventd/_filters.py index c15d8bfc383..a23c2e07a46 100644 --- a/cmk/gui/mkeventd/_filters.py +++ b/cmk/gui/mkeventd/_filters.py @@ -27,7 +27,7 @@ RegexFilter, ) -from .defines import phase_names, syslog_priorities +from .defines import action_whats, phase_names, syslog_priorities def register(filter_registry: FilterRegistry) -> None: @@ -205,6 +205,19 @@ def register(filter_registry: FilterRegistry) -> None: ) ) + filter_registry.register( + CheckboxRowFilter( + title=_l("History action type"), + sort_index=225, + info="history", + query_filter=query_filters.MultipleOptionsQuery( + ident="history_what", + options=[("history_what_%s" % k, k) for k in action_whats], + livestatus_query=partial(query_filters.options_toggled_filter, "history_what"), + ), + ) + ) + filter_registry.register( FilterTime( title=_l("First occurrence of event"), diff --git a/cmk/gui/mkeventd/registration.py b/cmk/gui/mkeventd/registration.py index 838e87b031e..c79a8dde174 100644 --- a/cmk/gui/mkeventd/registration.py +++ b/cmk/gui/mkeventd/registration.py @@ -20,6 +20,7 @@ ConfigVariableRegistry, SampleConfigGeneratorRegistry, ) +from cmk.gui.watolib.config_sync import ReplicationPathRegistry from cmk.gui.watolib.groups import ContactGroupUsageFinderRegistry from cmk.gui.watolib.main_menu import MainModuleRegistry from cmk.gui.watolib.mode import ModeRegistry @@ -66,6 +67,7 @@ def register( contact_group_usage_finder_registry: ContactGroupUsageFinderRegistry, timeperiod_usage_finder_registry: TimeperiodUsageFinderRegistry, endpoint_registry: EndpointRegistry, + replication_path_registry: ReplicationPathRegistry, ) -> None: views.register( data_source_registry, @@ -86,6 +88,7 @@ def register( rulespec_registry, match_item_generator_registry, notification_parameter_registry, + replication_path_registry, ) permission_section_registry.register(PermissionSectionEventConsole) config_domain_registry.register(ConfigDomainEventConsole) diff --git a/cmk/gui/mkeventd/views.py b/cmk/gui/mkeventd/views.py index 30d49a4e940..74d55ee596f 100644 --- a/cmk/gui/mkeventd/views.py +++ b/cmk/gui/mkeventd/views.py @@ -43,13 +43,18 @@ ) from cmk.gui.utils import escaping from cmk.gui.utils.html import HTML -from cmk.gui.utils.speaklater import LazyString from cmk.gui.utils.theme import Theme from cmk.gui.utils.transaction_manager import transactions from cmk.gui.utils.urls import makeactionuri, makeuri_contextless, urlencode_vars from cmk.gui.valuespec import MonitoringState from cmk.gui.view_utils import CellSpec -from cmk.gui.views.command import Command, CommandActionResult, CommandRegistry, CommandSpec +from cmk.gui.views.command import ( + Command, + CommandActionResult, + CommandGroupVarious, + CommandRegistry, + CommandSpec, +) from cmk.gui.views.sorter import ( cmp_custom_variable, cmp_num_split, @@ -1277,10 +1282,6 @@ def render(self, row: Row, cell: Cell) -> CellSpec: class ECCommand(Command): - @property - def tables(self) -> list[str]: - return ["event"] - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: return HTML.with_escaping( _("Affected %s: %s") @@ -1301,84 +1302,79 @@ def executor(self, command: CommandSpec, site: SiteId | None) -> None: execute_command(command, site=site) -class CommandECUpdateEvent(ECCommand): - @property - def ident(self) -> str: - return "ec_update_event" - - @property - def title(self) -> str: - return _("Update & acknowledge") - - @property - def confirm_title(self) -> str: - return ( - _("Update & acknowledge event?") - if request.var("_mkeventd_acknowledge") - else _("Update event?") - ) - - @property - def confirm_button(self) -> LazyString: - return _l("Update & acknowledge") if request.var("_mkeventd_acknowledge") else _l("Update") - - @property - def permission(self) -> Permission: - return PermissionECUpdateEvent - - def render(self, what: str) -> None: - html.open_table(border="0", cellpadding="0", cellspacing="3") - if user.may("mkeventd.update_comment"): - html.open_tr() - html.td(_("Change comment:")) - html.open_td() - html.text_input("_mkeventd_comment", size=50) - html.close_td() - html.close_tr() - if user.may("mkeventd.update_contact"): - html.open_tr() - html.td(_("Change contact:")) - html.open_td() - html.text_input("_mkeventd_contact", size=50) - html.close_td() - html.close_tr() +def command_update_event_render(what: str) -> None: + html.open_table(border="0", cellpadding="0", cellspacing="3") + if user.may("mkeventd.update_comment"): html.open_tr() - html.td("") + html.td(_("Change comment:")) html.open_td() - html.checkbox("_mkeventd_acknowledge", True, label=_("Set event to acknowledged")) + html.text_input("_mkeventd_comment", size=50) html.close_td() html.close_tr() - html.close_table() - html.open_div(class_="group") - html.button("_mkeventd_update", _("Update"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_mkeventd_update"): - if user.may("mkeventd.update_comment"): - comment = ( - request.get_str_input_mandatory("_mkeventd_comment").strip().replace(";", ",") - ) - else: - comment = "" - if user.may("mkeventd.update_contact"): - contact = ( - request.get_str_input_mandatory("_mkeventd_contact").strip().replace(":", ",") - ) - else: - contact = "" - ack = html.get_checkbox("_mkeventd_acknowledge") - events = ",".join(str(entry["event_id"]) for entry in action_rows) - return ( - f"UPDATE;{events};{user.id};{ack and 1 or 0};{comment};{contact}", - self.confirm_dialog_options(cmdtag, row, len(action_rows)), - ) - return None + if user.may("mkeventd.update_contact"): + html.open_tr() + html.td(_("Change contact:")) + html.open_td() + html.text_input("_mkeventd_contact", size=50) + html.close_td() + html.close_tr() + html.open_tr() + html.td("") + html.open_td() + html.checkbox("_mkeventd_acknowledge", True, label=_("Set event to acknowledged")) + html.close_td() + html.close_tr() + html.close_table() + html.open_div(class_="group") + html.button("_mkeventd_update", _("Update"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_update_event_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_mkeventd_update"): + if user.may("mkeventd.update_comment"): + comment = request.get_str_input_mandatory("_mkeventd_comment").strip().replace(";", ",") + else: + comment = "" + if user.may("mkeventd.update_contact"): + contact = request.get_str_input_mandatory("_mkeventd_contact").strip().replace(":", ",") + else: + contact = "" + ack = html.get_checkbox("_mkeventd_acknowledge") + events = ",".join(str(entry["event_id"]) for entry in action_rows) + return ( + f"UPDATE;{events};{user.id};{ack and 1 or 0};{comment};{contact}", + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + return None +CommandECUpdateEvent = ECCommand( + ident="ec_update_event", + title=_l("Update & acknowledge"), + confirm_title=lambda: ( + _l("Update & acknowledge event?") + if request.var("_mkeventd_acknowledge") + else _l("Update event?") + ), + confirm_button=lambda: ( + _l("Update & acknowledge") if request.var("_mkeventd_acknowledge") else _l("Update") + ), + permission=PermissionECUpdateEvent, + group=CommandGroupVarious, + tables=["event"], + render=command_update_event_render, + action=command_update_event_action, +) + PermissionECChangeEventState = Permission( section=PermissionSectionEventConsole, name="changestate", @@ -1391,68 +1387,66 @@ def _action( ) -class CommandECChangeState(ECCommand): - @property - def ident(self) -> str: - return "ec_change_state" +def command_change_state_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + value = MonitoringState().from_html_vars("_mkeventd_state") + assert value is not None + return ( + HTMLWriter.render_br() + + HTMLWriter.render_br() + + _("New state: %s") + % { + 0: _("OK"), + 1: _("WARN"), + 2: _("CRIT"), + 3: _("UNKNOWN"), + }[value] + ) - @property - def title(self) -> str: - return _("Change state") - @property - def confirm_title(self) -> str: - return _("Change event state?") +def command_change_state_render(what: str) -> None: + MonitoringState(label="Select new event state").render_input("_mkeventd_state", 2) + html.br() + html.br() + html.open_div(class_="group") + html.button("_mkeventd_changestate", _("Change state"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def confirm_button(self) -> LazyString: - return _l("Change") - - @property - def permission(self) -> Permission: - return PermissionECChangeEventState - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - value = MonitoringState().from_html_vars("_mkeventd_state") - assert value is not None +def command_change_state_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_mkeventd_changestate"): + events = ",".join(str(entry["event_id"]) for entry in action_rows) + state = MonitoringState().from_html_vars("_mkeventd_state") return ( - HTMLWriter.render_br() - + HTMLWriter.render_br() - + _("New state: %s") - % { - 0: _("OK"), - 1: _("WARN"), - 2: _("CRIT"), - 3: _("UNKNOWN"), - }[value] + f"CHANGESTATE;{events};{user.id};{state}", + command.confirm_dialog_options(cmdtag, row, action_rows), ) - - def render(self, what: str) -> None: - MonitoringState(label="Select new event state").render_input("_mkeventd_state", 2) - html.br() - html.br() - html.open_div(class_="group") - html.button("_mkeventd_changestate", _("Change state"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_mkeventd_changestate"): - events = ",".join(str(entry["event_id"]) for entry in action_rows) - state = MonitoringState().from_html_vars("_mkeventd_state") - return ( - f"CHANGESTATE;{events};{user.id};{state}", - self.confirm_dialog_options(cmdtag, row, len(action_rows)), - ) - return None - + return None + + +CommandECChangeState = ECCommand( + ident="ec_change_state", + title=_l("Change state"), + confirm_title=_l("Change event state?"), + confirm_button=_l("Change"), + permission=PermissionECChangeEventState, + group=CommandGroupVarious, + tables=["event"], + render=command_change_state_render, + action=command_change_state_action, + confirm_dialog_additions=command_change_state_confirm_dialog_additions, +) PermissionECCustomActions = Permission( section=PermissionSectionEventConsole, @@ -1466,48 +1460,47 @@ def _action( ) -class CommandECCustomAction(ECCommand): - @property - def ident(self) -> str: - return "ec_custom_actions" - - @property - def title(self) -> str: - return _("Custom action") - - @property - def confirm_title(self) -> str: - return _("Execute custom action '%s'?") % list(request.itervars(prefix="_action_"))[0][1] - - @property - def confirm_button(self) -> LazyString: - return _l("Execute") +def command_custom_actions_render(what: str) -> None: + html.open_div(class_="group") + for action_id, title in action_choices(omit_hidden=True): + html.button("_action_" + action_id, title, cssclass="border_hot") + html.br() + html.br() + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def permission(self) -> Permission: - return PermissionECCustomActions - def render(self, what: str) -> None: - html.open_div(class_="group") - for action_id, title in action_choices(omit_hidden=True): - html.button("_action_" + action_id, title, cssclass="border_hot") - html.br() - html.br() - html.button("_cancel", _("Cancel")) - html.close_div() +def command_custom_actions_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + for action_id, _title in action_choices(omit_hidden=True): + if request.var("_action_" + action_id): + events = ",".join(str(entry["event_id"]) for entry in action_rows) + return ( + f"ACTION;{events};{user.id};{action_id}", + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + return None - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - for action_id, _title in action_choices(omit_hidden=True): - if request.var("_action_" + action_id): - events = ",".join(str(entry["event_id"]) for entry in action_rows) - return ( - f"ACTION;{events};{user.id};{action_id}", - self.confirm_dialog_options(cmdtag, row, len(action_rows)), - ) - return None +CommandECCustomAction = ECCommand( + ident="ec_custom_actions", + title=_l("Custom action"), + confirm_title=lambda: ( + _l("Execute custom action '%s'?") % list(request.itervars(prefix="_action_"))[0][1] + ), + confirm_button=_l("Execute"), + permission=PermissionECCustomActions, + group=CommandGroupVarious, + tables=["event"], + render=command_custom_actions_render, + action=command_custom_actions_action, +) PermissionECArchiveEvent = Permission( section=PermissionSectionEventConsole, @@ -1518,42 +1511,39 @@ def _action( ) -class CommandECArchiveEvent(ECCommand): - @property - def ident(self) -> str: - return "ec_archive_event" - - @property - def title(self) -> str: - return _("Archive event") - - @property - def confirm_title(self) -> str: - return "%s?" % self.title - - @property - def confirm_button(self) -> LazyString: - return _l("Archive") - - @property - def permission(self) -> Permission: - return PermissionECArchiveEvent - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_delete_event", _("Archive Event"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() +def command_archive_event_render(what: str) -> None: + html.open_div(class_="group") + html.button("_delete_event", _("Archive Event"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_delete_event"): - events = ",".join(str(entry["event_id"]) for entry in action_rows) - command = f"DELETE;{events};{user.id}" - return command, self.confirm_dialog_options(cmdtag, row, len(action_rows)) - return None +def command_archive_event_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_delete_event"): + events = ",".join(str(entry["event_id"]) for entry in action_rows) + cmd = f"DELETE;{events};{user.id}" + return cmd, command.confirm_dialog_options(cmdtag, row, action_rows) + return None + + +CommandECArchiveEvent = ECCommand( + ident="ec_archive_event", + title=_l("Archive event"), + confirm_title=_l("Archive event?"), + confirm_button=_l("Archive"), + permission=PermissionECArchiveEvent, + group=CommandGroupVarious, + tables=["event"], + render=command_archive_event_render, + action=command_archive_event_action, +) PermissionECArchiveEventsOfHost = Permission( section=PermissionSectionEventConsole, @@ -1564,69 +1554,61 @@ def _action( ) -class CommandECArchiveEventsOfHost(ECCommand): - @property - def ident(self) -> str: - return "ec_archive_events_of_host" - - @property - def title(self) -> str: - return _("Archive events of hosts") - - @property - def confirm_title(self) -> str: - return _("Archive all events of this host?") - - @property - def confirm_button(self) -> LazyString: - return _l("Archive") - - @property - def permission(self) -> Permission: - return PermissionECArchiveEventsOfHost - - @property - def tables(self) -> list[str]: - return ["service"] +def command_archive_events_of_host_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + return HTML.empty() + _( + "All events of the host '%s' will be removed from the open events list. You can still access them in the archive." + ) % request.var("host") + + +def command_archive_events_of_host_render(what: str) -> None: + html.help( + _( + "Note: With this command you can archive all events of one host. " + 'Needs a rule "Check event state in Event Console" to be ' + "configured." + ) + ) + html.open_div(class_="group") + html.button("_archive_events_of_hosts", _("Archive events"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - return HTML.empty() + _( - "All events of the host '%s' will be removed from the open events list. You can still access them in the archive." - ) % request.var("host") - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: - return HTML.empty() - - def render(self, what: str) -> None: - html.help( - _( - "Note: With this command you can archive all events of one host. " - 'Needs a rule "Check event state in Event Console" to be ' - "configured." - ) +def command_archive_events_of_host_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_archive_events_of_hosts"): + commands = [f"DELETE_EVENTS_OF_HOST;{row['host_name']};{user.id}"] + return ( + commands, + command.confirm_dialog_options(cmdtag, row, action_rows), ) - html.open_div(class_="group") - html.button("_archive_events_of_hosts", _("Archive events"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_archive_events_of_hosts"): - commands = [f"DELETE_EVENTS_OF_HOST;{row['host_name']};{user.id}"] - return ( - commands, - self.confirm_dialog_options(cmdtag, row, len(action_rows)), - ) - return None + return None +CommandECArchiveEventsOfHost = ECCommand( + ident="ec_archive_events_of_host", + title=_l("Archive events of hosts"), + confirm_title=_l("Archive all events of this host?"), + confirm_button=_l("Archive"), + permission=PermissionECArchiveEventsOfHost, + group=CommandGroupVarious, + tables=["service"], + render=command_archive_events_of_host_render, + action=command_archive_events_of_host_action, + confirm_dialog_additions=command_archive_events_of_host_confirm_dialog_additions, + affected_output_cb=lambda _a, _b: HTML.empty(), +) + # . # .--Sorters-------------------------------------------------------------. # | ____ _ | diff --git a/cmk/gui/mkeventd/wato.py b/cmk/gui/mkeventd/wato.py index 6700050c928..8f4df2235a5 100644 --- a/cmk/gui/mkeventd/wato.py +++ b/cmk/gui/mkeventd/wato.py @@ -143,6 +143,7 @@ SampleConfigGeneratorRegistry, ) from cmk.gui.watolib.config_domains import ConfigDomainGUI, ConfigDomainOMD +from cmk.gui.watolib.config_sync import ReplicationPath, ReplicationPathRegistry from cmk.gui.watolib.config_variable_groups import ( ConfigVariableGroupNotifications, ConfigVariableGroupSiteManagement, @@ -194,6 +195,7 @@ def register( rulespec_registry: RulespecRegistry, match_item_generator_registry: MatchItemGeneratorRegistry, notification_parameter_registry: NotificationParameterRegistry, + replication_path_registry: ReplicationPathRegistry, ) -> None: sample_config_generator_registry.register(SampleConfigGeneratorECSampleRulepack) @@ -267,6 +269,21 @@ def register( hooks.register_builtin("pre-activate-changes", mkeventd_update_notification_configuration) + replication_path_registry.register( + ReplicationPath( + "dir", "mkeventd", str(ec.rule_pack_dir().relative_to(cmk.utils.paths.omd_root)), [] + ) + ) + + replication_path_registry.register( + ReplicationPath( + "dir", + "mkeventd_mkp", + str(ec.mkp_rule_pack_dir().relative_to(cmk.utils.paths.omd_root)), + [], + ) + ) + def _compiled_mibs_dir() -> Path: return cmk.utils.paths.omd_root / "local/share/check_mk/compiled_mibs" diff --git a/cmk/gui/mobile/pages.py b/cmk/gui/mobile/pages.py index f18d2c55df2..52c6cf9def4 100644 --- a/cmk/gui/mobile/pages.py +++ b/cmk/gui/mobile/pages.py @@ -484,11 +484,10 @@ def _show_command_form(datasource: ABCDataSource, rows: Rows) -> None: one_shown = False html.open_div(**{"data-role": "collapsible-set"}) - for command_class in command_registry.values(): - command = command_class() + for command in command_registry.values(): if what in command.tables and user.may(command.permission.name): html.open_div(class_=["command_group"], **{"data-role": "collapsible"}) - html.h3(command.title) + html.h3(str(command.title)) html.open_p() with html.form_context("actions"): diff --git a/cmk/gui/openapi/endpoints/contact_group_config/request_schemas.py b/cmk/gui/openapi/endpoints/contact_group_config/request_schemas.py index eba42b6ea2d..b3c51aff47f 100644 --- a/cmk/gui/openapi/endpoints/contact_group_config/request_schemas.py +++ b/cmk/gui/openapi/endpoints/contact_group_config/request_schemas.py @@ -21,7 +21,7 @@ class UpdateContactGroupAttributes(BaseSchema): inventory_paths = fields.Nested( InventoryPaths, required=False, - description="Permitted HW/SW inventory paths.", + description="Permitted HW/SW Inventory paths.", example={"type": "allow_all"}, ) customer = gui_fields.customer_field( @@ -50,7 +50,7 @@ class InputContactGroup(BaseSchema): inventory_paths = fields.Nested( InventoryPaths, load_default=lambda: {"type": "allow_all"}, - description="Permitted HW/SW inventory paths.", + description="Permitted HW/SW Inventory paths.", example={"type": "allow_all"}, ) customer = gui_fields.customer_field( diff --git a/cmk/gui/openapi/endpoints/contact_group_config/response_schemas.py b/cmk/gui/openapi/endpoints/contact_group_config/response_schemas.py index c237f1a5a6f..5bf9a4f670e 100644 --- a/cmk/gui/openapi/endpoints/contact_group_config/response_schemas.py +++ b/cmk/gui/openapi/endpoints/contact_group_config/response_schemas.py @@ -14,7 +14,7 @@ class ContactGroupExtensions(BaseSchema): customer = customer_field_response() inventory_paths = fields.Nested( InventoryPaths, - description="Permitted HW/SW inventory paths.", + description="Permitted HW/SW Inventory paths.", ) diff --git a/cmk/gui/openapi/endpoints/quick_setup/__init__.py b/cmk/gui/openapi/endpoints/quick_setup/__init__.py index 7a8aa6653ce..da3d4ab13ab 100644 --- a/cmk/gui/openapi/endpoints/quick_setup/__init__.py +++ b/cmk/gui/openapi/endpoints/quick_setup/__init__.py @@ -153,18 +153,28 @@ def complete_quick_setup_action(params: Mapping[str, Any]) -> Response: """Save the quick setup""" body = params["body"] quick_setup_id = params["quick_setup_id"] + button_id = body["button_id"] quick_setup = quick_setup_registry.get(quick_setup_id) if quick_setup is None: return _serve_error( title="Quick setup not found", detail=f"Quick setup with id '{quick_setup_id}' does not exist.", ) - return _serve_data( - data=complete_quick_setup( - quick_setup=quick_setup, - stages_raw_formspecs=[RawFormData(stage["form_data"]) for stage in body["stages"]], - ), - status_code=201, + for save_action in quick_setup.save_actions: + if save_action.id == button_id: + return _serve_data( + complete_quick_setup( + quick_setup=quick_setup, + save_action=save_action, + stages_raw_formspecs=[ + RawFormData(stage["form_data"]) for stage in body["stages"] + ], + ), + status_code=201, + ) + return _serve_error( + title="Save action not found", + detail=f"Save action with id '{button_id}' does not exist.", ) diff --git a/cmk/gui/openapi/endpoints/quick_setup/request_schemas.py b/cmk/gui/openapi/endpoints/quick_setup/request_schemas.py index 750702aeb3a..f1e42a9569e 100644 --- a/cmk/gui/openapi/endpoints/quick_setup/request_schemas.py +++ b/cmk/gui/openapi/endpoints/quick_setup/request_schemas.py @@ -36,6 +36,11 @@ class QuickSetupRequest(BaseSchema): class QuickSetupFinalSaveRequest(BaseSchema): + button_id = fields.String( + required=True, + description="Unique id of the save button clicked by the user", + example="save", + ) stages = fields.List( fields.Nested( QuickSetupStageRequest, diff --git a/cmk/gui/openapi/endpoints/quick_setup/response_schemas.py b/cmk/gui/openapi/endpoints/quick_setup/response_schemas.py index 4365851a3db..a730b48b04d 100644 --- a/cmk/gui/openapi/endpoints/quick_setup/response_schemas.py +++ b/cmk/gui/openapi/endpoints/quick_setup/response_schemas.py @@ -33,6 +33,17 @@ class Errors(BaseSchema): ) +class QuickSetupCompleteButton(BaseSchema): + id = fields.String( + example="save", + description="The button id", + ) + label = fields.String( + example="Save configuration", + description="The label of the complete button of the overall Quick setup", + ) + + class QuickSetupNextStageStructure(BaseSchema): components = fields.List( fields.Dict, @@ -92,9 +103,10 @@ class QuickSetupBaseResponse(BaseSchema): example="aws_quicksetup", description="The quicksetup id", ) - button_complete_label = fields.String( - example="Save configuration", - description="The label of the complete button of the overall Quick setup", + complete_buttons = fields.List( + fields.Nested(QuickSetupCompleteButton), + example=[{"id": "save", "label": "Save configuration"}], + description="A list of all complete buttons", ) diff --git a/cmk/gui/page_menu.py b/cmk/gui/page_menu.py index 9a8c9a77842..8ddf66d4f0f 100644 --- a/cmk/gui/page_menu.py +++ b/cmk/gui/page_menu.py @@ -121,28 +121,57 @@ def make_confirmed_form_submit_link( ) +def show_success_dialog( + title: str, + confirm_url: str, + message: str | HTML | None = None, + confirm_text: str | None = None, +) -> None: + dialog_options = { + "title": title, + "html": escaping.escape_text(message), + "confirmButtonText": confirm_text if confirm_text else _("Confirm"), + "customClass": { + "confirmButton": "confirm_success", + "icon": "confirm_icon" + " confirm_success", + }, + "showCancelButton": False, + "iconHtml": "", + } + + html.javascript( + "cmk.forms.confirm_dialog(%s, ()=>{location.href = %s;})" + % ( + json.dumps(dialog_options), + json.dumps(confirm_url), + ) + ) + + def show_confirm_cancel_dialog( title: str, confirm_url: str, cancel_url: str | None = None, message: str | HTML | None = None, confirm_text: str | None = None, + show_cancel_button: bool = True, ) -> None: + dialog_options = { + "title": title, + "html": escaping.escape_text(message), + "confirmButtonText": confirm_text if confirm_text else _("Confirm"), + "cancelButtonText": _("Cancel"), + "customClass": { + "confirmButton": "confirm_question", + "icon": "confirm_icon" + " confirm_question", + }, + "showCancelButton": show_cancel_button, + } + html.javascript( "cmk.forms.confirm_dialog(%s, ()=>{location.href = %s;}, %s)" % ( - json.dumps( - { - "title": title, - "html": escaping.escape_text(message), - "confirmButtonText": confirm_text if confirm_text else _("Confirm"), - "cancelButtonText": _("Cancel"), - "customClass": { - "confirmButton": "confirm_question", - "icon": "confirm_icon" + " confirm_question", - }, - } - ), + json.dumps(dialog_options), json.dumps(confirm_url), f"()=>{{location.href = {json.dumps(cancel_url)}}}" if cancel_url else "null", ) diff --git a/cmk/gui/pagetypes.py b/cmk/gui/pagetypes.py index 4717ddaf7fc..4ed8de182ce 100644 --- a/cmk/gui/pagetypes.py +++ b/cmk/gui/pagetypes.py @@ -54,7 +54,7 @@ from cmk.gui.http import request from cmk.gui.i18n import _, _l, _u from cmk.gui.logged_in import LoggedInUser, save_user_file, user -from cmk.gui.main_menu import mega_menu_registry +from cmk.gui.main_menu import mega_menu_registry, MegaMenuRegistry from cmk.gui.page_menu import ( doc_reference_to_page_menu, make_confirmed_form_submit_link, @@ -190,6 +190,19 @@ class PagetypeTopicConfig(OverridableConfig): hide: bool = False # TODO: Seems it is not configurable through the UI. Is it OK? +def register(mega_menu_registry_: MegaMenuRegistry) -> None: + mega_menu_registry_.register( + MegaMenu( + name="customize", + title=_l("Customize"), + icon="main_customize", + sort_index=10, + topics=_customize_menu_topics, + hide=hide_customize_menu, + ) + ) + + # .--Base----------------------------------------------------------------. # | ____ | # | | __ ) __ _ ___ ___ | @@ -2378,17 +2391,6 @@ def hide_customize_menu() -> bool: return not any(user.may(perm) for perm in permissions) -mega_menu_registry.register( - MegaMenu( - name="customize", - title=_l("Customize"), - icon="main_customize", - sort_index=10, - topics=_customize_menu_topics, - hide=hide_customize_menu, - ) -) - # .--Permissions---------------------------------------------------------. # | ____ _ _ | # | | _ \ ___ _ __ _ __ ___ (_)___ ___(_) ___ _ __ ___ | diff --git a/cmk/gui/painter/v0/painters.py b/cmk/gui/painter/v0/painters.py index 6df103ee8b1..b25d6cf581f 100644 --- a/cmk/gui/painter/v0/painters.py +++ b/cmk/gui/painter/v0/painters.py @@ -5,7 +5,7 @@ import abc import time -from collections.abc import Callable, Iterable, Mapping, Sequence +from collections.abc import Iterable, Mapping, Sequence from fnmatch import fnmatch from pathlib import Path @@ -4289,30 +4289,6 @@ def render(self, row: Row, cell: Cell) -> CellSpec: return (None, row["downtime_origin"] == 1 and _("configuration") or _("command")) -class PainterDowntimeRecurring(Painter): - # Poor man's composition. CRE and non-CRE have different renderers. - renderer: Callable[[Row, Cell], CellSpec] | None = None - - @property - def ident(self) -> str: - return "downtime_recurring" - - def title(self, cell: Cell) -> str: - return _("Downtime recurring interval") - - def short_title(self, cell: Cell) -> str: - return _("Recurring") - - @property - def columns(self) -> Sequence[ColumnName]: - return ["downtime_recurring"] - - def render(self, row: Row, cell: Cell) -> CellSpec: - renderer = type(self).renderer - assert renderer is not None - return renderer(row, cell) # pylint: disable=not-callable - - class PainterDowntimeWhat(Painter): @property def ident(self) -> str: diff --git a/cmk/gui/plugins/main_modules/registration.py b/cmk/gui/plugins/main_modules/registration.py index adc016583ff..432f2dca340 100644 --- a/cmk/gui/plugins/main_modules/registration.py +++ b/cmk/gui/plugins/main_modules/registration.py @@ -5,14 +5,8 @@ """Central module for common (non-edition specific) registrations""" -from functools import partial - -from livestatus import MultiSiteConnection - from cmk.ccc.crash_reporting import crash_report_registry -from cmk.ccc.version import Edition, edition -from cmk.utils import paths from cmk.utils.licensing.registry import register_cre_licensing_handler import cmk.gui.help @@ -26,7 +20,7 @@ default_permissions, graphing, gui_background_job, - hooks, + help_menu, inventory, login, logwatch, @@ -34,29 +28,23 @@ message, mobile, notifications, + pagetypes, painter_options, piggyback_hub, prediction, - sidebar, - sites, user_message, valuespec, - visuals, weblib, werks, ) from cmk.gui.background_job import job_registry from cmk.gui.background_job import registration as background_job_registration -from cmk.gui.backup.registration import backup_register from cmk.gui.bi import registration as bi_registration from cmk.gui.config import register_post_config_load_hook -from cmk.gui.custom_icons.registration import custom_icons_register from cmk.gui.dashboard import dashlet_registry from cmk.gui.dashboard import registration as dashboard_registration from cmk.gui.data_source import data_source_registry from cmk.gui.main_menu import mega_menu_registry -from cmk.gui.mkeventd import registration as mkeventd_registration -from cmk.gui.mkeventd.helpers import save_active_config from cmk.gui.nodevis import nodevis from cmk.gui.openapi import endpoint_registry from cmk.gui.openapi import registration as openapi_registration @@ -64,7 +52,6 @@ from cmk.gui.painter.v0.base import painter_registry from cmk.gui.painter_options import painter_option_registry from cmk.gui.permissions import permission_registry, permission_section_registry -from cmk.gui.query_filters import cre_sites_options from cmk.gui.quick_setup import registration as quick_setup_registration from cmk.gui.quick_setup.v0_unstable._registry import quick_setup_registry from cmk.gui.sidebar import snapin_registry @@ -85,8 +72,6 @@ from cmk.gui.visuals.filter import filter_registry from cmk.gui.visuals.info import visual_info_registry from cmk.gui.visuals.type import visual_type_registry -from cmk.gui.wato import notification_parameter_registry -from cmk.gui.wato import registration as wato_registration from cmk.gui.watolib import broker_connections as broker_connections_config from cmk.gui.watolib import configuration_bundles, groups_io, password_store from cmk.gui.watolib import notifications as notifications_config @@ -95,7 +80,6 @@ from cmk.gui.watolib import sites as sites_config from cmk.gui.watolib import tags as tag_config from cmk.gui.watolib import users as user_config -from cmk.gui.watolib.analyze_configuration import ac_test_registry from cmk.gui.watolib.automation_commands import automation_command_registry from cmk.gui.watolib.config_domain_name import ( config_domain_registry, @@ -103,6 +87,7 @@ config_variable_registry, sample_config_generator_registry, ) +from cmk.gui.watolib.config_sync import replication_path_registry from cmk.gui.watolib.groups import contact_group_usage_finder_registry from cmk.gui.watolib.host_attributes import host_attribute_registry, host_attribute_topic_registry from cmk.gui.watolib.host_rename import rename_host_hook_registry @@ -114,22 +99,12 @@ from cmk.gui.watolib.timeperiods import timeperiod_usage_finder_registry -def register_sites_options() -> None: - if edition(paths.omd_root) is not Edition.CME: - hooks.register_builtin("mkeventd-activate-changes", save_active_config) - visuals.MultipleSitesFilter.sites_options = cre_sites_options - visuals.SiteFilter.heading_hook = visuals.cre_site_filter_heading_info - - autocompleter_registry.register_autocompleter( - "sites", partial(autocompleters.sites_autocompleter, sites_options=cre_sites_options) - ) - - def register() -> None: + pagetypes.register(mega_menu_registry) + help_menu.register(mega_menu_registry) crash_handler.register(crash_report_registry) default_permissions.register(permission_section_registry, permission_registry) register_cre_licensing_handler() - visuals.register(page_registry, visual_info_registry, filter_registry) painter_options.register(painter_option_registry) views_registration.register( permission_section_registry, @@ -175,6 +150,8 @@ def register() -> None: timeperiod_usage_finder_registry, config_variable_group_registry, autocompleter_registry, + match_item_generator_registry, + replication_path_registry, ) piggyback_hub.register( config_domain_registry, @@ -182,42 +159,6 @@ def register() -> None: config_variable_registry, ) - if edition(paths.omd_root) is not Edition.CSE: # disabled in CSE - backup_register( - page_registry, - mode_registry, - main_module_registry, - ) - mkeventd_registration.register( - permission_section_registry, - permission_registry, - data_source_registry, - painter_registry, - command_registry, - sorter_registry, - icon_and_action_registry, - config_domain_registry, - sample_config_generator_registry, - mode_registry, - main_module_registry, - config_variable_group_registry, - config_variable_registry, - rulespec_group_registry, - rulespec_registry, - autocompleter_registry, - filter_registry, - notification_parameter_registry, - snapin_registry, - contact_group_usage_finder_registry, - timeperiod_usage_finder_registry, - endpoint_registry, - ) - custom_icons_register( - mode_registry, - main_module_registry, - permission_registry, - ) - mobile.register(layout_registry) userdb_registration.register( page_registry, @@ -228,33 +169,6 @@ def register() -> None: timeperiod_usage_finder_registry, ) - if edition(paths.omd_root) is Edition.CSE: - userdb_registration.saas_register(user_attribute_registry) - - wato_registration.register( - page_registry, - painter_registry, - sorter_registry, - icon_and_action_registry, - automation_command_registry, - job_registry, - filter_registry, - mode_registry, - permission_section_registry, - permission_registry, - main_module_topic_registry, - main_module_registry, - rulespec_group_registry, - config_domain_registry, - config_variable_registry, - config_variable_group_registry, - snapin_registry, - match_item_generator_registry, - mega_menu_registry, - ac_test_registry, - contact_group_usage_finder_registry, - notification_parameter_registry, - ) bi_registration.register( data_source_registry, painter_registry, @@ -281,13 +195,11 @@ def register() -> None: autocompleters.register(page_registry, autocompleter_registry) werks.register(page_registry) login.register(page_registry) - sidebar.register(page_registry, permission_section_registry, snapin_registry, dashlet_registry) message.register(page_registry) cmk.gui.help.register(page_registry) main.register(page_registry) logwatch.register(page_registry) prediction.register(page_registry) - register_sites_options() register_row_post_processor(inventory_row_post_processor) register_row_post_processor(join_service_row_post_processor) quick_setup_registration.register(main_module_registry, mode_registry, quick_setup_registry) @@ -297,7 +209,6 @@ def register() -> None: agent_registration.register(permission_section_registry) weblib.register(page_registry) openapi_registration.register(endpoint_registry, job_registry) - sites.ConnectionClass = MultiSiteConnection customer.CustomerAPIClass = customer.CustomerAPIStub register_userroles(config_file_registry) diff --git a/cmk/gui/plugins/wato/check_parameters/apc_ats_output.py b/cmk/gui/plugins/wato/check_parameters/apc_ats_output.py deleted file mode 100644 index 574942c91c9..00000000000 --- a/cmk/gui/plugins/wato/check_parameters/apc_ats_output.py +++ /dev/null @@ -1,75 +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 ( - CheckParameterRulespecWithItem, - rulespec_registry, - RulespecGroupCheckParametersEnvironment, -) -from cmk.gui.valuespec import Dictionary, Integer, Percentage, TextInput, Tuple - - -def _parameter_valuespec_apc_ats_output(): - return Dictionary( - title=_("Levels for ATS output parameters"), - optional_keys=True, - elements=[ - ( - "output_voltage_max", - Tuple( - title=_("Maximum levels for voltage"), - elements=[ - Integer(title=_("Warning at"), unit="Volt"), - Integer(title=_("Critical at"), unit="Volt"), - ], - ), - ), - ( - "output_voltage_min", - Tuple( - title=_("Minimum levels for Voltage"), - elements=[ - Integer(title=_("Warning if below"), unit="Volt"), - Integer(title=_("Critical if below"), unit="Volt"), - ], - ), - ), - ( - "load_perc_max", - Tuple( - title=_("Maximum levels for load in percent"), - elements=[ - Percentage(title=_("Warning at")), - Percentage(title=_("Critical at")), - ], - ), - ), - ( - "load_perc_min", - Tuple( - title=_("Minimum levels for load in percent"), - elements=[ - Percentage(title=_("Warning if below")), - Percentage(title=_("Critical if below")), - ], - ), - ), - ], - ) - - -rulespec_registry.register( - CheckParameterRulespecWithItem( - check_group_name="apc_ats_output", - group=RulespecGroupCheckParametersEnvironment, - item_spec=lambda: TextInput( - title=_("ID of phase"), - ), - match_type="dict", - parameter_valuespec=_parameter_valuespec_apc_ats_output, - title=lambda: _("APC Automatic Transfer Switch Output"), - ) -) diff --git a/cmk/gui/plugins/wato/check_parameters/etherbox.py b/cmk/gui/plugins/wato/check_parameters/etherbox.py index fbbd21566fe..5c3e6980a5d 100644 --- a/cmk/gui/plugins/wato/check_parameters/etherbox.py +++ b/cmk/gui/plugins/wato/check_parameters/etherbox.py @@ -31,34 +31,6 @@ def _item_spec() -> TextInput: ) -def _vs_voltage() -> Dictionary: - return Dictionary( - title=_("Voltage levels"), - elements=[ - ( - "levels", - SimpleLevels( - title=_("Voltage Levels"), - unit="V", - ), - ) - ], - optional_keys=[], - ) - - -rulespec_registry.register( - CheckParameterRulespecWithItem( - check_group_name="etherbox_voltage", - group=RulespecGroupCheckParametersApplications, - match_type="dict", - parameter_valuespec=_vs_voltage, - title=lambda: _("Etherbox voltage"), - item_spec=_item_spec, - ) -) - - def _vs_smoke() -> Dictionary: return Dictionary( title=_("Smoke monitoring"), diff --git a/cmk/gui/plugins/wato/check_parameters/interfaces.py b/cmk/gui/plugins/wato/check_parameters/interfaces.py index 1cd5b8c83c1..3cfcbeeef0c 100644 --- a/cmk/gui/plugins/wato/check_parameters/interfaces.py +++ b/cmk/gui/plugins/wato/check_parameters/interfaces.py @@ -59,7 +59,14 @@ def _vs_item_appearance(title, help_txt): ("alias", _("Use alias")), ], default_value="index", - help=help_txt, + help=help_txt + + _( + "

" + "Important note: When changing this option, the services " + "need to be removed and rediscovered to apply the changes. " + "Otherwise there is a risk of mismatch between the discovered " + "and checked services." + ), ) @@ -742,6 +749,7 @@ def _parameter_valuespec_if() -> Dictionary: "discovered_oper_status", "discovered_admin_status", "discovered_speed", + "item_appearance", ], # Created by discovery elements=[ ( diff --git a/cmk/gui/plugins/wato/check_parameters/plugs.py b/cmk/gui/plugins/wato/check_parameters/plugs.py index f62a852bda9..9db7e0c88fd 100644 --- a/cmk/gui/plugins/wato/check_parameters/plugs.py +++ b/cmk/gui/plugins/wato/check_parameters/plugs.py @@ -50,6 +50,7 @@ def _parameter_valuespec_plugs() -> Dictionary: choices=[ ("on", _("Plug is ON")), ("off", _("Plug is OFF")), + (None, _("State found during service discovery")), ], default_value="on", ), diff --git a/cmk/gui/plugins/wato/special_agents/hivemanager.py b/cmk/gui/plugins/wato/special_agents/hivemanager.py deleted file mode 100644 index b3cd17d5c1e..00000000000 --- a/cmk/gui/plugins/wato/special_agents/hivemanager.py +++ /dev/null @@ -1,35 +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.valuespec import TextInput, Tuple -from cmk.gui.wato import ( - MigrateToIndividualOrStoredPassword, - RulespecGroupDatasourceProgramsHardware, -) -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _valuespec_special_agents_hivemanager(): - return Tuple( - title=_("Aerohive HiveManager"), - help=_("Activate monitoring of host via a HTTP connect to the HiveManager"), - elements=[ - TextInput(title=_("Username")), - MigrateToIndividualOrStoredPassword(title=_("Password")), - ], - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("hivemanager"), - valuespec=_valuespec_special_agents_hivemanager, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/hivemanager_ng.py b/cmk/gui/plugins/wato/special_agents/hivemanager_ng.py deleted file mode 100644 index 1822c996b84..00000000000 --- a/cmk/gui/plugins/wato/special_agents/hivemanager_ng.py +++ /dev/null @@ -1,77 +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.valuespec import Dictionary, HTTPUrl, TextInput -from cmk.gui.wato import ( - MigrateToIndividualOrStoredPassword, - RulespecGroupDatasourceProgramsHardware, -) -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _valuespec_special_agents_hivemanager_ng(): - return Dictionary( - title=_("Aerohive HiveManager NG"), - help=_("Activate monitoring of the HiveManagerNG cloud."), - elements=[ - ( - "url", - HTTPUrl( - title=_("URL to HiveManagerNG, e.g. https://cloud.aerohive.com"), - allow_empty=False, - ), - ), - ( - "vhm_id", - TextInput( - title=_("Numerical ID of the VHM, e.g. 102"), - allow_empty=False, - ), - ), - ( - "api_token", - TextInput( - title=_("API access token"), - size=64, - allow_empty=False, - ), - ), - ( - "client_id", - TextInput( - title=_("Client ID"), - allow_empty=False, - ), - ), - ( - "client_secret", - MigrateToIndividualOrStoredPassword( - title=_("Client secret"), - allow_empty=False, - ), - ), - ( - "redirect_url", - HTTPUrl( - title=_("Redirect URL (has to be https)"), - allow_empty=False, - ), - ), - ], - optional_keys=False, - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("hivemanager_ng"), - valuespec=_valuespec_special_agents_hivemanager_ng, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/hp_msa.py b/cmk/gui/plugins/wato/special_agents/hp_msa.py deleted file mode 100644 index 536881bb70b..00000000000 --- a/cmk/gui/plugins/wato/special_agents/hp_msa.py +++ /dev/null @@ -1,51 +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.valuespec import Dictionary, TextInput -from cmk.gui.wato import ( - MigrateToIndividualOrStoredPassword, - RulespecGroupDatasourceProgramsHardware, -) -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _valuespec_special_agents_hp_msa(): - return Dictionary( - elements=[ - ( - "username", - TextInput( - title=_("Username"), - allow_empty=False, - ), - ), - ( - "password", - MigrateToIndividualOrStoredPassword( - title=_("Password"), - allow_empty=False, - ), - ), - ], - optional_keys=False, - title=_("HP MSA via Web Interface"), - help=_( - "This rule selects the Agent HP MSA instead of the normal Checkmk Agent " - "which collects the data through the HP MSA web interface" - ), - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("hp_msa"), - valuespec=_valuespec_special_agents_hp_msa, - ) -) 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/gui/plugins/wato/special_agents/innovaphone.py b/cmk/gui/plugins/wato/special_agents/innovaphone.py deleted file mode 100644 index 3360ac01cbc..00000000000 --- a/cmk/gui/plugins/wato/special_agents/innovaphone.py +++ /dev/null @@ -1,69 +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.special_agents.common_tls_verification import tls_verify_flag_default_yes -from cmk.gui.plugins.wato.utils import HostRulespec, rulespec_registry -from cmk.gui.valuespec import Dictionary, DropdownChoice, TextInput -from cmk.gui.wato import ( - MigrateToIndividualOrStoredPassword, - RulespecGroupDatasourceProgramsHardware, -) - - -def _valuespec_special_agents_innovaphone() -> Dictionary: - return Dictionary( - title=_("Innovaphone Gateways"), - help=_("Please specify the user and password needed to access the xml interface"), - elements=[ - ( - "protocol", - DropdownChoice( - title=_("Protocol"), - choices=[ - ("http", "HTTP"), - ("https", "HTTPS"), - ], - ), - ), - tls_verify_flag_default_yes(), - ( - "auth_basic", - Dictionary( - elements=[ - ( - "username", - TextInput( - title=_("Login username"), - allow_empty=False, - ), - ), - ( - "password", - MigrateToIndividualOrStoredPassword( - title=_("Password"), - allow_empty=False, - ), - ), - ], - optional_keys=[], - title=_("Basic authentication"), - ), - ), - ], - optional_keys=["protocol", "no-cert-check"], - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("innovaphone"), - valuespec=_valuespec_special_agents_innovaphone, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/jolokia.py b/cmk/gui/plugins/wato/special_agents/jolokia.py deleted file mode 100644 index 80429775fe9..00000000000 --- a/cmk/gui/plugins/wato/special_agents/jolokia.py +++ /dev/null @@ -1,91 +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.valuespec import Dictionary, DropdownChoice, NetworkPort, TextInput, Tuple -from cmk.gui.wato import MigrateToIndividualOrStoredPassword, RulespecGroupDatasourceProgramsApps -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _special_agents_jolokia_mk_jolokia_elements(): - return [ - ( - "port", - NetworkPort( - title=_("TCP port for connection"), - default_value=8080, - minvalue=1, - maxvalue=65535, - ), - ), - ( - "login", - Tuple( - title=_("Optional login (if required)"), - elements=[ - TextInput( - title=_("User ID for web login (if login required)"), - default_value="monitoring", - ), - MigrateToIndividualOrStoredPassword(title=_("Password for this user")), - DropdownChoice( - title=_("Login mode"), - choices=[ - ("basic", _("HTTP Basic Authentication")), - ("digest", _("HTTP Digest")), - ], - ), - ], - ), - ), - ( - "suburi", - TextInput( - title=_("relative URI under which Jolokia is visible"), - default_value="jolokia", - size=30, - ), - ), - ( - "instance", - TextInput( - title=_("Name of the instance in the monitoring"), - help=_( - "If you do not specify a name here, then the TCP port number " - "will be used as an instance name." - ), - ), - ), - ( - "protocol", - DropdownChoice( - title=_("Protocol"), - choices=[ - ("http", "HTTP"), - ("https", "HTTPS"), - ], - ), - ), - ] - - -def _valuespec_special_agents_jolokia(): - return Dictionary( - title=_("Jolokia"), - help=_("This rule allows querying the Jolokia web API."), - elements=_special_agents_jolokia_mk_jolokia_elements(), - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsApps, - name=RuleGroup.SpecialAgents("jolokia"), - valuespec=_valuespec_special_agents_jolokia, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/random.py b/cmk/gui/plugins/wato/special_agents/random.py deleted file mode 100644 index 04841d26296..00000000000 --- a/cmk/gui/plugins/wato/special_agents/random.py +++ /dev/null @@ -1,33 +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 FixedValue -from cmk.gui.wato import RulespecGroupDatasourceProgramsTesting - - -def _valuespec_special_agents_random(): - return FixedValue( - value={}, - title=_("Create random monitoring data"), - help=_( - "By configuring this rule for a host - instead of the normal " - "Check_MK agent random monitoring data will be created." - ), - totext=_("Create random monitoring data"), - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsTesting, - name=RuleGroup.SpecialAgents("random"), - valuespec=_valuespec_special_agents_random, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/storeonce4x.py b/cmk/gui/plugins/wato/special_agents/storeonce4x.py deleted file mode 100644 index 59f6cea7c0e..00000000000 --- a/cmk/gui/plugins/wato/special_agents/storeonce4x.py +++ /dev/null @@ -1,53 +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.valuespec import Dictionary, DropdownChoice, TextInput -from cmk.gui.wato import ( - MigrateToIndividualOrStoredPassword, - RulespecGroupDatasourceProgramsHardware, -) -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _valuespec_special_agents_storeonce4x(): - return Dictionary( - title=_("HPE StoreOnce via REST API 4.x"), - help=_( - "This rule set selects the special agent for HPE StoreOnce Appliances " - "instead of the normal Checkmk agent and allows monitoring via REST API v4.x or " - "higher. " - ), - optional_keys=["cert"], - elements=[ - ("user", TextInput(title=_("Username"), allow_empty=False)), - ( - "password", - MigrateToIndividualOrStoredPassword(title=_("Password"), allow_empty=False), - ), - ( - "cert", - DropdownChoice( - title=_("SSL certificate verification"), - choices=[ - (True, _("Activate")), - (False, _("Deactivate")), - ], - ), - ), - ], - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupDatasourceProgramsHardware, - name=RuleGroup.SpecialAgents("storeonce4x"), - valuespec=_valuespec_special_agents_storeonce4x, - ) -) diff --git a/cmk/gui/plugins/wato/special_agents/vsphere.py b/cmk/gui/plugins/wato/special_agents/vsphere.py deleted file mode 100644 index 56d61c67f40..00000000000 --- a/cmk/gui/plugins/wato/special_agents/vsphere.py +++ /dev/null @@ -1,200 +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.special_agents.common_tls_verification import tls_verify_options -from cmk.gui.utils.urls import DocReference -from cmk.gui.valuespec import ( - Checkbox, - Dictionary, - DropdownChoice, - Integer, - ListChoice, - NetworkPort, - TextInput, -) -from cmk.gui.wato import MigrateToIndividualOrStoredPassword, RulespecGroupVMCloudContainer -from cmk.gui.watolib.rulespecs import HostRulespec, rulespec_registry - - -def _valuespec_special_agents_vsphere() -> Dictionary: - return Dictionary( - title=_("VMware ESX via vSphere"), - help=_( - "This rule allows monitoring of VMware ESX via the vSphere API. " - "You can configure your connection settings here.", - ), - elements=[ - ( - "user", - TextInput( - title=_("vSphere User name"), - allow_empty=False, - ), - ), - ( - "secret", - MigrateToIndividualOrStoredPassword( - title=_("vSphere secret"), - allow_empty=False, - ), - ), - ( - "direct", - DropdownChoice( - title=_("Type of query"), - choices=[ - (True, _("Queried host is a host system")), - (False, _("Queried host is the vCenter")), - ], - ), - ), - ( - "tcp_port", - NetworkPort( - title=_("TCP Port number"), - help=_("Port number for HTTPS connection to vSphere"), - default_value=443, - minvalue=1, - maxvalue=65535, - ), - ), - tls_verify_options(), - ( - "timeout", - Integer( - title=_("Connect timeout"), - help=_( - "The network timeout in seconds when communicating with vSphere or " - "to the Checkmk Agent. The default is 60 seconds. Please note that this " - "is not a total timeout but is applied to each individual network transation." - ), - default_value=60, - minvalue=1, - unit=_("seconds"), - ), - ), - ( - "infos", - ListChoice( - title=_("Retrieve information about..."), - choices=[ - ("hostsystem", _("Host Systems")), - ("virtualmachine", _("Virtual Machines")), - ("datastore", _("Datastores")), - ("counters", _("Performance counters")), - ("licenses", _("License Usage")), - ], - default_value=["hostsystem", "virtualmachine", "datastore", "counters"], - allow_empty=False, - ), - ), - ( - "skip_placeholder_vms", - Checkbox( - title=_("Placeholder VMs"), - label=_("Do not monitor placeholder VMs"), - default_value=True, - true_label=_("ignore"), - false_label=_("monitor"), - help=_( - "Placeholder VMs are created by the Site Recovery Manager (SRM) and act as backup " - "virtual machines in case the default VM is unable to start. This option tells the " - "vSphere agent to exclude placeholder VMs in its output." - ), - ), - ), - ( - "host_pwr_display", - DropdownChoice( - title=_("Display ESX Host power state on"), - choices=[ - (None, _("The queried ESX system (vCenter / Host)")), - ("esxhost", _("The ESX Host")), - ("vm", _("The virtual machine")), - ], - default_value=None, - ), - ), - ( - "vm_pwr_display", - DropdownChoice( - title=_("Display VM power state additionally on"), - help=_( - "The power state can be displayed additionally either " - "on the ESX host or the VM. This will result in services " - "for both the queried system and the ESX host / VM. " - "By disabling the unwanted services it is then possible " - "to configure where the services are displayed." - ), - choices=[ - (None, _("The queried ESX system (vCenter / Host)")), - ("esxhost", _("The ESX Host")), - ("vm", _("The virtual machine")), - ], - default_value=None, - ), - ), - ( - "snapshots_on_host", - Checkbox( - title=_("VM snapshot summary"), - label=_("Display snapshot summary on ESX hosts"), - default_value=False, - help=_( - "By default the snapshot summary service is displayed on the vCenter. " - "Users who run an ESX host on its own or do not include their vCenter in the " - "monitoring can choose to display the snapshot summary on the ESX host itself." - ), - ), - ), - ( - "vm_piggyname", - DropdownChoice( - title=_("Piggyback name of virtual machines"), - choices=[ - ("alias", _("Use the name specified in the ESX system")), - ( - "hostname", - _("Use the VMs host name if set, otherwise fall back to ESX name"), - ), - ], - default_value="alias", - ), - ), - ( - "spaces", - DropdownChoice( - title=_("Spaces in host names"), - choices=[ - ("cut", _("Cut everything after first space")), - ("underscore", _("Replace with underscores")), - ], - default_value="underscore", - ), - ), - ], - optional_keys=[ - "tcp_port", - "timeout", - "vm_pwr_display", - "host_pwr_display", - "vm_piggyname", - ], - ignored_keys=["use_pysphere"], - ) - - -rulespec_registry.register( - HostRulespec( - group=RulespecGroupVMCloudContainer, - name=RuleGroup.SpecialAgents("vsphere"), - valuespec=_valuespec_special_agents_vsphere, - doc_references={DocReference.VMWARE: _("Monitoring VMWare ESXi")}, - ) -) diff --git a/cmk/gui/query_filters.py b/cmk/gui/query_filters.py index ed085c9cc07..c82fb1b92cd 100644 --- a/cmk/gui/query_filters.py +++ b/cmk/gui/query_filters.py @@ -16,7 +16,6 @@ from cmk.utils.labels import LabelGroups from cmk.utils.tags import TagGroupID -from cmk.gui import site_config, sites from cmk.gui.config import active_config from cmk.gui.exceptions import MKUserError from cmk.gui.i18n import _ @@ -979,14 +978,3 @@ def _add_row(row: Row) -> bool: return True return [row for row in rows if _add_row(row)] - - -def cre_sites_options() -> SitesOptions: - return sorted( - [ - (sitename, site_config.get_site_config(active_config, sitename)["alias"]) - for sitename, state in sites.states().items() - if state["state"] == "online" - ], - key=lambda a: a[1].lower(), - ) diff --git a/cmk/gui/quick_setup/_modes.py b/cmk/gui/quick_setup/_modes.py index 84a72ce479f..da6c90fdf63 100644 --- a/cmk/gui/quick_setup/_modes.py +++ b/cmk/gui/quick_setup/_modes.py @@ -3,7 +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. -from collections.abc import Callable, Collection, Iterator, Mapping, Sequence +from collections.abc import Callable, Collection, Iterable, Iterator, Mapping, Sequence from typing import Protocol from cmk.ccc.exceptions import MKGeneralException @@ -11,7 +11,7 @@ from cmk.utils.rulesets.definition import RuleGroup, RuleGroupType from cmk.gui import forms -from cmk.gui.breadcrumb import Breadcrumb +from cmk.gui.breadcrumb import Breadcrumb, BreadcrumbItem from cmk.gui.config import active_config from cmk.gui.exceptions import MKUserError from cmk.gui.htmllib.generator import HTMLWriter @@ -36,13 +36,19 @@ from cmk.gui.utils.html import HTML from cmk.gui.utils.transaction_manager import transactions from cmk.gui.utils.urls import make_confirm_delete_link -from cmk.gui.valuespec import Dictionary, DictionaryEntry, FixedValue, RuleComment, TextInput +from cmk.gui.valuespec import ( + Dictionary, + DictionaryEntry, + FixedValue, + RuleComment, + TextInput, +) from cmk.gui.wato._main_module_topics import MainModuleTopicQuickSetup from cmk.gui.wato.pages.hosts import ModeEditHost from cmk.gui.wato.pages.password_store import ModeEditPassword from cmk.gui.wato.pages.rulesets import ModeEditRule from cmk.gui.watolib.configuration_bundles import ( - BUNDLE_DOMAINS, + bundle_domains, BundleId, BundleReferences, ConfigBundle, @@ -64,6 +70,7 @@ def register(main_module_registry: MainModuleRegistry, mode_registry: ModeRegist mode_registry.register(ModeEditConfigurationBundles) mode_registry.register(ModeQuickSetupSpecialAgent) main_module_registry.register(MainModuleQuickSetupAWS) + main_module_registry.register(MainModuleQuickSetupAzure) class ModeQuickSetupSpecialAgent(WatoMode): @@ -105,7 +112,7 @@ def static_permissions() -> Collection[PermissionName]: def ensure_permissions(self) -> None: self._ensure_static_permissions() - for domain_definition in BUNDLE_DOMAINS[RuleGroupType.SPECIAL_AGENTS]: + for domain_definition in bundle_domains()[RuleGroupType.SPECIAL_AGENTS]: pname = domain_definition.permission user.need_permission(pname if "." in pname else ("wato." + pname)) @@ -127,7 +134,14 @@ def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: ) def page(self) -> None: - html.vue_app(app_name="quick_setup", data={"quick_setup_id": self._quick_setup_id}) + html.vue_app( + app_name="quick_setup", + data={ + "quick_setup_id": self._quick_setup_id, + "mode": "guided", + "toggle_enabled": False, + }, + ) class ModeEditConfigurationBundles(WatoMode): @@ -143,9 +157,16 @@ def name(cls) -> str: def static_permissions() -> Collection[PermissionName]: return [] + def _topic_breadcrumb_item(self) -> Iterable[BreadcrumbItem]: + """Return the BreadcrumbItem for the topic of this mode""" + yield BreadcrumbItem( + title=MainModuleTopicQuickSetup.title, + url=None, + ) + def ensure_permissions(self) -> None: self._ensure_static_permissions() - for domain_definition in BUNDLE_DOMAINS[self._bundle_group_type]: + for domain_definition in bundle_domains()[self._bundle_group_type]: pname = domain_definition.permission user.need_permission(pname if "." in pname else ("wato." + pname)) @@ -155,7 +176,7 @@ def _from_vars(self) -> None: self._bundle_group_type = RuleGroupType(self._name.split(":")[0]) except ValueError: raise MKUserError(None, _("Invalid configuration bundle group type.")) - if self._bundle_group_type not in BUNDLE_DOMAINS: + if self._bundle_group_type not in bundle_domains(): raise MKUserError( self.VAR_NAME, _("No edit configuration bundle implemented for bundle group type '%s'.") @@ -187,7 +208,8 @@ def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: icon_name="new", item=make_simple_link( mode_url( - ModeQuickSetupSpecialAgent.name(), varname=self._name + ModeQuickSetupSpecialAgent.name(), + varname=self._name, ) ), is_shortcut=True, @@ -258,14 +280,14 @@ def _action_url(self, action: str, bundle_id: BundleId) -> str: def action(self) -> ActionResult: check_csrf_token() if not transactions.check_transaction(): - return redirect(self.mode_url()) + return redirect(self.mode_url(**{"mode": self.name(), self.VAR_NAME: self._name})) - action = request.get_ascii_input_mandatory(self.VAR_ACTION) bundle_id = BundleId(request.get_ascii_input_mandatory(self.VAR_BUNDLE_ID)) + action = request.get_ascii_input_mandatory(self.VAR_ACTION) if action == "delete": delete_config_bundle(bundle_id) - return redirect(self.mode_url()) + return redirect(self.mode_url(**{"mode": self.name(), self.VAR_NAME: self._name})) def _special_agent_bundles_listing( self, group_name: str, bundles: Mapping[BundleId, BundleReferences] @@ -330,7 +352,7 @@ def _show_bundle_icons(self, table: Table, bundle_id: BundleId) -> None: html.empty_icon() table.cell(_("Actions"), css=["buttons rulebuttons"]) - edit_url = "" # TODO: introduce edit button + edit_url = mode_url(ModeConfigurationBundle.name(), bundle_id=bundle_id) html.icon_button(url=edit_url, title=_("Edit this configuration"), icon="edit") html.icon_button( @@ -381,6 +403,47 @@ def megamenu_search_terms(cls) -> Sequence[str]: return ["aws"] +class MainModuleQuickSetupAzure(ABCMainModule): + @property + def mode_or_url(self) -> str: + return mode_url( + ModeEditConfigurationBundles.name(), + varname=RuleGroup.SpecialAgents("azure"), + ) + + @property + def topic(self) -> MainModuleTopic: + return MainModuleTopicQuickSetup + + @property + def title(self) -> str: + return _("Microsoft Azure") + + @property + def icon(self) -> Icon: + return "quick_setup_azure" + + @property + def permission(self) -> None | str: + return None + + @property + def description(self) -> str: + return _("Configure Microsoft Azure monitoring in Checkmk") + + @property + def sort_index(self) -> int: + return 11 + + @property + def is_show_more(self) -> bool: + return False + + @classmethod + def megamenu_search_terms(cls) -> Sequence[str]: + return ["azure"] + + class EditDCDConnection(Protocol): def __init__(self) -> None: ... @@ -398,13 +461,17 @@ class ModeConfigurationBundle(WatoMode): def name(cls) -> str: return "edit_configuration_bundle" + @classmethod + def parent_mode(cls) -> None | type["WatoMode"]: + return ModeEditConfigurationBundles + @staticmethod def static_permissions() -> Collection[PermissionName]: return [] def ensure_permissions(self) -> None: self._ensure_static_permissions() - for domain_definition in BUNDLE_DOMAINS.get(self._rule_group_type, []): + for domain_definition in bundle_domains().get(self._rule_group_type, []): pname = domain_definition.permission user.need_permission(pname if "." in pname else ("wato." + pname)) @@ -441,7 +508,6 @@ def _special_agents_from_vars(self) -> None: [ self._bundle_references.rules, self._bundle_references.hosts, - self._bundle_references.passwords, ] ): raise MKUserError( @@ -453,7 +519,6 @@ def _special_agents_from_vars(self) -> None: assert len(self._bundle_references.rules) == 1 assert self._bundle_references.hosts assert len(self._bundle_references.hosts) == 1 - assert self._bundle_references.passwords # Rule ModeEditRule.set_vars(self._bundle_group, self._bundle_references.rules[0].id) @@ -477,18 +542,23 @@ def _special_agents_from_vars(self) -> None: edit_dcd_connection.from_vars(f"dcd_id_{index}") # Passwords - for index, password in enumerate(self._bundle_references.passwords): - request.set_var(f"password_id_{index}", password[0]) - self._edit_passwords = [ModeEditPassword() for _pw in self._bundle_references.passwords] - for index, edit_password in enumerate(self._edit_passwords): - edit_password.from_vars(f"password_id_{index}") + self._edit_passwords = [] + if self._bundle_references.passwords: + for index, password in enumerate(self._bundle_references.passwords): + request.set_var(f"password_id_{index}", password[0]) + self._edit_passwords = [ModeEditPassword() for _pw in self._bundle_references.passwords] + for index, edit_password in enumerate(self._edit_passwords): + edit_password.from_vars(f"password_id_{index}") @staticmethod def _configuration_vs(bundle_id: str) -> Dictionary: elements: Sequence[DictionaryEntry] = [ ("_name", TextInput(title=_("Name"), size=80)), ("_comment", RuleComment()), - ("_bundle_id", FixedValue(title=_("Configuration bundle ID"), value=bundle_id)), + ( + "_bundle_id", + FixedValue(title=_("Configuration bundle ID"), value=bundle_id), + ), ] return Dictionary( title=_("Configuration bundle properties"), @@ -520,7 +590,10 @@ def _sub_page_host(self) -> None: def _sub_page_dcd_connection(self) -> None: if any(edit_dcd_connection for edit_dcd_connection in self._edit_dcd_connections): - html.h1(_("Dynamic host management"), class_=["edit_configuration_bundle_header"]) + html.h1( + _("Dynamic host management"), + class_=["edit_configuration_bundle_header"], + ) for index, edit_dcd_connection in enumerate(self._edit_dcd_connections): if edit_dcd_connection: edit_dcd_connection.page(f"edit_dcd_{index}") @@ -579,7 +652,9 @@ def _page_menu_action_entries(self) -> Iterator[PageMenuEntry]: yield PageMenuEntry( title=_("Cancel"), icon_name="cancel", - item=make_simple_link(""), + item=make_simple_link( + mode_url(ModeEditConfigurationBundles.name(), varname=self._bundle_group) + ), is_shortcut=True, ) diff --git a/cmk/gui/quick_setup/config_setups/__init__.py b/cmk/gui/quick_setup/config_setups/__init__.py index 3ed95f18d48..94227a4afc0 100644 --- a/cmk/gui/quick_setup/config_setups/__init__.py +++ b/cmk/gui/quick_setup/config_setups/__init__.py @@ -5,7 +5,9 @@ from ..v0_unstable._registry import QuickSetupRegistry from .aws.stages import quick_setup_aws +from .azure.stages import quick_setup_azure def register(registry: QuickSetupRegistry) -> None: registry.register(quick_setup_aws) + registry.register(quick_setup_azure) diff --git a/cmk/gui/quick_setup/config_setups/aws/form_specs.py b/cmk/gui/quick_setup/config_setups/aws/form_specs.py index 04e1f4f91b7..1fe83e8cc51 100644 --- a/cmk/gui/quick_setup/config_setups/aws/form_specs.py +++ b/cmk/gui/quick_setup/config_setups/aws/form_specs.py @@ -171,14 +171,24 @@ def quick_setup_stage_1() -> Mapping[str, DictElement]: parameter_form=String( title=Title("Access key ID"), field_size=FieldSize.MEDIUM, - custom_validate=(validators.LengthInRange(min_value=1),), + custom_validate=( + validators.LengthInRange( + min_value=1, + error_msg=Message("Access key ID cannot be empty"), + ), + ), ), required=True, ), "secret_access_key": DictElement( parameter_form=Password( title=Title("Secret access key"), - custom_validate=(validators.LengthInRange(min_value=1),), + custom_validate=( + validators.LengthInRange( + min_value=1, + error_msg=Message("Secret access key cannot be empty"), + ), + ), ), required=True, ), @@ -197,6 +207,12 @@ def quick_setup_stage_2() -> Mapping[str, DictElement]: ) for name, title in aws_region_to_monitor() ], + custom_validate=( + validators.LengthInRange( + min_value=1, + error_msg=Message("Please choose one or more regions to continue"), + ), + ), ), required=True, ), @@ -206,19 +222,19 @@ def quick_setup_stage_2() -> Mapping[str, DictElement]: def quick_setup_stage_3() -> Mapping[str, DictElement]: valid_service_choices = {c.name for c in _regional_services()} return { - "global_services": DictElement( + "services": DictElement( parameter_form=MultipleChoice( - title=Title("Global services to monitor"), - elements=_global_services(), - prefill=DefaultValue([]), + title=Title("Services per region"), + elements=_regional_services(), + prefill=DefaultValue(list(valid_service_choices)), ), required=True, ), - "services": DictElement( + "global_services": DictElement( parameter_form=MultipleChoice( - title=Title("Services per region to monitor"), - elements=_regional_services(), - prefill=DefaultValue(list(valid_service_choices)), + title=Title("Global services"), + elements=_global_services(), + prefill=DefaultValue([]), ), required=True, ), @@ -240,7 +256,9 @@ def quick_setup_advanced() -> Mapping[str, DictElement]: title=Title("Port"), custom_validate=[ validators.NumberInRange( - 0, 65535, Message("Port must be between 0 and 65535") + 0, + 65535, + Message("Port must be between 0 and 65535"), ) ], ) diff --git a/cmk/gui/quick_setup/config_setups/aws/ruleset_helper.py b/cmk/gui/quick_setup/config_setups/aws/ruleset_helper.py index e682dea24c8..71e9bcabc23 100644 --- a/cmk/gui/quick_setup/config_setups/aws/ruleset_helper.py +++ b/cmk/gui/quick_setup/config_setups/aws/ruleset_helper.py @@ -8,7 +8,7 @@ from cmk.rulesets.v1 import Help, Label, Message, Title from cmk.rulesets.v1.form_specs import DictElement, Dictionary, FormSpec, List, String -from cmk.rulesets.v1.form_specs.validators import ValidationError +from cmk.rulesets.v1.form_specs.validators import LengthInRange, ValidationError def _validate_aws_tags(values: Sequence[Any]) -> object: @@ -48,6 +48,12 @@ def formspec_aws_tags(title: Title | None = None) -> FormSpec: "key": DictElement( parameter_form=String( title=Title("Key"), + custom_validate=[ + LengthInRange( + min_value=1, + error_msg=Message("Tags enabled but no key defined."), + ), + ], ), required=True, ), @@ -58,6 +64,12 @@ def formspec_aws_tags(title: Title | None = None) -> FormSpec: remove_element_label=Label("Remove value"), no_element_label=Label("No values defined"), editable_order=False, + custom_validate=[ + LengthInRange( + min_value=1, + error_msg=Message("Tags enabled but no values defined."), + ), + ], ), required=True, ), @@ -67,5 +79,11 @@ def formspec_aws_tags(title: Title | None = None) -> FormSpec: remove_element_label=Label("Remove tag"), no_element_label=Label("No tags defined"), editable_order=False, - custom_validate=[_validate_aws_tags], + custom_validate=[ + _validate_aws_tags, + LengthInRange( + min_value=1, + error_msg=Message("Tags enabled but no tags defined."), + ), + ], ) diff --git a/cmk/gui/quick_setup/config_setups/aws/stages.py b/cmk/gui/quick_setup/config_setups/aws/stages.py index 596b67413e8..e67aa3c93f8 100644 --- a/cmk/gui/quick_setup/config_setups/aws/stages.py +++ b/cmk/gui/quick_setup/config_setups/aws/stages.py @@ -14,15 +14,23 @@ from cmk.gui.quick_setup.config_setups.aws import form_specs as aws from cmk.gui.quick_setup.config_setups.aws import ruleset_helper from cmk.gui.quick_setup.config_setups.aws.form_specs import quick_setup_aws_form_spec +from cmk.gui.quick_setup.v0_unstable.definitions import QSSiteSelection from cmk.gui.quick_setup.v0_unstable.predefined import ( collect_params_from_form_data, + collect_params_with_defaults_from_form_data, complete, recaps, + utils, widgets, ) from cmk.gui.quick_setup.v0_unstable.predefined import validators as qs_validators -from cmk.gui.quick_setup.v0_unstable.setups import QuickSetup, QuickSetupStage -from cmk.gui.quick_setup.v0_unstable.type_defs import ParsedFormData, QuickSetupId, ServiceInterest +from cmk.gui.quick_setup.v0_unstable.setups import QuickSetup, QuickSetupSaveAction, QuickSetupStage +from cmk.gui.quick_setup.v0_unstable.type_defs import ( + ParsedFormData, + QuickSetupId, + ServiceInterest, + StageIndex, +) from cmk.gui.quick_setup.v0_unstable.widgets import ( Collapsible, FormSpecId, @@ -61,18 +69,18 @@ def prepare_aws() -> QuickSetupStage: "your AWS account." ), ), - Text(text=_("Save the generated Access key and Secret access key.")), + Text(text=_("Note down the generated Access key ID and Secret access key.")), Text( text=_( "Return to Checkmk, define a unique AWS account name, and use the " - "Access key and Secret access key below." + "Access key ID and Secret access key below." ) ), ], list_type="ordered", ), widgets.unique_id_formspec_wrapper( - title=Title("AWS account name"), prefill_template="aws_config" + title=Title("Configuration name"), prefill_template="aws_config" ), FormSpecWrapper( id=FormSpecId("credentials"), @@ -82,20 +90,31 @@ def prepare_aws() -> QuickSetupStage: ), ), ], - custom_validators=[qs_validators.validate_unique_id], + custom_validators=[ + qs_validators.validate_unique_id, + qs_validators.validate_test_connection_custom_collect_params( + rulespec_name=RuleGroup.SpecialAgents("aws"), + parameter_form=quick_setup_aws_form_spec(), + custom_collect_params=aws_collect_params_with_defaults, + error_message=_( + "Could not access your AWS account. Please check your Access and Secret key and try again." + ), + ), + ], recap=[recaps.recaps_form_spec], button_label="Configure host and regions", ) def configure_host_and_regions() -> QuickSetupStage: + site_default_value = site_attribute_default_value() return QuickSetupStage( title=_("Configure host and regions"), sub_title=_( "Name your host, define the path and select the regions you would like to monitor" ), configure_components=[ - widgets.host_name_and_host_path_formspec_wrapper(), + widgets.host_name_and_host_path_formspec_wrapper(host_prefill_template="aws"), FormSpecWrapper( id=FormSpecId("configure_host_and_regions"), form_spec=DictionaryExtended( @@ -103,15 +122,42 @@ def configure_host_and_regions() -> QuickSetupStage: layout=DictionaryLayout.two_columns, ), ), + FormSpecWrapper( + id=FormSpecId("site"), + form_spec=DictionaryExtended( + elements={ + QSSiteSelection: DictElement( + parameter_form=SingleChoice( + elements=[ + SingleChoiceElement( + name=site_id, + title=Title( # pylint: disable=localization-of-non-literal-string + title + ), + ) + for site_id, title in get_configured_site_choices() + ], + title=Title("Site selection"), + prefill=( + DefaultValue(site_default_value) + if site_default_value + else InputHint(Title("Please choose")) + ), + ), + required=True, + ) + }, + layout=DictionaryLayout.two_columns, + ), + ), ], - custom_validators=[], + custom_validators=[qs_validators.validate_host_name_doesnt_exists], recap=[recaps.recaps_form_spec], button_label="Configure services to monitor", ) def _configure() -> Sequence[Widget]: - site_default_value = site_attribute_default_value() return [ FormSpecWrapper( id=FormSpecId("configure_services_to_monitor"), @@ -123,34 +169,6 @@ def _configure() -> Sequence[Widget]: Collapsible( title="Other options", items=[ - FormSpecWrapper( - id=FormSpecId("site"), - form_spec=DictionaryExtended( - elements={ - "site_selection": DictElement( - parameter_form=SingleChoice( - elements=[ - SingleChoiceElement( - name=site_id, - title=Title( # pylint: disable=localization-of-non-literal-string - title - ), - ) - for site_id, title in get_configured_site_choices() - ], - title=Title("Site selection"), - prefill=( - DefaultValue(site_default_value) - if site_default_value - else InputHint(Title("Please choose")) - ), - ), - required=True, - ) - }, - layout=DictionaryLayout.two_columns, - ), - ), FormSpecWrapper( id=FormSpecId("aws_tags"), form_spec=DictionaryExtended( @@ -178,31 +196,55 @@ def configure_services_to_monitor() -> QuickSetupStage: recap=[ recaps.recaps_form_spec, ], - button_label="Review & run preview service discovery", + button_label="Test configuration", ) +def recap_found_services( + _quick_setup_id: QuickSetupId, + _stage_index: StageIndex, + parsed_data: ParsedFormData, +) -> Sequence[Widget]: + service_discovery_result = utils.get_service_discovery_preview( + rulespec_name=RuleGroup.SpecialAgents("aws"), + all_stages_form_data=parsed_data, + parameter_form=quick_setup_aws_form_spec(), + collect_params=aws_collect_params_with_defaults, + ) + aws_service_interest = ServiceInterest(r"(?i).*aws.*", "services") + filtered_groups_of_services, _other_services = utils.group_services_by_interest( + services_of_interest=[aws_service_interest], + service_discovery_result=service_discovery_result, + ) + if len(filtered_groups_of_services[aws_service_interest]): + return [ + Text(text=_("AWS services found!")), + Text( + text=_( + "Save your progress and go to the Activate Changes page to enable it. EC2 instances may take a few minutes to show up." + ) + ), + ] + return [ + Text(text=_("No AWS services found.")), + Text( + text=_( + "The connection to AWS was successful, but no services were found. If this is unintentional, please verify your configuration." + ) + ), + ] + + def review_and_run_preview_service_discovery() -> QuickSetupStage: return QuickSetupStage( - title=_("Review and run preview service discovery"), - sub_title=_("Review your configuration and run preview service discovery"), + title=_("Review and test configuration"), + sub_title=_("Test the AWS connection based on your configuration settings"), configure_components=[], - custom_validators=[ - qs_validators.validate_test_connection_custom_collect_params( - rulespec_name=RuleGroup.SpecialAgents("aws"), - parameter_form=quick_setup_aws_form_spec(), - custom_collect_params=aws_collect_params, - ) - ], + custom_validators=[], recap=[ - recaps.recap_service_discovery_custom_collect_params( - rulespec_name=RuleGroup.SpecialAgents("aws"), - parameter_form=quick_setup_aws_form_spec(), - services_of_interest=[ServiceInterest(".*", "services")], - custom_collect_params=aws_collect_params, - ) + recap_found_services, ], - button_label="Run preview service discovery", + button_label=_("Test configuration"), ) @@ -223,6 +265,14 @@ def aws_collect_params( ) +def aws_collect_params_with_defaults( + all_stages_form_data: ParsedFormData, parameter_form: Dictionary +) -> Mapping[str, object]: + return aws_transform_to_disk( + collect_params_with_defaults_from_form_data(all_stages_form_data, parameter_form) + ) + + def _migrate_aws_service(service: str) -> object: # Global if service in ["ce", "route53"]: @@ -240,8 +290,8 @@ def aws_transform_to_disk(params: Mapping[str, object]) -> Mapping[str, object]: assert isinstance(global_services, list) services = params["services"] assert isinstance(services, list) - overall_tags = params.get("overall_tags", []) - assert isinstance(overall_tags, list) + overall_tags = params.get("overall_tags") + regions_to_monitor = params["regions_to_monitor"] assert isinstance(regions_to_monitor, list) keys_to_rename = {"aws_lambda": "lambda"} @@ -253,8 +303,11 @@ def aws_transform_to_disk(params: Mapping[str, object]) -> Mapping[str, object]: "access": {}, # TODO required key but not yet implemented. It's part of quick_setup_advanced() "services": {keys_to_rename.get(k, k): _migrate_aws_service(k) for k in services}, "piggyback_naming_convention": "ip_region_instance", - "overall_tags": [(tag["key"], tag["values"]) for tag in overall_tags], } + if overall_tags is not None: + assert isinstance(overall_tags, list) + params["overall_tags"] = [(tag["key"], tag["values"]) for tag in overall_tags] + return params @@ -262,11 +315,16 @@ def aws_transform_to_disk(params: Mapping[str, object]) -> Mapping[str, object]: title=_("Amazon Web Services (AWS)"), id=QuickSetupId(RuleGroup.SpecialAgents("aws")), stages=[ - prepare_aws(), - configure_host_and_regions(), - configure_services_to_monitor(), - review_and_run_preview_service_discovery(), + prepare_aws, + configure_host_and_regions, + configure_services_to_monitor, + review_and_run_preview_service_discovery, + ], + save_actions=[ + QuickSetupSaveAction( + id="activate_changes", + label=_("Save & go to Activate changes"), + action=save_action, + ), ], - save_action=save_action, - button_complete_label=_("Save & go to Activate changes"), ) diff --git a/cmk/gui/quick_setup/config_setups/azure/__init__.py b/cmk/gui/quick_setup/config_setups/azure/__init__.py new file mode 100644 index 00000000000..c42b91132bf --- /dev/null +++ b/cmk/gui/quick_setup/config_setups/azure/__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/cmk/gui/quick_setup/config_setups/azure/stages.py b/cmk/gui/quick_setup/config_setups/azure/stages.py new file mode 100644 index 00000000000..f945f011cae --- /dev/null +++ b/cmk/gui/quick_setup/config_setups/azure/stages.py @@ -0,0 +1,250 @@ +#!/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, Sequence + +from cmk.ccc.i18n import _ + +from cmk.utils.rulesets.definition import RuleGroup + +from cmk.gui.form_specs.private.dictionary_extended import DictionaryExtended +from cmk.gui.form_specs.vue.shared_type_defs import DictionaryLayout +from cmk.gui.quick_setup.v0_unstable.definitions import QSSiteSelection +from cmk.gui.quick_setup.v0_unstable.predefined import ( + collect_params_from_form_data, + complete, + recaps, + widgets, +) +from cmk.gui.quick_setup.v0_unstable.predefined import validators as qs_validators +from cmk.gui.quick_setup.v0_unstable.setups import ( + QuickSetup, + QuickSetupSaveAction, + QuickSetupStage, +) +from cmk.gui.quick_setup.v0_unstable.type_defs import ( + ParsedFormData, + QuickSetupId, + ServiceInterest, +) +from cmk.gui.quick_setup.v0_unstable.widgets import ( + Collapsible, + FormSpecId, + FormSpecWrapper, + ListOfWidgets, + Text, + Widget, +) +from cmk.gui.user_sites import get_configured_site_choices, site_attribute_default_value + +from cmk.plugins.azure.rulesets import ( # pylint: disable=cmk-module-layer-violation + azure, +) +from cmk.rulesets.v1 import Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + InputHint, + SingleChoice, + SingleChoiceElement, +) + + +def configure_authentication() -> QuickSetupStage: + return QuickSetupStage( + title=_("Prepare Azure for Checkmk"), + configure_components=[ + ListOfWidgets( + items=[ + Text( + text=_( + "Create an Azure app for Checkmk: Register the app in Azure Active Directory and note down the Application ID." + ) + ), + Text( + text=_( + 'Assign permissions to the app: Grant necessary access rights, assigning the "Reader" role.' + ), + ), + Text( + text=_( + "Generate a key for the app: Create a Secret key in the app settings and note it down." + ) + ), + Text( + text=_( + "Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, and the Client secret from Azure." + ) + ), + Text( + text=_( + "Return to Checkmk: Define a unique Azure account name, and use the Subscription ID, Tenant ID, Client ID, and the Client secret below." + ) + ), + ], + list_type="ordered", + ), + widgets.unique_id_formspec_wrapper( + title=Title("Configuration name"), prefill_template="azure_config" + ), + FormSpecWrapper( + id=FormSpecId("credentials"), + form_spec=DictionaryExtended( + elements=azure.configuration_authentication(), + layout=DictionaryLayout.two_columns, + ), + ), + ], + custom_validators=[qs_validators.validate_unique_id], + recap=[recaps.recaps_form_spec], + button_label="Configure host and authority", + ) + + +def configure_host_and_authority() -> QuickSetupStage: + site_default_value = site_attribute_default_value() + return QuickSetupStage( + title=_("Configure host and authority"), + sub_title=_( + "Name your host, define the path and select the authority you would like to monitor" + ), + configure_components=[ + widgets.host_name_and_host_path_formspec_wrapper(host_prefill_template="azure"), + FormSpecWrapper( + id=FormSpecId("configure_authority"), + form_spec=DictionaryExtended( + elements=azure.configuration_authority(), + layout=DictionaryLayout.two_columns, + ), + ), + FormSpecWrapper( + id=FormSpecId("site"), + form_spec=DictionaryExtended( + elements={ + QSSiteSelection: DictElement( + parameter_form=SingleChoice( + elements=[ + SingleChoiceElement( + name=site_id, + title=Title( # pylint: disable=localization-of-non-literal-string + title + ), + ) + for site_id, title in get_configured_site_choices() + ], + title=Title("Site selection"), + prefill=( + DefaultValue(site_default_value) + if site_default_value + else InputHint(Title("Please choose")) + ), + ), + required=True, + ) + }, + layout=DictionaryLayout.two_columns, + ), + ), + ], + custom_validators=[qs_validators.validate_host_name_doesnt_exists], + recap=[recaps.recaps_form_spec], + button_label="Configure services to monitor", + ) + + +def _configure() -> Sequence[Widget]: + return [ + FormSpecWrapper( + id=FormSpecId("configure_services_to_monitor"), + form_spec=DictionaryExtended( + elements=azure.configuration_services(), + layout=DictionaryLayout.two_columns, + ), + ), + Collapsible( + title="Other options", + items=[ + FormSpecWrapper( + id=FormSpecId("configure_advanced"), + form_spec=DictionaryExtended( + elements=azure.configuration_advanced(), + layout=DictionaryLayout.two_columns, + ), + ), + ], + ), + ] + + +def configure_services_to_monitor() -> QuickSetupStage: + return QuickSetupStage( + title=_("Configure services to monitor"), + sub_title=_("Select and configure the Microsoft Azure services you would like to monitor"), + configure_components=_configure, + custom_validators=[], + recap=[ + recaps.recaps_form_spec, + ], + button_label="Review & run preview service discovery", + ) + + +def review_and_run_preview_service_discovery() -> QuickSetupStage: + return QuickSetupStage( + title=_("Review and run preview service discovery"), + sub_title=_("Review your configuration and run preview service discovery"), + configure_components=[], + custom_validators=[ + qs_validators.validate_test_connection_custom_collect_params( + rulespec_name=RuleGroup.SpecialAgents("azure"), + parameter_form=azure.formspec(), + custom_collect_params=azure_collect_params, + ) + ], + recap=[ + recaps.recap_service_discovery_custom_collect_params( + rulespec_name=RuleGroup.SpecialAgents("azure"), + parameter_form=azure.formspec(), + services_of_interest=[ServiceInterest(".*", "services")], + custom_collect_params=azure_collect_params, + ) + ], + button_label="Run preview service discovery", + ) + + +def save_action(all_stages_form_data: ParsedFormData) -> str: + return complete.create_and_save_special_agent_bundle_custom_collect_params( + special_agent_name="azure", + parameter_form=azure.formspec(), + all_stages_form_data=all_stages_form_data, + custom_collect_params=azure_collect_params, + ) + + +def azure_collect_params( + all_stages_form_data: ParsedFormData, parameter_form: Dictionary +) -> Mapping[str, object]: + return collect_params_from_form_data(all_stages_form_data, parameter_form) + + +quick_setup_azure = QuickSetup( + title=_("Microsoft Azure"), + id=QuickSetupId(RuleGroup.SpecialAgents("azure")), + stages=[ + configure_authentication, + configure_host_and_authority, + configure_services_to_monitor, + review_and_run_preview_service_discovery, + ], + save_actions=[ + QuickSetupSaveAction( + id="activate_changes", + label=_("Save & go to Activate changes"), + action=save_action, + ), + ], +) diff --git a/cmk/gui/quick_setup/to_frontend.py b/cmk/gui/quick_setup/to_frontend.py index bcd3e8253c9..73e9f746b6c 100644 --- a/cmk/gui/quick_setup/to_frontend.py +++ b/cmk/gui/quick_setup/to_frontend.py @@ -20,7 +20,7 @@ build_quick_setup_formspec_map, stage_components, ) -from cmk.gui.quick_setup.v0_unstable.setups import QuickSetup +from cmk.gui.quick_setup.v0_unstable.setups import QuickSetup, QuickSetupSaveAction from cmk.gui.quick_setup.v0_unstable.type_defs import ( GeneralStageErrors, ParsedFormData, @@ -85,12 +85,18 @@ class Stage: stage_recap: Sequence[Widget] = field(default_factory=list) +@dataclass +class CompleteButton: + id: str + label: str + + @dataclass class QuickSetupOverview: quick_setup_id: QuickSetupId overviews: list[StageOverview] stage: Stage - button_complete_label: str + complete_buttons: list[CompleteButton] mode: str = field(default="guided") @@ -106,7 +112,7 @@ class CompleteStage: class QuickSetupAllStages: quick_setup_id: QuickSetupId stages: list[CompleteStage] - button_complete_label: str + complete_buttons: list[CompleteButton] mode: str = field(default="overview") @@ -168,6 +174,7 @@ def _form_spec_parse( def quick_setup_guided_mode(quick_setup: QuickSetup) -> QuickSetupOverview: + stages = [stage() for stage in quick_setup.stages] return QuickSetupOverview( quick_setup_id=quick_setup.id, overviews=[ @@ -175,18 +182,21 @@ def quick_setup_guided_mode(quick_setup: QuickSetup) -> QuickSetupOverview: title=stage.title, sub_title=stage.sub_title, ) - for stage in quick_setup.stages + for stage in stages ], stage=Stage( next_stage_structure=NextStageStructure( components=[ _get_stage_components_from_widget(widget) - for widget in stage_components(quick_setup.stages[0]) + for widget in stage_components(stages[0]) ], - button_label=quick_setup.stages[0].button_label, + button_label=stages[0].button_label, ), ), - button_complete_label=quick_setup.button_complete_label, + complete_buttons=[ + CompleteButton(id=save_action.id, label=save_action.label) + for save_action in quick_setup.save_actions + ], ) @@ -195,8 +205,8 @@ def validate_stage( stages_raw_formspecs: Sequence[RawFormData], ) -> Errors | None: errors = Errors() - - quick_setup_formspec_map = build_quick_setup_formspec_map(quick_setup.stages) + stages = [stage() for stage in quick_setup.stages] + quick_setup_formspec_map = build_quick_setup_formspec_map(stages) errors.stage_errors.extend( _stage_validate_all_form_spec_keys_existing( @@ -207,9 +217,7 @@ def validate_stage( if errors.exist(): return errors - for custom_validator in quick_setup.stages[ - StageIndex(len(stages_raw_formspecs) - 1) - ].custom_validators: + for custom_validator in stages[StageIndex(len(stages_raw_formspecs) - 1)].custom_validators: errors.stage_errors.extend( custom_validator( quick_setup.id, @@ -226,11 +234,12 @@ def retrieve_next_stage( stages_raw_formspecs: Sequence[RawFormData], ) -> Stage: current_stage_index = StageIndex(len(stages_raw_formspecs) - 1) - quick_setup_formspec_map = build_quick_setup_formspec_map(quick_setup.stages) + stages = [stage() for stage in quick_setup.stages] + quick_setup_formspec_map = build_quick_setup_formspec_map(stages) current_stage_recap = [ r - for recap_callable in quick_setup.stages[current_stage_index].recap + for recap_callable in stages[current_stage_index].recap for r in recap_callable( quick_setup.id, current_stage_index, @@ -241,7 +250,7 @@ def retrieve_next_stage( if current_stage_index == len(quick_setup.stages) - 1: return Stage(next_stage_structure=None, stage_recap=current_stage_recap) - next_stage = quick_setup.stages[current_stage_index + 1] + next_stage = stages[current_stage_index + 1] return Stage( next_stage_structure=NextStageStructure( @@ -256,22 +265,21 @@ def retrieve_next_stage( def complete_quick_setup( quick_setup: QuickSetup, + save_action: QuickSetupSaveAction, stages_raw_formspecs: Sequence[RawFormData], ) -> QuickSetupSaveRedirect: - if quick_setup.save_action is None: - return QuickSetupSaveRedirect(redirect_url=None) - return QuickSetupSaveRedirect( - redirect_url=quick_setup.save_action( + redirect_url=save_action.action( _form_spec_parse( stages_raw_formspecs, - build_quick_setup_formspec_map(quick_setup.stages), + build_quick_setup_formspec_map([stage() for stage in quick_setup.stages]), ) ) ) def quick_setup_overview_mode(quick_setup: QuickSetup) -> QuickSetupAllStages: + stages = [stage() for stage in quick_setup.stages] return QuickSetupAllStages( quick_setup_id=quick_setup.id, stages=[ @@ -283,7 +291,10 @@ def quick_setup_overview_mode(quick_setup: QuickSetup) -> QuickSetupAllStages: ], button_label=stage.button_label, ) - for stage in quick_setup.stages + for stage in stages + ], + complete_buttons=[ + CompleteButton(id=save_action.id, label=save_action.label) + for save_action in quick_setup.save_actions ], - button_complete_label=quick_setup.button_complete_label, ) diff --git a/cmk/gui/quick_setup/v0_unstable/definitions.py b/cmk/gui/quick_setup/v0_unstable/definitions.py index 87845556703..be903403f23 100644 --- a/cmk/gui/quick_setup/v0_unstable/definitions.py +++ b/cmk/gui/quick_setup/v0_unstable/definitions.py @@ -20,3 +20,6 @@ class QuickSetupNotFoundException(MKGeneralException): UniqueFormSpecIDStr = "formspec_unique_id" UniqueBundleIDStr = "bundle_id" +QSHostName = "host_name" +QSHostPath = "host_path" +QSSiteSelection = "site_selection" diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/__init__.py b/cmk/gui/quick_setup/v0_unstable/predefined/__init__.py index 6b7420fe5fc..7532571fda6 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/__init__.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/__init__.py @@ -5,6 +5,7 @@ import cmk.gui.quick_setup.v0_unstable.predefined._complete as complete import cmk.gui.quick_setup.v0_unstable.predefined._recaps as recaps +import cmk.gui.quick_setup.v0_unstable.predefined._utils as utils import cmk.gui.quick_setup.v0_unstable.predefined._validators as validators import cmk.gui.quick_setup.v0_unstable.predefined._widgets as widgets from cmk.gui.quick_setup.v0_unstable.predefined._common import ( @@ -25,6 +26,7 @@ "complete", "recaps", "validators", + "utils", "widgets", "collect_params_from_form_data", "build_quick_setup_formspec_map", diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_common.py b/cmk/gui/quick_setup/v0_unstable/predefined/_common.py index d24402b95c5..ab86466450f 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/_common.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_common.py @@ -77,18 +77,18 @@ def _create_diag_special_agent_input( ) -def _find_unique_id(form_data: Any, target_key: str) -> None | str: +def _find_id_in_form_data(form_data: Any, target_key: str) -> None | str: if isinstance(form_data, dict): for key, value in form_data.items(): if key == target_key: return value - result = _find_unique_id(value, target_key) + result = _find_id_in_form_data(value, target_key) if result is not None: return result return None if isinstance(form_data, list): for item in form_data: - result = _find_unique_id(item, target_key) + result = _find_id_in_form_data(item, target_key) if result is not None: return result return None diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_complete.py b/cmk/gui/quick_setup/v0_unstable/predefined/_complete.py index c5a56a779de..b7b997f35b5 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/_complete.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_complete.py @@ -12,7 +12,6 @@ from cmk.utils.global_ident_type import GlobalIdent, PROGRAM_ID_QUICK_SETUP from cmk.utils.hostaddress import HostName -from cmk.utils.password_store import ad_hoc_password_id from cmk.utils.password_store import Password as StorePassword from cmk.utils.rulesets.definition import RuleGroup from cmk.utils.rulesets.ruleset_matcher import RuleConditionsSpec, RuleOptionsSpec, RuleSpec @@ -20,14 +19,18 @@ from cmk.gui.config import active_config from cmk.gui.http import request from cmk.gui.i18n import _ -from cmk.gui.quick_setup.v0_unstable.definitions import UniqueBundleIDStr +from cmk.gui.quick_setup.v0_unstable.definitions import ( + QSHostName, + QSHostPath, + QSSiteSelection, + UniqueBundleIDStr, +) from cmk.gui.quick_setup.v0_unstable.predefined._common import ( _collect_params_with_defaults_from_form_data, _collect_passwords_from_form_data, - _find_unique_id, + _find_id_in_form_data, ) from cmk.gui.quick_setup.v0_unstable.type_defs import ParsedFormData -from cmk.gui.quick_setup.v0_unstable.widgets import FormSpecId from cmk.gui.site_config import site_is_local from cmk.gui.utils.urls import makeuri_contextless from cmk.gui.wato.pages.activate_changes import ModeActivateChanges @@ -39,6 +42,7 @@ ConfigBundle, create_config_bundle, CreateBundleEntities, + CreateDCDConnection, CreateHost, CreatePassword, CreateRule, @@ -46,6 +50,7 @@ ) from cmk.gui.watolib.host_attributes import HostAttributes from cmk.gui.watolib.hosts_and_folders import Folder, folder_tree, Host +from cmk.gui.watolib.passwords import load_passwords from cmk.gui.watolib.services import ( DiscoveryAction, get_check_table, @@ -55,6 +60,12 @@ from cmk.rulesets.v1.form_specs import Dictionary +class DCDHook: + create_dcd_connections: Callable[[BundleId, SiteId, Folder], list[CreateDCDConnection]] = ( + lambda *_args: [] + ) + + def _normalize_folder_path_str(folder_path: str) -> str: r"""Normalizes a folder representation @@ -118,22 +129,27 @@ def sanitize_folder_path(folder_path: str) -> Folder: if sanitized_folder_path in tree.all_folders(): return tree.all_folders()[sanitized_folder_path] return tree.root_folder().create_subfolder( - name=sanitized_folder_path, title=sanitized_folder_path, attributes={} + name=sanitized_folder_path, + title=sanitized_folder_path.split("/")[-1] + if "/" in sanitized_folder_path + else sanitized_folder_path, + attributes={}, ) -def create_host_from_form_data( +def create_special_agent_host_from_form_data( host_name: HostName, site_id: SiteId, - host_path: str, + folder: Folder, ) -> CreateHost: - # TODO Folder formspec. The sanitize function is likely to change once we have a folder formspec. - return CreateHost( name=host_name, - folder=sanitize_folder_path(host_path), + folder=folder, attributes=HostAttributes( tag_address_family="no-ip", + tag_agent="special-agents", + tag_piggyback="auto-piggyback", + tag_snmp_ds="no-snmp", site=site_id, ), ) @@ -217,6 +233,13 @@ def create_and_save_special_agent_bundle_custom_collect_params( ) +def _find_bundle_id(all_stages_form_data: ParsedFormData) -> BundleId: + bundle_id = _find_id_in_form_data(form_data=all_stages_form_data, target_key=UniqueBundleIDStr) + if bundle_id is None: + raise ValueError("No bundle id found") + return BundleId(bundle_id) + + def _create_and_save_special_agent_bundle( special_agent_name: str, parameter_form: Dictionary, @@ -224,40 +247,36 @@ def _create_and_save_special_agent_bundle( collect_params: Callable[[ParsedFormData, Dictionary], Mapping[str, object]], ) -> str: rulespec_name = RuleGroup.SpecialAgents(special_agent_name) - bundle_id = _find_unique_id(form_data=all_stages_form_data, target_key=UniqueBundleIDStr) - if bundle_id is None: - raise ValueError("No bundle id found") + bundle_id = _find_bundle_id(all_stages_form_data) - host_name = all_stages_form_data[FormSpecId("host_data")]["host_name"] - host_path = all_stages_form_data[FormSpecId("host_data")]["host_path"] + host_name = _find_id_in_form_data(all_stages_form_data, QSHostName) + host_path = _find_id_in_form_data(all_stages_form_data, QSHostPath) - site_selection = _find_unique_id(all_stages_form_data, "site_selection") + if host_name is None or host_path is None: + raise ValueError("Host name or host path not found in form data") + + site_selection = _find_id_in_form_data(all_stages_form_data, QSSiteSelection) site_id = SiteId(site_selection) if site_selection else omd_site() params = collect_params(all_stages_form_data, parameter_form) - # TODO: Find a better solution. - # Here we replace the password id if the user has selected from password store - # otherwise, the previous one will be overwritten. - if all_stages_form_data[FormSpecId("credentials")]["secret_access_key"][1] == "stored_password": - all_stages_form_data[FormSpecId("credentials")]["secret_access_key"] = ( - "explicit_password", - all_stages_form_data[FormSpecId("credentials")]["secret_access_key"][1], - ( - ad_hoc_password_id(), - all_stages_form_data[FormSpecId("credentials")]["secret_access_key"][2][1], - ), - ) - passwords = _collect_passwords_from_form_data(all_stages_form_data, parameter_form) + collected_passwords = _collect_passwords_from_form_data(all_stages_form_data, parameter_form) - # TODO: DCD still to be implemented cmk-18341 + stored_passwords = load_passwords() + # We need to filter out the passwords that are already stored in the password store since they + # should be independent of the configuration bundle + passwords = { + pwid: pw for pwid, pw in collected_passwords.items() if pwid not in stored_passwords + } + # TODO: The sanitize function is likely to change once we have a folder FormSpec. + folder = sanitize_folder_path(host_path) hosts = [ - create_host_from_form_data( - host_name=HostName(host_name), host_path=host_path, site_id=site_id + create_special_agent_host_from_form_data( + host_name=HostName(host_name), folder=folder, site_id=site_id ) ] create_config_bundle( - bundle_id=BundleId(bundle_id), + bundle_id=bundle_id, bundle=ConfigBundle( title=f"{bundle_id}_config", comment="", @@ -269,23 +288,24 @@ def _create_and_save_special_agent_bundle( passwords=create_passwords( passwords=passwords, rulespec_name=rulespec_name, - bundle_id=BundleId(bundle_id), + bundle_id=bundle_id, ), rules=[ create_rule( params=params, - host_name=host["name"], - host_path=host["folder"].path(), + host_name=create_host["name"], + host_path=create_host["folder"].path(), rulespec_name=rulespec_name, - bundle_id=BundleId(bundle_id), + bundle_id=bundle_id, site_id=site_id, ) - for host in hosts + for create_host in hosts ], + dcd_connections=DCDHook.create_dcd_connections(bundle_id, site_id, folder), ), ) try: - host: Host = Host.load_host(host_name) + host: Host = Host.load_host(HostName(host_name)) if not site_is_local(active_config, site_id): get_check_table(host, DiscoveryAction.REFRESH, raise_errors=False) snapshot = fetch_service_discovery_background_job_status(site_id, host_name) @@ -309,6 +329,10 @@ def _create_and_save_special_agent_bundle( return makeuri_contextless( request, - [("mode", ModeActivateChanges.name())], + [ + ("mode", ModeActivateChanges.name()), + ("origin", "quick_setup"), + ("special_agent_name", special_agent_name), + ], filename="wato.py", ) diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_recaps.py b/cmk/gui/quick_setup/v0_unstable/predefined/_recaps.py index 3e79843bd84..62f7e28a443 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/_recaps.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_recaps.py @@ -6,26 +6,18 @@ from collections.abc import Callable, Mapping, Sequence from functools import partial -from livestatus import SiteId - -from cmk.ccc.site import omd_site - -from cmk.automations.results import SpecialAgentDiscoveryPreviewResult - -from cmk.checkengine.discovery import CheckPreviewEntry - from cmk.gui.form_specs.vue.form_spec_visitor import serialize_data_for_frontend from cmk.gui.form_specs.vue.visitors import DataOrigin from cmk.gui.i18n import ungettext from cmk.gui.quick_setup.v0_unstable._registry import quick_setup_registry from cmk.gui.quick_setup.v0_unstable.predefined._common import ( _collect_params_with_defaults_from_form_data, - _collect_passwords_from_form_data, - _create_diag_special_agent_input, - _find_unique_id, - _match_service_interest, build_quick_setup_formspec_map, ) +from cmk.gui.quick_setup.v0_unstable.predefined._utils import ( + get_service_discovery_preview, + group_services_by_interest, +) from cmk.gui.quick_setup.v0_unstable.setups import CallableRecap from cmk.gui.quick_setup.v0_unstable.type_defs import ( ParsedFormData, @@ -34,7 +26,6 @@ StageIndex, ) from cmk.gui.quick_setup.v0_unstable.widgets import FormSpecRecap, ListOfWidgets, Text, Widget -from cmk.gui.watolib.check_mk_automations import special_agent_discovery_preview from cmk.rulesets.v1.form_specs import Dictionary @@ -48,7 +39,7 @@ def recaps_form_spec( if quick_setup is None: raise ValueError(f"Quick setup with id {quick_setup_id} not found") - quick_setup_formspec_map = build_quick_setup_formspec_map([quick_setup.stages[stage_index]]) + quick_setup_formspec_map = build_quick_setup_formspec_map([quick_setup.stages[stage_index]()]) return [ FormSpecRecap( @@ -104,18 +95,13 @@ def _recap_service_discovery( _stage_index: StageIndex, all_stages_form_data: ParsedFormData, ) -> Sequence[Widget]: - params = collect_params(all_stages_form_data, parameter_form) - passwords = _collect_passwords_from_form_data(all_stages_form_data, parameter_form) - site_id = _find_unique_id(all_stages_form_data, "site_selection") - host_name = _find_unique_id(all_stages_form_data, "host_name") - - service_discovery_result = special_agent_discovery_preview( - SiteId(site_id) if site_id else omd_site(), - _create_diag_special_agent_input( - rulespec_name=rulespec_name, host_name=host_name, passwords=passwords, params=params - ), + service_discovery_result = get_service_discovery_preview( + rulespec_name=rulespec_name, + all_stages_form_data=all_stages_form_data, + parameter_form=parameter_form, + collect_params=collect_params, ) - check_preview_entry_by_service_interest, others = _check_preview_entry_by_service_interest( + check_preview_entry_by_service_interest, others = group_services_by_interest( services_of_interest, service_discovery_result ) items: list[Widget] = [ @@ -128,23 +114,3 @@ def _recap_service_discovery( items.append(Text(text=ungettext("%s other service", "%s other services", len(others)))) return [ListOfWidgets(items=items, list_type="check")] - - -def _check_preview_entry_by_service_interest( - services_of_interest: Sequence[ServiceInterest], - service_discovery_result: SpecialAgentDiscoveryPreviewResult, -) -> tuple[Mapping[ServiceInterest, list[CheckPreviewEntry]], list[CheckPreviewEntry]]: - check_preview_entry_by_service_interest: Mapping[ServiceInterest, list[CheckPreviewEntry]] = { - si: [] for si in services_of_interest - } - others: list[CheckPreviewEntry] = [] - for check_preview_entry in service_discovery_result.check_table: - if matching_services_interests := _match_service_interest( - check_preview_entry, services_of_interest - ): - check_preview_entry_by_service_interest[matching_services_interests].append( - check_preview_entry - ) - else: - others.append(check_preview_entry) - return check_preview_entry_by_service_interest, others diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_utils.py b/cmk/gui/quick_setup/v0_unstable/predefined/_utils.py new file mode 100644 index 00000000000..6a3dfb549b0 --- /dev/null +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_utils.py @@ -0,0 +1,69 @@ +#!/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 Callable, Mapping, Sequence + +from livestatus import SiteId + +from cmk.ccc.site import omd_site + +from cmk.automations.results import SpecialAgentDiscoveryPreviewResult + +from cmk.checkengine.discovery import CheckPreviewEntry + +from cmk.gui.quick_setup.v0_unstable.definitions import QSHostName, QSSiteSelection +from cmk.gui.quick_setup.v0_unstable.predefined._common import ( + _collect_passwords_from_form_data, + _create_diag_special_agent_input, + _find_id_in_form_data, + _match_service_interest, +) +from cmk.gui.quick_setup.v0_unstable.type_defs import ( + ParsedFormData, + ServiceInterest, +) +from cmk.gui.watolib.check_mk_automations import special_agent_discovery_preview + +from cmk.rulesets.v1.form_specs import Dictionary + + +def get_service_discovery_preview( + rulespec_name: str, + all_stages_form_data: ParsedFormData, + parameter_form: Dictionary, + collect_params: Callable[[ParsedFormData, Dictionary], Mapping[str, object]], +) -> SpecialAgentDiscoveryPreviewResult: + params = collect_params(all_stages_form_data, parameter_form) + passwords = _collect_passwords_from_form_data(all_stages_form_data, parameter_form) + site_id = _find_id_in_form_data(all_stages_form_data, QSSiteSelection) + host_name = _find_id_in_form_data(all_stages_form_data, QSHostName) + + service_discovery_result = special_agent_discovery_preview( + SiteId(site_id) if site_id else omd_site(), + _create_diag_special_agent_input( + rulespec_name=rulespec_name, host_name=host_name, passwords=passwords, params=params + ), + ) + return service_discovery_result + + +def group_services_by_interest( + services_of_interest: Sequence[ServiceInterest], + service_discovery_result: SpecialAgentDiscoveryPreviewResult, +) -> tuple[Mapping[ServiceInterest, list[CheckPreviewEntry]], list[CheckPreviewEntry]]: + check_preview_entry_by_service_interest: Mapping[ServiceInterest, list[CheckPreviewEntry]] = { + si: [] for si in services_of_interest + } + others: list[CheckPreviewEntry] = [] + for check_preview_entry in service_discovery_result.check_table: + if matching_services_interests := _match_service_interest( + check_preview_entry, services_of_interest + ): + check_preview_entry_by_service_interest[matching_services_interests].append( + check_preview_entry + ) + else: + others.append(check_preview_entry) + return check_preview_entry_by_service_interest, others diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_validators.py b/cmk/gui/quick_setup/v0_unstable/predefined/_validators.py index 76ce038a122..1ad47b9a5bc 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/_validators.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_validators.py @@ -5,17 +5,25 @@ from collections.abc import Callable, Mapping from functools import partial +from uuid import uuid4 from livestatus import SiteId from cmk.ccc.site import omd_site -from cmk.gui.quick_setup.v0_unstable.definitions import UniqueBundleIDStr +from cmk.utils.hostaddress import HostName + +from cmk.gui.i18n import _ +from cmk.gui.quick_setup.v0_unstable.definitions import ( + QSHostName, + QSSiteSelection, + UniqueBundleIDStr, +) from cmk.gui.quick_setup.v0_unstable.predefined._common import ( _collect_params_with_defaults_from_form_data, _collect_passwords_from_form_data, _create_diag_special_agent_input, - _find_unique_id, + _find_id_in_form_data, ) from cmk.gui.quick_setup.v0_unstable.setups import CallableValidator from cmk.gui.quick_setup.v0_unstable.type_defs import ( @@ -26,6 +34,7 @@ ) from cmk.gui.watolib.check_mk_automations import diag_special_agent from cmk.gui.watolib.configuration_bundles import ConfigBundleStore +from cmk.gui.watolib.hosts_and_folders import Host from cmk.rulesets.v1.form_specs import Dictionary @@ -34,24 +43,28 @@ def validate_test_connection_custom_collect_params( rulespec_name: str, parameter_form: Dictionary, custom_collect_params: Callable[[ParsedFormData, Dictionary], Mapping[str, object]], + error_message: str | None = None, ) -> CallableValidator: return partial( _validate_test_connection, rulespec_name, parameter_form, custom_collect_params, + error_message, ) def validate_test_connection( rulespec_name: str, parameter_form: Dictionary, + error_message: str | None = None, ) -> CallableValidator: return partial( _validate_test_connection, rulespec_name, parameter_form, _collect_params_with_defaults_from_form_data, + error_message, ) @@ -59,13 +72,14 @@ def _validate_test_connection( rulespec_name: str, parameter_form: Dictionary, collect_params: Callable[[ParsedFormData, Dictionary], Mapping[str, object]], + error_message: str | None, _quick_setup_id: QuickSetupId, _stage_index: StageIndex, all_stages_form_data: ParsedFormData, ) -> GeneralStageErrors: general_errors: GeneralStageErrors = [] - site_id = _find_unique_id(all_stages_form_data, "site_selection") - host_name = _find_unique_id(all_stages_form_data, "host_name") + site_id = _find_id_in_form_data(all_stages_form_data, QSSiteSelection) + host_name = _find_id_in_form_data(all_stages_form_data, QSHostName) or str(uuid4()) params = collect_params(all_stages_form_data, parameter_form) passwords = _collect_passwords_from_form_data(all_stages_form_data, parameter_form) output = diag_special_agent( @@ -76,7 +90,10 @@ def _validate_test_connection( ) for result in output.results: if result.return_code != 0: - general_errors.append(result.response) + if error_message: + general_errors.append(error_message) + # Do not show long output + general_errors.append(result.response.split("\n")[-1]) return general_errors @@ -85,7 +102,7 @@ def validate_unique_id( _stage_index: StageIndex, stages_form_data: ParsedFormData, ) -> GeneralStageErrors: - bundle_id = _find_unique_id(stages_form_data, UniqueBundleIDStr) + bundle_id = _find_id_in_form_data(stages_form_data, UniqueBundleIDStr) if bundle_id is None: return [f"Expected the key '{UniqueBundleIDStr}' in the form data"] @@ -93,3 +110,23 @@ def validate_unique_id( return [f'Configuration bundle "{bundle_id}" already exists.'] return [] + + +def validate_host_name_doesnt_exists( + _quick_setup_id: QuickSetupId, + _stage_index: StageIndex, + stages_form_data: ParsedFormData, +) -> GeneralStageErrors: + host_name = _find_id_in_form_data(stages_form_data, QSHostName) + assert host_name is not None + host = Host.host(HostName(host_name)) + if host: + return [ + _( + "A host with the name %s already exists in the folder %s. " + "Please choose a different host name." + ) + % (host_name, host.folder().alias_path()) + ] + + return [] diff --git a/cmk/gui/quick_setup/v0_unstable/predefined/_widgets.py b/cmk/gui/quick_setup/v0_unstable/predefined/_widgets.py index a62bc12294d..69aa7cebc1e 100644 --- a/cmk/gui/quick_setup/v0_unstable/predefined/_widgets.py +++ b/cmk/gui/quick_setup/v0_unstable/predefined/_widgets.py @@ -7,11 +7,17 @@ from cmk.gui.fields.definitions import HOST_NAME_REGEXP from cmk.gui.form_specs.private.dictionary_extended import DictionaryExtended from cmk.gui.form_specs.vue.shared_type_defs import DictionaryLayout -from cmk.gui.quick_setup.v0_unstable.definitions import UniqueBundleIDStr, UniqueFormSpecIDStr +from cmk.gui.quick_setup.v0_unstable.definitions import ( + QSHostName, + QSHostPath, + UniqueBundleIDStr, + UniqueFormSpecIDStr, +) from cmk.gui.quick_setup.v0_unstable.widgets import FormSpecId, FormSpecWrapper from cmk.gui.watolib.configuration_bundles import ConfigBundleStore +from cmk.gui.watolib.hosts_and_folders import folder_tree -from cmk.rulesets.v1 import Title +from cmk.rulesets.v1 import Message, Title from cmk.rulesets.v1.form_specs import DictElement, FieldSize, String, validators from cmk.rulesets.v1.form_specs._base import DefaultValue @@ -28,7 +34,12 @@ def unique_id_formspec_wrapper( parameter_form=String( title=title, field_size=FieldSize.MEDIUM, - custom_validate=(validators.LengthInRange(min_value=1),), + custom_validate=( + validators.LengthInRange( + min_value=1, + error_msg=Message("%s cannot be empty") % str(title), + ), + ), prefill=DefaultValue( unique_default_name_suggestion( template=prefill_template, @@ -44,14 +55,29 @@ def unique_id_formspec_wrapper( ) -def _host_name_dict_element(title: Title = Title("Host name")) -> DictElement: +def _host_name_dict_element( + title: Title = Title("Host name"), + prefill_template: str = "qs_host", +) -> DictElement: return DictElement( parameter_form=String( title=title, field_size=FieldSize.MEDIUM, custom_validate=( - validators.LengthInRange(min_value=1), - validators.MatchRegex(HOST_NAME_REGEXP), + validators.LengthInRange( + min_value=1, + error_msg=Message("%s cannot be empty") % str(title), + ), + validators.MatchRegex( + regex=HOST_NAME_REGEXP, + error_msg=Message("Invalid characters in %s") % str(title), + ), + ), + prefill=DefaultValue( + unique_default_name_suggestion( + template=prefill_template, + used_names=set(folder_tree().root_folder().all_hosts_recursively()), + ) ), ), required=True, @@ -63,24 +89,31 @@ def _host_name_dict_element(title: Title = Title("Host name")) -> DictElement: ) -def _host_path_dict_element(title: Title = Title("Host Path")) -> DictElement: +def _host_path_dict_element(title: Title = Title("Folder")) -> DictElement: return DictElement( parameter_form=String( title=title, field_size=FieldSize.MEDIUM, - custom_validate=(validators.MatchRegex(FOLDER_PATTERN),), + custom_validate=( + validators.MatchRegex( + regex=FOLDER_PATTERN, + error_msg=Message("Invalid characters in %s") % str(title), + ), + ), ), required=True, ) -def host_name_and_host_path_formspec_wrapper() -> FormSpecWrapper: +def host_name_and_host_path_formspec_wrapper( + host_prefill_template: str = "qs_host", +) -> FormSpecWrapper: return FormSpecWrapper( id=FormSpecId("host_data"), form_spec=DictionaryExtended( elements={ - "host_name": _host_name_dict_element(), - "host_path": _host_path_dict_element(), + QSHostName: _host_name_dict_element(prefill_template=host_prefill_template), + QSHostPath: _host_path_dict_element(), }, layout=DictionaryLayout.two_columns, ), diff --git a/cmk/gui/quick_setup/v0_unstable/setups.py b/cmk/gui/quick_setup/v0_unstable/setups.py index 1c1d0dbeec7..b4bddbffd75 100644 --- a/cmk/gui/quick_setup/v0_unstable/setups.py +++ b/cmk/gui/quick_setup/v0_unstable/setups.py @@ -22,6 +22,13 @@ WidgetConfigurator = Callable[[], Sequence[Widget]] +@dataclass(frozen=True) +class QuickSetupSaveAction: + id: str + label: str + action: CallableSaveAction + + @dataclass(frozen=True) class QuickSetupStage: title: str @@ -36,6 +43,5 @@ class QuickSetupStage: class QuickSetup: title: str id: QuickSetupId - stages: Sequence[QuickSetupStage] - button_complete_label: str - save_action: CallableSaveAction | None = None + stages: Sequence[Callable[[], QuickSetupStage]] + save_actions: Sequence[QuickSetupSaveAction] diff --git a/cmk/gui/rulespec.py b/cmk/gui/rulespec.py index 8acf61fd67e..4743d12f323 100644 --- a/cmk/gui/rulespec.py +++ b/cmk/gui/rulespec.py @@ -8,7 +8,6 @@ from cmk.ccc.debug import enabled as debug_enabled -from cmk.gui.form_specs.vue.visitors._registry import form_spec_registry from cmk.gui.i18n import _ from cmk.gui.log import logger from cmk.gui.utils import add_failed_plugin @@ -44,9 +43,6 @@ def register_plugins(loaded_rule_specs: Sequence[LoadedRuleSpec]) -> None: "Duplicate rule_spec '%s', keeping legacy rulespec", legacy_rulespec.name ) continue - # This isn't actually a "real" registry - # Just some lookup for the experimental formspec rendering - form_spec_registry[loaded_rule_spec.rule_spec.name] = loaded_rule_spec rulespec_registry.register(legacy_rulespec) except Exception as e: diff --git a/cmk/gui/sidebar/__init__.py b/cmk/gui/sidebar/__init__.py index 1e726b94b4e..1d5924755e2 100644 --- a/cmk/gui/sidebar/__init__.py +++ b/cmk/gui/sidebar/__init__.py @@ -11,7 +11,7 @@ import os import textwrap import traceback -from collections.abc import Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass from enum import Enum from typing import Any, cast, Self @@ -34,11 +34,12 @@ from cmk.gui.i18n import _ from cmk.gui.log import logger from cmk.gui.logged_in import LoggedInUser, user -from cmk.gui.main_menu import mega_menu_registry +from cmk.gui.main_menu import mega_menu_registry, MegaMenuRegistry from cmk.gui.page_menu import PageMenu, PageMenuDropdown, PageMenuTopic from cmk.gui.pages import AjaxPage, PageRegistry, PageResult from cmk.gui.permissions import PermissionSectionRegistry from cmk.gui.type_defs import Icon as Icon +from cmk.gui.type_defs import TopicMenuTopic from cmk.gui.user_sites import get_configured_site_choices from cmk.gui.utils import load_web_plugins from cmk.gui.utils.csrf_token import check_csrf_token @@ -53,6 +54,7 @@ from ._snapin import begin_footnote_links as begin_footnote_links from ._snapin import bulletlink as bulletlink from ._snapin import CustomizableSidebarSnapin as CustomizableSidebarSnapin +from ._snapin import default_view_menu_topics as default_view_menu_topics from ._snapin import end_footnote_links as end_footnote_links from ._snapin import footnotelinks as footnotelinks from ._snapin import heading as heading @@ -68,6 +70,7 @@ from ._snapin import snapin_site_choice as snapin_site_choice from ._snapin import snapin_width as snapin_width from ._snapin import SnapinRegistry as SnapinRegistry +from ._snapin import view_menu_items as view_menu_items from ._snapin import write_snapin_exception as write_snapin_exception from ._snapin_dashlet import SnapinDashlet from .main_menu import ( @@ -86,6 +89,8 @@ def register( permission_section_registry: PermissionSectionRegistry, snapin_registry_: SnapinRegistry, dashlet_registry: DashletRegistry, + mega_menu_registry_: MegaMenuRegistry, + view_menu_topics: Callable[[], list[TopicMenuTopic]], ) -> None: page_registry.register_page("sidebar_fold")(AjaxFoldSnapin) page_registry.register_page("sidebar_openclose")(AjaxOpenCloseSnapin) @@ -101,7 +106,12 @@ def register( PageAjaxSidebarGetUnackIncompWerks ) permission_section_registry.register(PermissionSectionSidebarSnapins) - _snapin.register(snapin_registry_, page_registry) + _snapin.register( + snapin_registry_, + page_registry, + mega_menu_registry_, + view_menu_topics, + ) dashlet_registry.register(SnapinDashlet) diff --git a/cmk/gui/sidebar/_snapin/__init__.py b/cmk/gui/sidebar/_snapin/__init__.py index f66306a48ca..90a06eaa2ab 100644 --- a/cmk/gui/sidebar/_snapin/__init__.py +++ b/cmk/gui/sidebar/_snapin/__init__.py @@ -3,13 +3,18 @@ # 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 Callable + from cmk.ccc import version from cmk.ccc.version import edition_supports_nagvis from cmk.utils import paths +from cmk.gui.main_menu import MegaMenuRegistry from cmk.gui.pages import PageRegistry +from cmk.gui.type_defs import TopicMenuTopic +from . import _views from ._base import CustomizableSidebarSnapin as CustomizableSidebarSnapin from ._base import PageHandlers as PageHandlers from ._base import SidebarSnapin as SidebarSnapin @@ -40,10 +45,17 @@ from ._site_status import SiteStatus from ._speedometer import Speedometer from ._tactical_overview import TacticalOverviewSnapin -from ._views import ajax_export_views, Views +from ._views import ajax_export_views +from ._views import default_view_menu_topics as default_view_menu_topics +from ._views import view_menu_items as view_menu_items -def register(snapin_registry_: SnapinRegistry, page_registry: PageRegistry) -> None: +def register( + snapin_registry_: SnapinRegistry, + page_registry: PageRegistry, + mega_menu_registry: MegaMenuRegistry, + view_menu_topics: Callable[[], list[TopicMenuTopic]], +) -> None: snapin_registry_.register(Bookmarks) snapin_registry_.register(Dashboards) snapin_registry_.register(HostGroups) @@ -57,7 +69,6 @@ def register(snapin_registry_: SnapinRegistry, page_registry: PageRegistry) -> N snapin_registry_.register(SiteStatus) snapin_registry_.register(Speedometer) snapin_registry_.register(TacticalOverviewSnapin) - snapin_registry_.register(Views) - page_registry.register_page_handler("export_views", ajax_export_views) + _views.register(page_registry, snapin_registry_, mega_menu_registry, view_menu_topics) page_registry.register_page("ajax_search_monitoring")(PageSearchMonitoring) page_registry.register_page("ajax_search_setup")(PageSearchSetup) diff --git a/cmk/gui/sidebar/_snapin/_views.py b/cmk/gui/sidebar/_snapin/_views.py index 3dfc7e31492..ea2b02f9f85 100644 --- a/cmk/gui/sidebar/_snapin/_views.py +++ b/cmk/gui/sidebar/_snapin/_views.py @@ -6,7 +6,7 @@ # pylint: disable=protected-access import pprint -from collections.abc import Sequence +from collections.abc import Callable from cmk.utils.user import UserId @@ -18,13 +18,36 @@ from cmk.gui.http import response from cmk.gui.i18n import _, _l from cmk.gui.logged_in import user -from cmk.gui.main_menu import mega_menu_registry +from cmk.gui.main_menu import MegaMenuRegistry from cmk.gui.nodevis.topology import ParentChildTopologyPage +from cmk.gui.pages import PageRegistry from cmk.gui.type_defs import ABCMegaMenuSearch, MegaMenu, TopicMenuTopic, Visual from cmk.gui.views.store import get_permitted_views from ._base import SidebarSnapin from ._helpers import footnotelinks, make_topic_menu, show_topic_menu +from ._registry import SnapinRegistry + + +def register( + page_registry: PageRegistry, + snapin_registry: SnapinRegistry, + mega_menu_registry: MegaMenuRegistry, + view_menu_topics: Callable[[], list[TopicMenuTopic]], +) -> None: + snapin_registry.register(Views) + page_registry.register_page_handler("export_views", ajax_export_views) + + mega_menu_registry.register( + MegaMenu( + name="monitoring", + title=_l("Monitor"), + icon="main_monitoring", + sort_index=5, + topics=view_menu_topics, + search=MonitoringSearch("monitoring_search"), + ) + ) class Views(SidebarSnapin): @@ -41,7 +64,7 @@ def description(cls): return _("Links to global views and dashboards") def show(self): - show_topic_menu(treename="views", menu=view_menu_topics(include_reports=False)) + show_topic_menu(treename="views", menu=make_topic_menu(view_menu_items())) links = [] if user.may("general.edit_views"): @@ -59,11 +82,11 @@ def ajax_export_views() -> None: @request_memoize() -def view_menu_topics(include_reports: bool) -> list[TopicMenuTopic]: - return make_topic_menu(view_menu_items(include_reports)) +def default_view_menu_topics() -> list[TopicMenuTopic]: + return make_topic_menu(view_menu_items()) -def view_menu_items(include_reports: bool) -> Sequence[tuple[str, tuple[str, Visual]]]: +def view_menu_items() -> list[tuple[str, tuple[str, Visual]]]: # The page types that are implementing the PageRenderer API should also be # part of the menu. Bring them into a visual like structure to make it easy to # integrate them. @@ -99,17 +122,9 @@ def view_menu_items(include_reports: bool) -> Sequence[tuple[str, tuple[str, Vis visuals_to_show += [("pages", e) for e in pages_to_show] visuals_to_show += page_type_items - if include_reports: - visuals_to_show += report_menu_items() - return visuals_to_show -def report_menu_items() -> list[tuple[str, tuple[str, Visual]]]: - """Is replaced by cmk.gui.reporting.registration""" - return [] - - class MonitoringSearch(ABCMegaMenuSearch): """Search field in the monitoring menu""" @@ -154,15 +169,3 @@ def show_search_field(self) -> None: ) html.close_div() html.div("", id_="mk_side_clear") - - -mega_menu_registry.register( - MegaMenu( - name="monitoring", - title=_l("Monitor"), - icon="main_monitoring", - sort_index=5, - topics=lambda: view_menu_topics(include_reports=True), - search=MonitoringSearch("monitoring_search"), - ) -) diff --git a/cmk/gui/sites.py b/cmk/gui/sites.py index 94edef3580b..7b3220ddf2a 100644 --- a/cmk/gui/sites.py +++ b/cmk/gui/sites.py @@ -34,11 +34,13 @@ from cmk.gui.config import active_config from cmk.gui.ctx_stack import g +from cmk.gui.flask_app import current_app from cmk.gui.http import request from cmk.gui.i18n import _ from cmk.gui.log import logger from cmk.gui.logged_in import LoggedInUser from cmk.gui.logged_in import user as global_user +from cmk.gui.site_config import get_site_config from cmk.gui.utils.compatibility import ( is_distributed_monitoring_compatible_for_licensing, LicensingCompatibility, @@ -276,13 +278,15 @@ def _inhibit_incompatible_site_connection( } -ConnectionClass = MultiSiteConnection - - def _connect_multiple_sites(user: LoggedInUser) -> None: enabled_sites, disabled_sites = _get_enabled_and_disabled_sites(user) _set_initial_site_states(enabled_sites, disabled_sites) - g.live = ConnectionClass(enabled_sites, disabled_sites) + + g.live = MultiSiteConnection( + sites=enabled_sites, + disabled_sites=disabled_sites, + only_sites_postprocess=current_app().features.livestatus_only_sites_postprocess, + ) # Fetch status of sites by querying the version of Nagios and livestatus # This may be cached by a proxy for up to the next configuration reload. @@ -598,3 +602,14 @@ def filter_available_site_choices(choices: list[tuple[SiteId, str]]) -> list[tup continue sites_enabled.append(entry) return sites_enabled + + +def site_choices() -> list[tuple[str, str]]: + return sorted( + [ + (sitename, get_site_config(active_config, sitename)["alias"]) + for sitename, state in states().items() + if state["state"] == "online" + ], + key=lambda a: a[1].lower(), + ) diff --git a/cmk/gui/userdb/registration.py b/cmk/gui/userdb/registration.py index 03d1efe8a6e..d8d607d3a46 100644 --- a/cmk/gui/userdb/registration.py +++ b/cmk/gui/userdb/registration.py @@ -20,7 +20,7 @@ from .htpasswd import HtpasswdUserConnector from .user_sync_job import ajax_sync, execute_userdb_job, UserSyncBackgroundJob -__all__ = ["register", "saas_register"] +__all__ = ["register"] def register( @@ -47,7 +47,3 @@ def register( contact_group_usage_finder_registry.register(find_usages_of_contact_group_in_users) timeperiod_usage_finder_registry.register(find_timeperiod_usage_in_users) user_connector_registry.register(HtpasswdUserConnector) - - -def saas_register(saas_user_attribute_registry: UserAttributeRegistry) -> None: - user_attributes.saas_register(saas_user_attribute_registry) diff --git a/cmk/gui/userdb/user_attributes.py b/cmk/gui/userdb/user_attributes.py index 02f3d877a79..62ff83e051d 100644 --- a/cmk/gui/userdb/user_attributes.py +++ b/cmk/gui/userdb/user_attributes.py @@ -40,10 +40,6 @@ def register(user_attribute_registry: UserAttributeRegistry) -> None: user_attribute_registry.register(UIBasicAdvancedToggle) -def saas_register(saas_user_attribute_registry: UserAttributeRegistry) -> None: - saas_user_attribute_registry.register(UISaaSOnboardingButtonToggle) - - class TemperatureUnitUserAttribute(UserAttribute): @classmethod def name(cls) -> str: @@ -269,25 +265,6 @@ def domain(self) -> str: return "multisite" -class UISaaSOnboardingButtonToggle(UserAttribute): - @classmethod - def name(cls) -> str: - return "ui_saas_onboarding_button_toggle" - - def topic(self) -> str: - return "interface" - - def valuespec(self) -> ValueSpec: - return DropdownChoice( - title=_("Toggle onboarding button"), - # FIXME: Why isn't this simply a bool instead of an Optional[Literal["Invisible"]]? - choices=[(None, _("Visible")), ("invisible", _("Invisible"))], - ) - - def domain(self) -> str: - return "multisite" - - class UIIconTitle(UserAttribute): @classmethod def name(cls) -> str: diff --git a/cmk/gui/utils/rule_specs/legacy_converter.py b/cmk/gui/utils/rule_specs/legacy_converter.py index 0e4faa129ce..2b99d92a764 100644 --- a/cmk/gui/utils/rule_specs/legacy_converter.py +++ b/cmk/gui/utils/rule_specs/legacy_converter.py @@ -10,7 +10,7 @@ from dataclasses import dataclass from functools import partial from types import ModuleType -from typing import Any, assert_never, Literal, Self, TypeVar +from typing import Any, assert_never, Literal, Self, Tuple, TypeVar from cmk.ccc.version import Edition @@ -22,6 +22,15 @@ from cmk.gui import valuespec as legacy_valuespecs from cmk.gui import wato as legacy_wato from cmk.gui.exceptions import MKUserError +from cmk.gui.form_specs.private import ( + DictionaryExtended, + LegacyValueSpec, + ListExtended, + ListOfStrings, + MonitoredHostExtended, +) +from cmk.gui.form_specs.vue.shared_type_defs import ListOfStringsLayout +from cmk.gui.form_specs.vue.visitors import DefaultValue as VueDefaultValue from cmk.gui.utils.autocompleter_config import ContextAutocompleterConfig from cmk.gui.utils.rule_specs.loader import RuleSpec as APIV1RuleSpec from cmk.gui.utils.urls import DocReference @@ -36,6 +45,7 @@ from cmk.gui.watolib.rulespecs import ( CheckParameterRulespecWithItem, CheckParameterRulespecWithoutItem, + FormSpecDefinition, ManualCheckParameterRulespec, rulespec_group_registry, ) @@ -49,6 +59,14 @@ legacy_bakery_groups = None +@dataclass(frozen=True) +class FormSpecCallable: + spec: Callable[[], ruleset_api_v1.form_specs.FormSpec[Any]] + + def __call__(self) -> ruleset_api_v1.form_specs.FormSpec: + return self.spec() + + GENERATED_GROUP_PREFIX = "gen-" RULESET_DOC_REFERENCES_MAP = { @@ -195,7 +213,9 @@ def _convert_to_legacy_check_parameter_rulespec( edition_only: Edition, localizer: Callable[[str], str], ) -> CheckParameterRulespecWithItem | CheckParameterRulespecWithoutItem: - if isinstance(to_convert.condition, ruleset_api_v1.rule_specs.HostAndItemCondition): + convert_condition = to_convert.condition + if isinstance(convert_condition, ruleset_api_v1.rule_specs.HostAndItemCondition): + item_spec, item_form_spec = _get_item_spec_maker(convert_condition, localizer) return CheckParameterRulespecWithItem( check_group_name=to_convert.name, title=( @@ -206,16 +226,19 @@ def _convert_to_legacy_check_parameter_rulespec( to_convert.topic, localizer, ), - item_spec=_get_item_spec_maker(to_convert.condition, localizer), + item_spec=item_spec, match_type="dict", parameter_valuespec=partial( - convert_to_legacy_valuespec, to_convert.parameter_form(), localizer + convert_to_legacy_valuespec, FormSpecCallable(to_convert.parameter_form), localizer ), is_deprecated=to_convert.is_deprecated, create_manual_check=False, # weird field since the CME, as well as the CSE is based on a CCE, but we currently only # want to mark rulespecs that are available in both the CCE and CME as such is_cloud_and_managed_edition_only=edition_only is Edition.CCE, + form_spec_definition=FormSpecDefinition( + to_convert.parameter_form, lambda: item_form_spec + ), ) return CheckParameterRulespecWithoutItem( check_group_name=to_convert.name, @@ -225,10 +248,11 @@ def _convert_to_legacy_check_parameter_rulespec( ), match_type="dict", parameter_valuespec=partial( - convert_to_legacy_valuespec, to_convert.parameter_form(), localizer + convert_to_legacy_valuespec, FormSpecCallable(to_convert.parameter_form), localizer ), create_manual_check=False, is_cloud_and_managed_edition_only=edition_only is Edition.CCE, + form_spec_definition=FormSpecDefinition(to_convert.parameter_form, None), ) @@ -240,8 +264,14 @@ def _convert_to_legacy_manual_check_parameter_rulespec( match to_convert.condition: case ruleset_api_v1.rule_specs.HostCondition(): item_spec = None + item_form_spec = None case ruleset_api_v1.rule_specs.HostAndItemCondition(): - item_spec = _get_item_spec_maker(to_convert.condition, localizer) + item_spec, item_as_form_spec = _get_item_spec_maker(to_convert.condition, localizer) + + def wrapped_value(): + return item_as_form_spec + + item_form_spec = wrapped_value case other: assert_never(other) @@ -251,7 +281,9 @@ def _convert_to_legacy_manual_check_parameter_rulespec( ), check_group_name=to_convert.name, parameter_valuespec=( - partial(convert_to_legacy_valuespec, to_convert.parameter_form(), localizer) + partial( + convert_to_legacy_valuespec, FormSpecCallable(to_convert.parameter_form), localizer + ) if to_convert.parameter_form is not None else None ), @@ -260,6 +292,9 @@ def _convert_to_legacy_manual_check_parameter_rulespec( match_type="dict", item_spec=item_spec, is_cloud_and_managed_edition_only=edition_only is Edition.CCE, + form_spec_definition=None + if to_convert.parameter_form is None + else FormSpecDefinition(to_convert.parameter_form, item_form_spec), ) @@ -327,11 +362,14 @@ def _convert_to_legacy_host_rule_spec_rulespec( return legacy_rulespecs.HostRulespec( group=_convert_to_legacy_rulespec_group(legacy_main_group, to_convert.topic, localizer), name=config_scope_prefix(to_convert.name), - valuespec=partial(convert_to_legacy_valuespec, to_convert.parameter_form(), localizer), + valuespec=partial( + convert_to_legacy_valuespec, FormSpecCallable(to_convert.parameter_form), localizer + ), title=None if to_convert.title is None else partial(to_convert.title.localize, localizer), is_deprecated=to_convert.is_deprecated, match_type=_convert_to_legacy_match_type(to_convert), doc_references=_get_doc_references(config_scope_prefix(to_convert.name), localizer), + form_spec_definition=FormSpecDefinition(to_convert.parameter_form, None), ) @@ -344,12 +382,15 @@ def _convert_to_legacy_agent_config_rule_spec( group=_convert_to_legacy_rulespec_group(legacy_main_group, to_convert.topic, localizer), name=RuleGroup.AgentConfig(to_convert.name), valuespec=partial( - _transform_agent_config_rule_spec_match_type, to_convert.parameter_form(), localizer + _transform_agent_config_rule_spec_match_type, + FormSpecCallable(to_convert.parameter_form), + localizer, ), title=None if to_convert.title is None else partial(to_convert.title.localize, localizer), is_deprecated=to_convert.is_deprecated, match_type=_convert_to_legacy_match_type(to_convert), doc_references=_get_doc_references(RuleGroup.AgentConfig(to_convert.name), localizer), + form_spec_definition=FormSpecDefinition(to_convert.parameter_form, None), ) @@ -363,19 +404,40 @@ def _add_agent_config_match_type_key(value: object) -> object: def _remove_agent_config_match_type_key(value: object) -> object: if isinstance(value, dict): - value.pop("cmk-match-type", None) - return value + return {k: v for k, v in value.items() if k != "cmk-match-type"} raise TypeError(value) def _transform_agent_config_rule_spec_match_type( - parameter_form: ruleset_api_v1.form_specs.Dictionary, localizer: Callable[[str], str] + parameter_form: FormSpecCallable, localizer: Callable[[str], str] ) -> legacy_valuespecs.ValueSpec: + legacy_vs = convert_to_legacy_valuespec(parameter_form, localizer) + inner_transform = ( + legacy_vs if isinstance(legacy_vs, Transform) and parameter_form().migrate else None + ) + if not inner_transform: + return Transform( + legacy_vs, + forth=_remove_agent_config_match_type_key, + back=_add_agent_config_match_type_key, + ) + + # We cannot simply wrap legacy_vs into a Transform to handle the match type key. Wrapping a + # valuespec into a Transform results in the following order of transformations: + # 1. outer transform (_remove_agent_config_match_type_key) + # 2. inner transforms + # _remove_agent_config_match_type_key fails for non-dictionaries, however, it is the job of the + # inner transforms to migrate to a dictionairy in case of a migration from a non-dictionary + # rule spec. return Transform( - convert_to_legacy_valuespec(parameter_form, localizer), - forth=_remove_agent_config_match_type_key, - back=_add_agent_config_match_type_key, + valuespec=Transform( + inner_transform._valuespec, # pylint: disable=protected-access + to_valuespec=_remove_agent_config_match_type_key, + from_valuespec=_add_agent_config_match_type_key, + ), + to_valuespec=inner_transform.to_valuespec, + from_valuespec=inner_transform.from_valuespec, ) @@ -390,13 +452,16 @@ def _convert_to_legacy_service_rule_spec_rulespec( ), item_type="service", name=config_scope_prefix(to_convert.name), - valuespec=partial(convert_to_legacy_valuespec, to_convert.parameter_form(), localizer), + valuespec=partial( + convert_to_legacy_valuespec, FormSpecCallable(to_convert.parameter_form), localizer + ), title=None if to_convert.title is None else partial(to_convert.title.localize, localizer), is_deprecated=to_convert.is_deprecated, match_type=( "dict" if to_convert.eval_type == ruleset_api_v1.rule_specs.EvalType.MERGE else "all" ), doc_references=_get_doc_references(config_scope_prefix(to_convert.name), localizer), + form_spec_definition=FormSpecDefinition(to_convert.parameter_form, None), ) @@ -663,7 +728,7 @@ def _convert_to_inner_legacy_valuespec( case ruleset_api_v1.form_specs.RegularExpression(): return _convert_to_legacy_regular_expression(to_convert, localizer) - case ruleset_api_v1.form_specs.Dictionary(): + case ruleset_api_v1.form_specs.Dictionary() | DictionaryExtended(): return _convert_to_legacy_dictionary(to_convert, localizer) case ruleset_api_v1.form_specs.SingleChoice(): @@ -678,9 +743,12 @@ def _convert_to_inner_legacy_valuespec( case ruleset_api_v1.form_specs.HostState(): return _convert_to_legacy_host_state(to_convert, localizer) - case ruleset_api_v1.form_specs.List(): + case ruleset_api_v1.form_specs.List() | ListExtended(): return _convert_to_legacy_list(to_convert, localizer) + case ListOfStrings(): + return _convert_to_legacy_list_of_strings(to_convert, localizer) + case ruleset_api_v1.form_specs.FixedValue(): return _convert_to_legacy_fixed_value(to_convert, localizer) @@ -702,7 +770,7 @@ def _convert_to_inner_legacy_valuespec( case ruleset_api_v1.form_specs.Metric(): return _convert_to_legacy_metric_name(to_convert, localizer) - case ruleset_api_v1.form_specs.MonitoredHost(): + case ruleset_api_v1.form_specs.MonitoredHost() | MonitoredHostExtended(): return _convert_to_legacy_monitored_host_name(to_convert, localizer) case ruleset_api_v1.form_specs.MonitoredService(): @@ -720,13 +788,20 @@ def _convert_to_inner_legacy_valuespec( case ruleset_api_v1.form_specs.TimePeriod(): return _convert_to_legacy_timeperiod_selection(to_convert, localizer) + case LegacyValueSpec(): + return to_convert.valuespec + case other: raise NotImplementedError(other) def convert_to_legacy_valuespec( - to_convert: ruleset_api_v1.form_specs.FormSpec, localizer: Callable[[str], str] + to_convert: ruleset_api_v1.form_specs.FormSpec | FormSpecCallable, + localizer: Callable[[str], str], ) -> legacy_valuespecs.ValueSpec: + if isinstance(to_convert, FormSpecCallable): + to_convert = to_convert() + def allow_empty_value_wrapper( update_func: Callable[[object], object], ) -> Callable[[object], object]: @@ -1022,6 +1097,10 @@ def _get_packed_value( packed_dict: dict, ) -> object: match nested_form, value_to_pack: + case DictionaryExtended() as dict_form, dict() as dict_to_pack: + return _pack_dict_groups( + dict_form.elements, dict_form.ignored_elements, dict_to_pack, packed_dict + ) case ruleset_api_v1.form_specs.Dictionary() as dict_form, dict() as dict_to_pack: return _pack_dict_groups( dict_form.elements, dict_form.ignored_elements, dict_to_pack, packed_dict @@ -1049,7 +1128,7 @@ def _pack_dict_groups( nested_packed_dict = {} if isinstance( (nested_form := dict_elements[key_to_pack].parameter_form), - ruleset_api_v1.form_specs.Dictionary, + (ruleset_api_v1.form_specs.Dictionary, DictionaryExtended), ): # handle innermost migrations if nested_form.migrate is not None: @@ -1088,6 +1167,10 @@ def _get_unpacked_value( nested_form: ruleset_api_v1.form_specs.FormSpec, value_to_unpack: object ) -> object: match nested_form, value_to_unpack: + case DictionaryExtended() as dict_form, dict() as dict_to_unpack: + return _unpack_dict_group( + dict_form.elements, dict_form.ignored_elements, dict_to_unpack + ) case ruleset_api_v1.form_specs.Dictionary() as dict_form, dict() as dict_to_unpack: return _unpack_dict_group( dict_form.elements, dict_form.ignored_elements, dict_to_unpack @@ -1151,7 +1234,8 @@ def wrapper(value: Mapping[str, object], var_prefix: str) -> None: def _convert_to_legacy_dictionary( - to_convert: ruleset_api_v1.form_specs.Dictionary, localizer: Callable[[str], str] + to_convert: ruleset_api_v1.form_specs.Dictionary | DictionaryExtended, + localizer: Callable[[str], str], ) -> legacy_valuespecs.Transform | legacy_valuespecs.Dictionary: ungrouped_element_key_props, ungrouped_elements = _get_ungrouped_elements( to_convert.elements, localizer @@ -1159,6 +1243,16 @@ def _convert_to_legacy_dictionary( grouped_elements_map, hidden_group_keys = _group_elements(to_convert.elements, localizer) required_group_keys = set(grouped_elements_map.keys()) - hidden_group_keys + default_keys: list[str] | None = None + if isinstance(to_convert, DictionaryExtended) and (prefill := to_convert.prefill) is not None: + default_keys = [] + for key, value in prefill.value.items(): + if not isinstance(value, VueDefaultValue): + raise ValueError( + "Unable to migrate prefill value. Only able to use Vue-DefaultValue as value for key." + ) + default_keys.append(key) + return legacy_valuespecs.Transform( legacy_valuespecs.Dictionary( elements=list(ungrouped_elements) + list(grouped_elements_map.items()), @@ -1168,6 +1262,7 @@ def _convert_to_legacy_dictionary( required_keys=ungrouped_element_key_props.required + list(required_group_keys), ignored_keys=list(to_convert.ignored_elements), hidden_keys=ungrouped_element_key_props.hidden + list(hidden_group_keys), + default_keys=default_keys, validate=( _convert_to_dict_legacy_validation( to_convert.custom_validate, @@ -1378,24 +1473,35 @@ def _convert_to_legacy_cascading_dropdown( def _get_item_spec_maker( condition: ruleset_api_v1.rule_specs.HostAndItemCondition, localizer: Callable[[str], str], -) -> Callable[ - [], - legacy_valuespecs.TextInput - | legacy_valuespecs.DropdownChoice - | legacy_valuespecs.TextAreaUnicode - | legacy_valuespecs.FixedValue, +) -> Tuple[ + Callable[ + [], + legacy_valuespecs.TextInput + | legacy_valuespecs.DropdownChoice + | legacy_valuespecs.TextAreaUnicode + | legacy_valuespecs.FixedValue, + ], + ruleset_api_v1.form_specs.FormSpec, ]: item_form_with_title = dataclasses.replace(condition.item_form, title=condition.item_title) match item_form_with_title: case ruleset_api_v1.form_specs.String(): - return partial(_convert_to_legacy_text_input, item_form_with_title, localizer) + return partial( + _convert_to_legacy_text_input, item_form_with_title, localizer + ), item_form_with_title case ruleset_api_v1.form_specs.SingleChoice(): - return partial(_convert_to_legacy_dropdown_choice, item_form_with_title, localizer) + return partial( + _convert_to_legacy_dropdown_choice, item_form_with_title, localizer + ), item_form_with_title case ruleset_api_v1.form_specs.MultilineText(): - return partial(_convert_to_legacy_text_area, item_form_with_title, localizer) + return partial( + _convert_to_legacy_text_area, item_form_with_title, localizer + ), item_form_with_title case ruleset_api_v1.form_specs.FixedValue(): - return partial(_convert_to_legacy_fixed_value, item_form_with_title, localizer) + return partial( + _convert_to_legacy_fixed_value, item_form_with_title, localizer + ), item_form_with_title case other: raise ValueError(other) @@ -1417,8 +1523,8 @@ def wrapper(value: _ValidateFuncType, var_prefix: str) -> None: def _convert_to_legacy_list( - to_convert: ruleset_api_v1.form_specs.List, localizer: Callable[[str], str] -) -> legacy_valuespecs.ListOf | legacy_valuespecs.ListOfStrings: + to_convert: ruleset_api_v1.form_specs.List | ListExtended, localizer: Callable[[str], str] +) -> legacy_valuespecs.ListOf: template = convert_to_legacy_valuespec(to_convert.element_template, localizer) converted_kwargs: dict[str, Any] = { "valuespec": template, @@ -1436,9 +1542,41 @@ def _convert_to_legacy_list( to_convert.custom_validate, localizer ) + if isinstance(to_convert, ListExtended): + converted_kwargs["default_value"] = to_convert.prefill.value + return legacy_valuespecs.ListOf(**converted_kwargs) +def _convert_to_legacy_list_of_strings( + to_convert: ListOfStrings, localizer: Callable[[str], str] +) -> legacy_valuespecs.ListOfStrings: + template = convert_to_legacy_valuespec(to_convert.string_spec, localizer) + match to_convert.layout: + case ListOfStringsLayout.horizontal: + orientation = "horizontal" + case ListOfStringsLayout.vertical: + orientation = "vertical" + case _: + assert_never(to_convert.layout) + + converted_kwargs: dict[str, Any] = { + "valuespec": template, + "title": _localize_optional(to_convert.title, localizer), + "help": _localize_optional(to_convert.help_text, localizer), + "orientation": orientation, + "default_value": to_convert.prefill.value, + **_get_allow_empty_conf(to_convert, localizer), + } + + if to_convert.custom_validate is not None: + converted_kwargs["validate"] = _convert_to_legacy_validation( + to_convert.custom_validate, localizer + ) + + return legacy_valuespecs.ListOfStrings(**converted_kwargs) + + def _convert_to_legacy_fixed_value( to_convert: ruleset_api_v1.form_specs.FixedValue, localizer: Callable[[str], str] ) -> legacy_valuespecs.FixedValue: @@ -2093,7 +2231,7 @@ def _convert_to_legacy_metric_name( def _convert_to_legacy_monitored_host_name( - to_convert: ruleset_api_v1.form_specs.MonitoredHost, + to_convert: ruleset_api_v1.form_specs.MonitoredHost | MonitoredHostExtended, localizer: Callable[[str], str], ) -> legacy_valuespecs.MonitoredHostname: converted_kwargs: dict[str, Any] = { @@ -2111,6 +2249,8 @@ def _convert_to_legacy_monitored_host_name( if (title := _localize_optional(to_convert.title, localizer)) is None: title = ruleset_api_v1.Title("Host name").localize(localizer) converted_kwargs["title"] = title + if isinstance(to_convert, MonitoredHostExtended): + converted_kwargs["default_value"] = to_convert.prefill.value return legacy_valuespecs.MonitoredHostname(**converted_kwargs) diff --git a/cmk/gui/utils/script_helpers.py b/cmk/gui/utils/script_helpers.py index ef1cc0228af..8416b02658e 100644 --- a/cmk/gui/utils/script_helpers.py +++ b/cmk/gui/utils/script_helpers.py @@ -17,6 +17,10 @@ from flask.ctx import RequestContext from werkzeug.test import create_environ +from cmk.ccc.version import edition + +from cmk.utils import paths + from cmk.gui.http import Response Environments = typing.Literal["production", "testing", "development"] @@ -27,7 +31,8 @@ def session_wsgi_app(debug: bool = False, testing: bool = False) -> Flask: # TODO: Temporary hack. Can be removed once #12954 has been ported from 2.0.0 from cmk.gui.wsgi.app import make_wsgi_app - return make_wsgi_app(debug=debug, testing=testing) + # For now always use the detected edition. At some point make this parameterized + return make_wsgi_app(edition(paths.omd_root), debug=debug, testing=testing) def make_request_context(app: Flask, environ: dict[str, Any] | None = None) -> RequestContext: diff --git a/cmk/gui/view_renderer.py b/cmk/gui/view_renderer.py index a40911099b5..eefcab05eb9 100644 --- a/cmk/gui/view_renderer.py +++ b/cmk/gui/view_renderer.py @@ -93,13 +93,15 @@ def render( class GUIViewRenderer(ABCViewRenderer): - page_menu_dropdowns_hook: Callable[[View, Rows, list[PageMenuDropdown]], None] = ( - lambda v, r, p: None - ) - - def __init__(self, view: View, show_buttons: bool) -> None: + def __init__( + self, + view: View, + show_buttons: bool, + page_menu_dropdowns_callback: Callable[[View, Rows, list[PageMenuDropdown]], None], + ) -> None: super().__init__(view) self._show_buttons = show_buttons + self._page_menu_dropdowns_callback = page_menu_dropdowns_callback def render( # pylint: disable=too-many-branches self, @@ -352,7 +354,7 @@ def _page_menu(self, rows: Rows, show_filters: list[Filter]) -> PageMenu: + export_dropdown ) - GUIViewRenderer.page_menu_dropdowns_hook(self.view, rows, page_menu_dropdowns) + self._page_menu_dropdowns_callback(self.view, rows, page_menu_dropdowns) menu = PageMenu( dropdowns=page_menu_dropdowns, @@ -400,7 +402,7 @@ def _page_menu_entries_selected_objects(self) -> Iterator[PageMenuEntry]: for _group_class, commands in sorted(by_group.items(), key=lambda x: x[0]().sort_index): for command in commands: yield PageMenuEntry( - title=command.title, + title=str(command.title), icon_name=command.icon_name, item=( PageMenuPopup(self._render_command_form(info_name, command)) diff --git a/cmk/gui/views/command/base.py b/cmk/gui/views/command/base.py index 21e133c4d55..a655ee57064 100644 --- a/cmk/gui/views/command/base.py +++ b/cmk/gui/views/command/base.py @@ -17,9 +17,8 @@ from cmk.gui.type_defs import Row, Rows from cmk.gui.utils.html import HTML from cmk.gui.utils.speaklater import LazyString -from cmk.gui.utils.time import timezone_utc_offset_str -from .group import command_group_registry, CommandGroup +from .group import CommandGroup CommandSpecWithoutSite = str CommandSpecWithSite = tuple[SiteId | None, CommandSpecWithoutSite] @@ -45,88 +44,87 @@ class CommandConfirmDialogOptions: class Command(abc.ABC): - @property - @abc.abstractmethod - def ident(self) -> str: - """The identity of a command. One word, may contain alpha numeric characters""" - raise NotImplementedError() - - @property - @abc.abstractmethod - def title(self) -> str: - raise NotImplementedError() + def __init__( + self, + ident: str, + title: LazyString, + permission: Permission, + tables: Sequence[str], + render: Callable[[str], None], + action: Callable[ + ["Command", Literal["HOST", "SVC"], str, Row, int, Rows], CommandActionResult + ], + group: type[CommandGroup], + confirm_button: LazyString | Callable[[], LazyString], + confirm_title: LazyString | Callable[[], LazyString] | None = None, + confirm_dialog_additions: Callable[[Literal["HOST", "SVC"], Row, Rows], HTML] | None = None, + confirm_dialog_icon_class: Callable[[], Literal["question", "warning"]] | None = None, + cancel_button: LazyString = _l("Cancel"), + deny_button: LazyString | None = None, + deny_js_function: str | None = None, + affected_output_cb: Callable[[int, Literal["HOST", "SVC"]], HTML] | None = None, + icon_name: str = "commands", + is_show_more: bool = False, + is_shortcut: bool = False, + is_suggested: bool = False, + only_view: str | None = None, + show_command_form: bool = True, + executor: CommandExecutor | None = None, + ) -> None: + self.ident = ident + self.title = title + self.confirm_button = confirm_button + self._confirm_title = confirm_title + self.cancel_button = cancel_button + self.deny_button = deny_button + self.deny_js_function = deny_js_function + self.permission = permission + self.tables = tables + self.render = render + self._action = action + self.group = group + self.only_view = only_view + self.icon_name = icon_name + self.is_show_more = is_show_more + self.is_shortcut = is_shortcut + self.is_suggested = is_suggested + self.show_command_form = show_command_form + self._confirm_dialog_additions = confirm_dialog_additions + self._confirm_dialog_icon_class = confirm_dialog_icon_class + self._affected_output_cb = affected_output_cb + self._executor = executor @property def confirm_title(self) -> str: - return ("%s %s?") % (self.confirm_button, self.title.lower()) - - @property - @abc.abstractmethod - def confirm_button(self) -> LazyString: - raise NotImplementedError() - - @property - def cancel_button(self) -> LazyString: - return _l("Cancel") - - @property - def deny_button(self) -> LazyString | None: - return None - - @property - def deny_js_function(self) -> str | None: - return None - - @property - @abc.abstractmethod - def permission(self) -> Permission: - raise NotImplementedError() - - @property - @abc.abstractmethod - def tables(self) -> list[str]: - """List of livestatus table identities the action may be used with""" - raise NotImplementedError() - - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - return HTML.empty() - - def confirm_dialog_icon_class(self) -> Literal["question", "warning"]: - return "question" + if self._confirm_title: + return str(self._confirm_title) + return ("%s %s?") % (self.confirm_button, str(self.title).lower()) def confirm_dialog_options( - self, cmdtag: Literal["HOST", "SVC"], row: Row, len_action_rows: int + self, cmdtag: Literal["HOST", "SVC"], row: Row, action_rows: Rows ) -> CommandConfirmDialogOptions: return CommandConfirmDialogOptions( self.confirm_title, - self.affected(len_action_rows, cmdtag), - self.confirm_dialog_additions(cmdtag, row, len_action_rows), - self.confirm_dialog_icon_class(), - self.confirm_button, + self.affected(len(action_rows), cmdtag), + ( + self._confirm_dialog_additions(cmdtag, row, action_rows) + if self._confirm_dialog_additions + else HTML.empty() + ), + ( + self._confirm_dialog_icon_class() + if callable(self._confirm_dialog_icon_class) + else "question" + ), + self.confirm_button() if callable(self.confirm_button) else self.confirm_button, self.cancel_button, self.deny_button, self.deny_js_function, ) - def confirm_dialog_date_and_time_format( - self, timestamp: float, show_timezone: bool = True - ) -> str: - """Return date, time and if show_timezone is True the local timezone in the format of e.g. - 'Mon, 01. January 2042 at 01:23 [UTC+01:00]'""" - local_time = time.localtime(timestamp) - return ( - time.strftime(_("%a, %d. %B %Y at %H:%M"), local_time) - + (" " + timezone_utc_offset_str(timestamp)) - if show_timezone - else "" - ) - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: + if self._affected_output_cb: + return self._affected_output_cb(len_action_rows, cmdtag) return HTML.with_escaping( _("Affected %s: %s") % ( @@ -152,57 +150,21 @@ def user_confirm_options( ) -> list[tuple[str, str]]: return [(_("Confirm"), "_do_confirm")] - def render(self, what: str) -> None: - raise NotImplementedError() - def action( self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows ) -> CommandActionResult: - result = self._action(cmdtag, spec, row, row_index, action_rows) + result = self._action(self, cmdtag, spec, row, row_index, action_rows) if result: commands, confirm_dialog_options = result return commands, confirm_dialog_options return None - @abc.abstractmethod - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - raise NotImplementedError() - - @property - def group(self) -> type[CommandGroup]: - """The command group the commmand belongs to""" - return command_group_registry["various"] - - @property - def only_view(self) -> str | None: - """View name to show a view exclusive command for""" - return None - - @property - def icon_name(self) -> str: - return "commands" - - @property - def is_show_more(self) -> bool: - return False - - @property - def is_shortcut(self) -> bool: - return False - - @property - def is_suggested(self) -> bool: - return False - - @property - def show_command_form(self) -> bool: - return True - def executor(self, command: CommandSpec, site: SiteId | None) -> None: """Function that is called to execute this action""" # We only get CommandSpecWithoutSite here. Can be cleaned up once we have a dedicated # object type for the command assert isinstance(command, str) + if self._executor: + self._executor(command, site) + return sites.live().command("[%d] %s" % (int(time.time()), command), site) diff --git a/cmk/gui/views/command/commands.py b/cmk/gui/views/command/commands.py index a7bdfb444d5..a739cee287b 100644 --- a/cmk/gui/views/command/commands.py +++ b/cmk/gui/views/command/commands.py @@ -35,7 +35,6 @@ from cmk.gui.type_defs import Choices, Row, Rows from cmk.gui.utils import escaping from cmk.gui.utils.html import HTML -from cmk.gui.utils.speaklater import LazyString from cmk.gui.utils.time import timezone_utc_offset_str from cmk.gui.utils.urls import makeuri, makeuri_contextless from cmk.gui.valuespec import AbsoluteDate, Age, Checkbox, DatePicker, Dictionary, TimePicker @@ -69,8 +68,13 @@ def register( command_registry.register(CommandAcknowledge) command_registry.register(CommandRemoveAcknowledgments) command_registry.register(CommandAddComment) - command_registry.register(CommandScheduleDowntimes) - command_registry.register(CommandRemoveDowntime) + command_registry.register( + CommandScheduleDowntimes( + recurring_downtimes=NoRecurringDowntimes(), + ) + ) + command_registry.register(CommandRemoveDowntimesHostServicesTable) + command_registry.register(CommandRemoveDowntimesDowntimesTable) command_registry.register(CommandRemoveComments) permission_section_registry.register(PermissionSectionAction) permission_registry.register(PermissionActionReschedule) @@ -131,89 +135,79 @@ def do_sort(self): ) -class CommandReschedule(Command): - @property - def ident(self) -> str: - return "reschedule" - - @property - def title(self) -> str: - return _("Reschedule active checks") - - @property - def confirm_title(self) -> str: - return _("Reschedule active checks immediately?") - - @property - def confirm_button(self) -> LazyString: - return _l("Reschedule") - - @property - def icon_name(self): - return "service_duration" - - @property - def permission(self) -> Permission: - return PermissionActionReschedule - - @property - def tables(self) -> list[str]: - return ["host", "service"] +def command_reschedule_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + return ( + HTMLWriter.render_br() + + HTMLWriter.render_br() + + "Spreading: %s minutes" % request.var("_resched_spread") + ) - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - return ( - HTMLWriter.render_br() - + HTMLWriter.render_br() - + "Spreading: %s minutes" % request.var("_resched_spread") - ) - def render(self, what: str) -> None: - html.open_div(class_="group") - html.write_text_permissive(_("Spread over") + " ") - html.text_input( - "_resched_spread", default_value="5", size=3, cssclass="number", required=True +def command_reschedule_render(what: str) -> None: + html.open_div(class_="group") + html.write_text_permissive(_("Spread over") + " ") + html.text_input("_resched_spread", default_value="5", size=3, cssclass="number", required=True) + html.write_text_permissive(" " + _("minutes")) + html.help( + _( + "Spreading distributes checks evenly over the specified period. " + "This helps to avoid short-term peaks in CPU usage and " + "therefore, performance problems." ) - html.write_text_permissive(" " + _("minutes")) - html.help( - _( - "Spreading distributes checks evenly over the specified period. " - "This helps to avoid short-term peaks in CPU usage and " - "therefore, performance problems." + ) + html.close_div() + + html.open_div(class_="group") + html.button("_resched_checks", _("Reschedule"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_reschedule_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_resched_checks"): + spread = request.get_validated_type_input_mandatory(int, "_resched_spread") + if spread < 0: + raise MKUserError( + "_resched_spread", _("Spread should be a positive number: %s") % spread ) - ) - html.close_div() - html.open_div(class_="group") - html.button("_resched_checks", _("Reschedule"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() + t = time.time() + if spread: + t += spread * 60.0 * row_index / len(action_rows) - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_resched_checks"): - spread = request.get_validated_type_input_mandatory(int, "_resched_spread") - if spread < 0: - raise MKUserError( - "_resched_spread", _("Spread should be a positive number: %s") % spread - ) + cmd = "SCHEDULE_FORCED_" + cmdtag + "_CHECK;%s;%d" % (spec, int(t)) + return cmd, command.confirm_dialog_options( + cmdtag, + row, + action_rows, + ) + return None - t = time.time() - if spread: - t += spread * 60.0 * row_index / len(action_rows) - command = "SCHEDULE_FORCED_" + cmdtag + "_CHECK;%s;%d" % (spec, int(t)) - return command, self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ) - return None +CommandReschedule = Command( + ident="reschedule", + title=_l("Reschedule active checks"), + confirm_title=_l("Reschedule active checks immediately?"), + confirm_button=_l("Reschedule"), + permission=PermissionActionReschedule, + group=CommandGroupVarious, + tables=["host", "service"], + icon_name="service_duration", + render=command_reschedule_render, + action=command_reschedule_action, + confirm_dialog_additions=command_reschedule_confirm_dialog_additions, +) # . @@ -241,86 +235,74 @@ def _action( ) -class CommandNotifications(Command): - @property - def ident(self) -> str: - return "notifications" - - @property - def title(self) -> str: - return _("Enable/disable notifications") - - @property - def confirm_title(self) -> str: - return ( - _("Enable notifications?") +def command_notifications_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + return ( + HTMLWriter.render_br() + + HTMLWriter.render_br() + + ( + _("Notifications will be sent according to the notification rules") if request.var("_enable_notifications") - else _("Disable notifications?") + else _("This will suppress all notifications") ) + ) - @property - def confirm_button(self) -> LazyString: - return _l("Enable") if request.var("_enable_notifications") else _l("Disable") - @property - def permission(self) -> Permission: - return PermissionActionNotifications +def command_notifications_confirm_dialog_icon_class() -> Literal["question", "warning"]: + if request.var("_enable_notifications"): + return "question" + return "warning" - @property - def tables(self) -> list[str]: - return ["host", "service"] - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - return ( - HTMLWriter.render_br() - + HTMLWriter.render_br() - + ( - _("Notifications will be sent according to the notification rules") - if request.var("_enable_notifications") - else _("This will suppress all notifications") - ) - ) +def command_notifications_render(what: str) -> None: + html.open_div(class_="group") + html.button("_enable_notifications", _("Enable"), cssclass="border_hot") + html.button("_disable_notifications", _("Disable"), cssclass="border_hot") + html.button("_cancel", _("Cancel")) + html.close_div() - def confirm_dialog_icon_class(self) -> Literal["question", "warning"]: - if request.var("_enable_notifications"): - return "question" - return "warning" - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_enable_notifications", _("Enable"), cssclass="border_hot") - html.button("_disable_notifications", _("Disable"), cssclass="border_hot") - html.button("_cancel", _("Cancel")) - html.close_div() +def command_notifications_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_enable_notifications"): + return ( + "ENABLE_" + cmdtag + "_NOTIFICATIONS;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + if request.var("_disable_notifications"): + return ( + "DISABLE_" + cmdtag + "_NOTIFICATIONS;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + return None - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_enable_notifications"): - return ( - "ENABLE_" + cmdtag + "_NOTIFICATIONS;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - if request.var("_disable_notifications"): - return ( - "DISABLE_" + cmdtag + "_NOTIFICATIONS;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - return None +CommandNotifications = Command( + ident="notifications", + title=_l("Enable/disable notifications"), + confirm_title=lambda: ( + _l("Enable notifications?") + if request.var("_enable_notifications") + else _l("Disable notifications?") + ), + confirm_button=lambda: _l("Enable") if request.var("_enable_notifications") else _l("Disable"), + permission=PermissionActionNotifications, + tables=["host", "service"], + group=CommandGroupVarious, + confirm_dialog_additions=command_notifications_confirm_dialog_additions, + confirm_dialog_icon_class=command_notifications_confirm_dialog_icon_class, + render=command_notifications_render, + action=command_notifications_action, +) # . # .--Enable/Disable Active Checks----------------------------------------. @@ -347,68 +329,49 @@ def _action( ) -class CommandToggleActiveChecks(Command): - @property - def ident(self) -> str: - return "toggle_active_checks" +def command_toggle_active_checks_render(what: str) -> None: + html.open_div(class_="group") + html.button("_enable_checks", _("Enable"), cssclass="border_hot") + html.button("_disable_checks", _("Disable"), cssclass="border_hot") + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def title(self) -> str: - return _("Enable/Disable active checks") - @property - def confirm_title(self) -> str: +def command_toggle_active_checks_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_enable_checks"): return ( - _("Enable active checks") - if request.var("_enable_checks") - else _("Disable active checks") + "ENABLE_" + cmdtag + "_CHECK;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), ) + if request.var("_disable_checks"): + return ( + "DISABLE_" + cmdtag + "_CHECK;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + return None - @property - def confirm_button(self) -> LazyString: - return _l("Enable") if request.var("_enable_checks") else _l("Disable") - - @property - def permission(self) -> Permission: - return PermissionActionEnableChecks - - @property - def tables(self) -> list[str]: - return ["host", "service"] - - def confirm_dialog_icon_class(self) -> Literal["question", "warning"]: - return "warning" - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_enable_checks", _("Enable"), cssclass="border_hot") - html.button("_disable_checks", _("Disable"), cssclass="border_hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_enable_checks"): - return ( - "ENABLE_" + cmdtag + "_CHECK;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - if request.var("_disable_checks"): - return ( - "DISABLE_" + cmdtag + "_CHECK;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - return None +CommandToggleActiveChecks = Command( + ident="toggle_active_checks", + title=_l("Enable/Disable active checks"), + confirm_title=lambda: ( + _l("Enable active checks") if request.var("_enable_checks") else _l("Disable active checks") + ), + confirm_button=lambda: _l("Enable") if request.var("_enable_checks") else _l("Disable"), + permission=PermissionActionEnableChecks, + group=CommandGroupVarious, + tables=["host", "service"], + confirm_dialog_icon_class=lambda: "warning", + render=command_toggle_active_checks_render, + action=command_toggle_active_checks_action, +) # . # .--Enable/Disable Passive Checks---------------------------------------. @@ -427,68 +390,51 @@ def _action( # '----------------------------------------------------------------------' -class CommandTogglePassiveChecks(Command): - @property - def ident(self) -> str: - return "toggle_passive_checks" +def command_toggle_passive_checks_render(what: str) -> None: + html.open_div(class_="group") + html.button("_enable_passive_checks", _("Enable"), cssclass="border_hot") + html.button("_disable_passive_checks", _("Disable"), cssclass="border_hot") + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def title(self) -> str: - return _("Enable/Disable passive checks") - @property - def confirm_title(self) -> str: +def command_toggle_passive_checks_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_enable_passive_checks"): return ( - _("Enable passive checks") - if request.var("_enable_passive_checks") - else _("Disable passive checks") + "ENABLE_PASSIVE_" + cmdtag + "_CHECKS;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), ) + if request.var("_disable_passive_checks"): + return ( + "DISABLE_PASSIVE_" + cmdtag + "_CHECKS;%s" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), + ) + return None - @property - def confirm_button(self) -> LazyString: - return _l("Enable") if request.var("_enable_passive_checks") else _l("Disable") - - @property - def permission(self) -> Permission: - return PermissionActionEnableChecks - - @property - def tables(self) -> list[str]: - return ["host", "service"] - - def confirm_dialog_icon_class(self) -> Literal["question", "warning"]: - return "warning" - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_enable_passive_checks", _("Enable"), cssclass="border_hot") - html.button("_disable_passive_checks", _("Disable"), cssclass="border_hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_enable_passive_checks"): - return ( - "ENABLE_PASSIVE_" + cmdtag + "_CHECKS;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - if request.var("_disable_passive_checks"): - return ( - "DISABLE_PASSIVE_" + cmdtag + "_CHECKS;%s" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - return None +CommandTogglePassiveChecks = Command( + ident="toggle_passive_checks", + title=_l("Enable/Disable passive checks"), + confirm_title=lambda: ( + _l("Enable passive checks") + if request.var("_enable_passive_checks") + else _l("Disable passive checks") + ), + confirm_button=lambda: _l("Enable") if request.var("_enable_passive_checks") else _l("Disable"), + permission=PermissionActionEnableChecks, + group=CommandGroupVarious, + tables=["host", "service"], + confirm_dialog_icon_class=lambda: "warning", + render=command_toggle_passive_checks_render, + action=command_toggle_passive_checks_action, +) # . # .--Clear Modified Attributes-------------------------------------------. @@ -518,64 +464,57 @@ def _action( ) -class CommandClearModifiedAttributes(Command): - @property - def ident(self) -> str: - return "clear_modified_attributes" - - @property - def title(self) -> str: - return _("Reset modified attributes") - - @property - def confirm_button(self) -> LazyString: - return _l("Reset") - - @property - def permission(self) -> Permission: - return PermissionActionClearModifiedAttributes - - @property - def tables(self) -> list[str]: - return ["host", "service"] +def command_clear_modified_attributes_render(what: str) -> None: + html.open_div(class_="group") + html.button("_clear_modattr", _("Reset attributes"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_clear_modified_attributes_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + return ( + HTMLWriter.render_br() + + HTMLWriter.render_br() + + _("Resets the commands '%s', '%s' and '%s' to the default state") + % ( + CommandToggleActiveChecks.title, + CommandTogglePassiveChecks.title, + CommandNotifications.title, + ) + ) - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_clear_modattr", _("Reset attributes"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: +def command_clear_modified_attributes_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_clear_modattr"): return ( - HTMLWriter.render_br() - + HTMLWriter.render_br() - + _("Resets the commands '%s', '%s' and '%s' to the default state") - % ( - CommandToggleActiveChecks().title, - CommandTogglePassiveChecks().title, - CommandNotifications().title, - ) + "CHANGE_" + cmdtag + "_MODATTR;%s;0" % spec, + command.confirm_dialog_options(cmdtag, row, action_rows), ) + return None - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_clear_modattr"): - return ( - "CHANGE_" + cmdtag + "_MODATTR;%s;0" % spec, - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - return None +CommandClearModifiedAttributes = Command( + ident="clear_modified_attributes", + title=_l("Reset modified attributes"), + confirm_button=_l("Reset"), + permission=PermissionActionClearModifiedAttributes, + group=CommandGroupVarious, + tables=["host", "service"], + render=command_clear_modified_attributes_render, + action=command_clear_modified_attributes_action, + confirm_dialog_additions=command_clear_modified_attributes_confirm_dialog_additions, +) # . # .--Fake Checks---------------------------------------------------------. @@ -610,155 +549,139 @@ def sort_index(self) -> int: return 15 -class CommandFakeCheckResult(Command): - @property - def ident(self) -> str: - return "fake_check_result" - - @property - def title(self) -> str: - return _("Fake check results") - - @property - def confirm_title(self) -> str: - return _("Set fake check result to ‘%s’?") % self._get_target_state() - - def _get_target_state(self) -> str: - state = request.var("_state") - statename = request.var(f"_state_{state}") - - return "" if statename is None else statename +def _get_target_state() -> str: + state = request.var("_state") + statename = request.var(f"_state_{state}") + + return "" if statename is None else statename + + +def command_fake_check_result_render(what: str) -> None: + _render_test_notification_tip() + + html.open_div(class_="group") + html.open_table(class_=["fake_check_result"]) + + html.open_tr() + html.open_td() + html.write_text_permissive(_("Result") + "   ") + html.close_td() + html.open_td() + html.open_span(class_="inline_radio_group") + for value, description in _get_states(what): + html.radiobutton("_state", str(value), value == 0, description) + html.hidden_field(f"_state_{value}", description) + html.close_span() + html.close_td() + html.close_tr() + + html.open_tr() + html.open_td() + html.write_text_permissive(_("Plug-in output") + "   ") + html.close_td() + html.open_td() + html.text_input("_fake_output", "", size=60, placeholder=_("What is the purpose?")) + html.close_td() + html.close_tr() + + html.open_tr() + html.open_td() + html.write_text_permissive(_("Performance data") + "   ") + html.close_td() + html.open_td() + html.text_input( + "_fake_perfdata", + "", + size=60, + placeholder=_("Enter performance data to show in notifications etc. ..."), + ) + html.close_td() + html.close_tr() - @property - def confirm_button(self) -> LazyString: - return _l("Set to '%s'") % self._get_target_state() + html.close_table() + html.close_div() - @property - def icon_name(self): - return "fake_check_result" + html.open_div(class_="group") + html.button("_fake_check_result", _("Fake check result"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() - @property - def permission(self) -> Permission: - return PermissionActionFakeChecks - @property - def tables(self) -> list[str]: - return ["host", "service"] +def _link_to_test_notifications() -> HTML: + return html.render_a( + _("Test notification"), + makeuri_contextless(request, [("mode", "test_notifications")], filename="wato.py"), + ) - @property - def group(self) -> type[CommandGroup]: - return CommandGroupFakeCheck - @property - def is_show_more(self) -> bool: - return True - - def _link_to_test_notifications(self): - return html.render_a( - _("Test notification"), - makeuri_contextless(request, [("mode", "test_notifications")], filename="wato.py"), +def _render_test_notification_tip() -> None: + html.open_div(class_="info") + html.icon("toggle_details") + html.write_text_permissive( + "   " + + _( + "If you are looking for a way to test your notification settings, try '%s' in Setup > Test notifications" ) + % _link_to_test_notifications() + ) + html.close_div() - def _render_test_notification_tip(self): - html.open_div(class_="info") - html.icon("toggle_details") - html.write_text_permissive( - "   " - + _( - "If you are looking for a way to test your notification settings, try '%s' in Setup > Test notifications" - ) - % self._link_to_test_notifications() - ) - html.close_div() - def _get_states(self, what): - if what == "host": - return [(0, _("Up")), (1, _("Down"))] +def _get_states(what: str) -> list[tuple[int, str]]: + if what == "host": + return [(0, _("Up")), (1, _("Down"))] - return [(0, _("OK")), (1, _("Warning")), (2, _("Critical")), (3, _("Unknown"))] + return [(0, _("OK")), (1, _("Warning")), (2, _("Critical")), (3, _("Unknown"))] - def render(self, what: str) -> None: - self._render_test_notification_tip() - html.open_div(class_="group") - html.open_table(class_=["fake_check_result"]) +def command_fake_check_result_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_fake_check_result"): + state = request.var("_state") + statename = request.var(f"_state_{state}") + pluginoutput = request.get_str_input_mandatory("_fake_output").strip() - html.open_tr() - html.open_td() - html.write_text_permissive(_("Result") + "   ") - html.close_td() - html.open_td() - html.open_span(class_="inline_radio_group") - for value, description in self._get_states(what): - html.radiobutton("_state", value, value == 0, description) - html.hidden_field(f"_state_{value}", description) - html.close_span() - html.close_td() - html.close_tr() + if not pluginoutput: + pluginoutput = _("Manually set to %s by %s") % ( + escaping.escape_attribute(statename), + user.id, + ) - html.open_tr() - html.open_td() - html.write_text_permissive(_("Plug-in output") + "   ") - html.close_td() - html.open_td() - html.text_input("_fake_output", "", size=60, placeholder=_("What is the purpose?")) - html.close_td() - html.close_tr() + perfdata = request.var("_fake_perfdata") + if perfdata: + pluginoutput += "|" + perfdata - html.open_tr() - html.open_td() - html.write_text_permissive(_("Performance data") + "   ") - html.close_td() - html.open_td() - html.text_input( - "_fake_perfdata", - "", - size=60, - placeholder=_("Enter performance data to show in notifications etc. ..."), + cmd = "PROCESS_{}_CHECK_RESULT;{};{};{}".format( + "SERVICE" if cmdtag == "SVC" else cmdtag, + spec, + state, + livestatus.lqencode(pluginoutput), ) - html.close_td() - html.close_tr() - - html.close_table() - html.close_div() - - html.open_div(class_="group") - html.button("_fake_check_result", _("Fake check result"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_fake_check_result"): - state = request.var("_state") - statename = request.var(f"_state_{state}") - pluginoutput = request.get_str_input_mandatory("_fake_output").strip() - - if not pluginoutput: - pluginoutput = _("Manually set to %s by %s") % ( - escaping.escape_attribute(statename), - user.id, - ) - perfdata = request.var("_fake_perfdata") - if perfdata: - pluginoutput += "|" + perfdata + return cmd, command.confirm_dialog_options(cmdtag, row, action_rows) - command = "PROCESS_{}_CHECK_RESULT;{};{};{}".format( - "SERVICE" if cmdtag == "SVC" else cmdtag, - spec, - state, - livestatus.lqencode(pluginoutput), - ) + return None - return command, self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ) - return None +CommandFakeCheckResult = Command( + ident="fake_check_result", + title=_l("Fake check results"), + confirm_title=lambda: _l("Set fake check result to ‘%s’?") % _get_target_state(), + confirm_button=lambda: _l("Set to '%s'") % _get_target_state(), + permission=PermissionActionFakeChecks, + tables=["host", "service"], + group=CommandGroupFakeCheck, + icon_name="fake_check_result", + is_show_more=True, + render=command_fake_check_result_render, + action=command_fake_check_result_action, +) # . @@ -789,94 +712,77 @@ def _action( ) -class CommandCustomNotification(Command): - @property - def ident(self) -> str: - return "send_custom_notification" - - @property - def title(self) -> str: - return _("Send custom notification") - - @property - def confirm_title(self) -> str: - return "%s?" % self.title - - @property - def confirm_button(self) -> LazyString: - return _l("Send") - - @property - def icon_name(self): - return "notifications" - - @property - def permission(self) -> Permission: - return PermissionActionCustomNotification - - @property - def tables(self) -> list[str]: - return ["host", "service"] - - @property - def is_show_more(self) -> bool: - return True - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.text_input( - "_cusnot_comment", - id_="cusnot_comment", - size=60, - submit="_customnotification", - label=_("Comment"), - placeholder=_("Enter your message here"), - ) - html.close_div() - - html.open_div(class_="group") - html.checkbox( - "_cusnot_forced", - False, - label=_( - "Send regardless of restrictions, e.g. notification period or disabled notifications (forced)" - ), - ) - html.close_div() - html.open_div(class_="group") - html.checkbox( - "_cusnot_broadcast", - False, - label=_("Send to all contacts of the selected hosts/services (broadcast)"), +def command_custom_notification_render(what: str) -> None: + html.open_div(class_="group") + html.text_input( + "_cusnot_comment", + id_="cusnot_comment", + size=60, + submit="_customnotification", + label=_("Comment"), + placeholder=_("Enter your message here"), + ) + html.close_div() + + html.open_div(class_="group") + html.checkbox( + "_cusnot_forced", + False, + label=_( + "Send regardless of restrictions, e.g. notification period or disabled notifications (forced)" + ), + ) + html.close_div() + html.open_div(class_="group") + html.checkbox( + "_cusnot_broadcast", + False, + label=_("Send to all contacts of the selected hosts/services (broadcast)"), + ) + html.close_div() + + html.open_div(class_="group") + html.button("_customnotification", _("Send"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_custom_notification_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_customnotification"): + comment = request.get_str_input_mandatory("_cusnot_comment") + broadcast = 1 if html.get_checkbox("_cusnot_broadcast") else 0 + forced = 2 if html.get_checkbox("_cusnot_forced") else 0 + cmd = "SEND_CUSTOM_{}_NOTIFICATION;{};{};{};{}".format( + cmdtag, + spec, + broadcast + forced, + user.id, + livestatus.lqencode(comment), ) - html.close_div() + return cmd, command.confirm_dialog_options(cmdtag, row, action_rows) + return None - html.open_div(class_="group") - html.button("_customnotification", _("Send"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_customnotification"): - comment = request.get_str_input_mandatory("_cusnot_comment") - broadcast = 1 if html.get_checkbox("_cusnot_broadcast") else 0 - forced = 2 if html.get_checkbox("_cusnot_forced") else 0 - command = "SEND_CUSTOM_{}_NOTIFICATION;{};{};{};{}".format( - cmdtag, - spec, - broadcast + forced, - user.id, - livestatus.lqencode(comment), - ) - return command, self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ) - return None +CommandCustomNotification = Command( + ident="send_custom_notification", + title=_l("Send custom notification"), + confirm_title=_l("Send custom notification?"), + confirm_button=_l("Send"), + icon_name="notifications", + permission=PermissionActionCustomNotification, + group=CommandGroupVarious, + tables=["host", "service"], + is_show_more=True, + render=command_custom_notification_render, + action=command_custom_notification_action, +) # . # .--Acknowledge---------------------------------------------------------. @@ -911,392 +817,357 @@ def sort_index(self) -> int: return 5 -class CommandAcknowledge(Command): - @property - def ident(self) -> str: - return "acknowledge" - - @property - def title(self) -> str: - return _("Acknowledge problems") - - @property - def confirm_title(self) -> str: - return _("Acknowledge problems?") - - @property - def confirm_button(self) -> LazyString: - return _l("Yes, acknowledge") - - @property - def cancel_button(self) -> LazyString: - return _l("No, discard") - - @property - def deny_button(self) -> LazyString | None: - return _l("No, adjust settings") - - @property - def deny_js_function(self) -> str | None: - return '() => cmk.page_menu.toggle_popup("popup_command_acknowledge")' - - @property - def icon_name(self): - return "ack" - - @property - def is_shortcut(self) -> bool: - return True - - @property - def is_suggested(self) -> bool: - return True - - @property - def permission(self) -> Permission: - return PermissionActionAcknowledge - - @property - def group(self) -> type[CommandGroup]: - return CommandGroupAcknowledge - - @property - def tables(self) -> list[str]: - return ["host", "service", "aggr"] - - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - if request.var("_ack_expire"): - date = request.get_str_input("_ack_expire_date") - time_ = request.get_str_input("_ack_expire_time") - timestamp = time.mktime(time.strptime(f"{date} {time_}", "%Y-%m-%d %H:%M")) - formatted_datetime_str = self.confirm_dialog_date_and_time_format(timestamp) - - expire_conditions_li = html.render_li( - _("On recovery (OK/UP)") - if request.var("_ack_sticky") - else _("If state changes OR on recovery (OK/UP)") - ) - expire_time_li = html.render_li( - _("On %s (server time).") % formatted_datetime_str - if request.var("_ack_expire") - else _("No expiration date") - ) - persistent_comment_div = html.render_div( - ( - _("Comment will be kept after acknowledgment expires.") - if request.var("_ack_persistent") - else _("Comment will be removed after acknowledgment expires.") - ), - class_="confirm_block", - ) - - return html.render_div( - content=html.render_div(_("Acknowledgment expires:"), class_="confirm_block") - + expire_conditions_li - + expire_time_li - + persistent_comment_div, - class_="confirm_block", - ) - - def render(self, what: str) -> None: - submit_id = "_acknowledge" - html.open_div(class_="group") - html.text_input( - "_ack_comment", - id_="ack_comment", - size=60, - submit=submit_id, - label=_("Comment"), - required=True, - placeholder=_("e.g. ticket ID"), - oninput=f"cmk.forms.enable_submit_buttons_on_nonempty_input(this, ['{submit_id}']);", - ) - if request.get_str_input("_ack_comment"): - html.final_javascript( - f"cmk.forms.enable_submit_buttons_on_nonempty_input(document.getElementById('ack_comment'), ['{submit_id}']);" - ) - - html.close_div() - - html.open_div(class_="group ack_command_options") - html.heading(_("Options")) - if user.may("wato.global"): - html.open_span() - html.write_text_permissive("(") - html.a(_("Edit defaults"), self._action_defaults_url()) - html.write_text_permissive(")") - html.close_span() - - date, time_ = self._expiration_date_and_time( - active_config.acknowledge_problems.get("ack_expire", 3600) - ) - is_raw_edition: bool = cmk_version.edition(paths.omd_root) is cmk_version.Edition.CRE - html.open_div(class_="disabled" if is_raw_edition else "") - html.checkbox( - "_ack_expire", - False, - label=_("Expire on"), - onclick="cmk.page_menu.ack_problems_update_expiration_active_state(this);", - ) - html.open_div(class_="date_time_picker") - self._vs_date().render_input("_ack_expire_date", date) - self._vs_time().render_input("_ack_expire_time", time_) - html.close_div() - - html.span( - timezone_utc_offset_str() - + " " - + _("Server time (currently: %s)") - % time.strftime("%m/%d/%Y %H:%M", time.localtime(time.time())), - class_="server_time", - ) - if is_raw_edition: - render_cre_upgrade_button() - html.help( - _("Note: Expiration of acknowledgements only works when using the Checkmk Micro Core.") - ) - html.close_div() +def command_acknowledge_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + if request.var("_ack_expire"): + date = request.get_str_input("_ack_expire_date") + time_ = request.get_str_input("_ack_expire_time") + timestamp = time.mktime(time.strptime(f"{date} {time_}", "%Y-%m-%d %H:%M")) + formatted_datetime_str = _confirm_dialog_date_and_time_format(timestamp) + + expire_conditions_li = html.render_li( + _("On recovery (OK/UP)") + if request.var("_ack_sticky") + else _("If state changes OR on recovery (OK/UP)") + ) + expire_time_li = html.render_li( + _("On %s (server time).") % formatted_datetime_str + if request.var("_ack_expire") + else _("No expiration date") + ) + persistent_comment_div = html.render_div( + ( + _("Comment will be kept after acknowledgment expires.") + if request.var("_ack_persistent") + else _("Comment will be removed after acknowledgment expires.") + ), + class_="confirm_block", + ) - html.open_div() - html.checkbox( - "_ack_sticky", - active_config.acknowledge_problems["ack_sticky"], - label=_("Ignore status changes until services/hosts are OK/UP again (sticky)"), - ) - html.div( - "" - + _("Example:") - + " " - + _("Service was WARN and goes CRIT - acknowledgment doesn't expire."), - class_="example", - ) - html.close_div() + return html.render_div( + content=html.render_div(_("Acknowledgment expires:"), class_="confirm_block") + + expire_conditions_li + + expire_time_li + + persistent_comment_div, + class_="confirm_block", + ) - html.div( - html.render_checkbox( - "_ack_persistent", - active_config.acknowledge_problems["ack_persistent"], - label=_("Keep comment after acknowledgment expires (persistent comment)"), - ) - ) - html.div( - html.render_checkbox( - "_ack_notify", - active_config.acknowledge_problems["ack_notify"], - label=_("Notify affected users if %s are in place (send notifications)") - % self._link_to_notification_rules(), - ) +def command_acknowledge_render(what: str) -> None: + submit_id = "_acknowledge" + html.open_div(class_="group") + html.text_input( + "_ack_comment", + id_="ack_comment", + size=60, + submit=submit_id, + label=_("Comment"), + required=True, + placeholder=_("e.g. ticket ID"), + oninput=f"cmk.forms.enable_submit_buttons_on_nonempty_input(this, ['{submit_id}']);", + ) + if request.get_str_input("_ack_comment"): + html.final_javascript( + f"cmk.forms.enable_submit_buttons_on_nonempty_input(document.getElementById('ack_comment'), ['{submit_id}']);" ) - html.close_div() - html.open_div(class_="group buttons") - tooltip_submission_disabled = _("Enter a comment to acknowledge problems") - open_submit_button_container_div(tooltip_submission_disabled) - html.button( - submit_id, - _("Acknowledge problems"), - cssclass="hot disabled", - ) - html.close_div() + html.close_div() - html.buttonlink(makeuri(request, [], delvars=["filled_in"]), _("Cancel")) - html.close_div() + html.open_div(class_="group ack_command_options") + html.heading(_("Options")) + if user.may("wato.global"): + html.open_span() + html.write_text_permissive("(") + html.a(_("Edit defaults"), _action_defaults_url()) + html.write_text_permissive(")") + html.close_span() - def _action_defaults_url(self) -> str: - return makeuri_contextless( - request, - [("mode", "edit_configvar"), ("varname", "acknowledge_problems")], - filename="wato.py", + date, time_ = _expiration_date_and_time( + active_config.acknowledge_problems.get("ack_expire", 3600) + ) + is_raw_edition: bool = cmk_version.edition(paths.omd_root) is cmk_version.Edition.CRE + html.open_div(class_="disabled" if is_raw_edition else "") + html.checkbox( + "_ack_expire", + False, + label=_("Expire on"), + onclick="cmk.page_menu.ack_problems_update_expiration_active_state(this);", + ) + html.open_div(class_="date_time_picker") + _vs_date().render_input("_ack_expire_date", date) + _vs_time().render_input("_ack_expire_time", time_) + html.close_div() + + html.span( + timezone_utc_offset_str() + + " " + + _("Server time (currently: %s)") + % time.strftime("%m/%d/%Y %H:%M", time.localtime(time.time())), + class_="server_time", + ) + if is_raw_edition: + render_cre_upgrade_button() + html.help( + _("Note: Expiration of acknowledgements only works when using the Checkmk Micro Core.") + ) + html.close_div() + + html.open_div() + html.checkbox( + "_ack_sticky", + active_config.acknowledge_problems["ack_sticky"], + label=_("Ignore status changes until services/hosts are OK/UP again (sticky)"), + ) + html.div( + "" + + _("Example:") + + " " + + _("Service was WARN and goes CRIT - acknowledgment doesn't expire."), + class_="example", + ) + html.close_div() + + html.div( + html.render_checkbox( + "_ack_persistent", + active_config.acknowledge_problems["ack_persistent"], + label=_("Keep comment after acknowledgment expires (persistent comment)"), ) + ) - def _link_to_notification_rules(self) -> HTML: - return html.render_a( - _("notification rules"), - makeuri_contextless(request, [("mode", "notifications")], filename="wato.py"), + html.div( + html.render_checkbox( + "_ack_notify", + active_config.acknowledge_problems["ack_notify"], + label=_("Notify affected users if %s are in place (send notifications)") + % _link_to_notification_rules(), ) + ) + html.close_div() + + html.open_div(class_="group buttons") + tooltip_submission_disabled = _("Enter a comment to acknowledge problems") + open_submit_button_container_div(tooltip_submission_disabled) + html.button( + submit_id, + _("Acknowledge problems"), + cssclass="hot disabled", + ) + html.close_div() - def _expiration_date_and_time(self, time_until_exp: int) -> tuple[str, str]: - exp_time = time.localtime(time.time() + time_until_exp) - return time.strftime("%Y-%m-%d", exp_time), time.strftime("%H:%M", exp_time) + html.buttonlink(makeuri(request, [], delvars=["filled_in"]), _("Cancel")) + html.close_div() - def _action( # pylint: disable=too-many-branches - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if "aggr_tree" in row: # BI mode - specs = [] - for site, host, service in _find_all_leaves(row["aggr_tree"]): - if service: - spec = f"{host};{service}" - cmdtag = "SVC" - else: - spec = host - cmdtag = "HOST" - specs.append((site, spec, cmdtag)) - - if request.var("_acknowledge"): - comment = request.get_str_input("_ack_comment") - if not comment: - raise MKUserError("_ack_comment", _("You need to supply a comment.")) - if ";" in comment: - raise MKUserError("_ack_comment", _("The comment must not contain semicolons.")) - non_empty_comment = comment - - sticky = 2 if request.var("_ack_sticky") else 0 - sendnot = 1 if request.var("_ack_notify") else 0 - perscomm = 1 if request.var("_ack_persistent") else 0 - - if request.var("_ack_expire"): - expire_date = self._vs_date().from_html_vars("_ack_expire_date") - expire_time = self._vs_time().from_html_vars("_ack_expire_time") - expire_timestamp = int( - time.mktime( - time.strptime(f"{expire_date} {expire_time}", "%Y-%m-%d %H:%M"), - ) - ) - if expire_timestamp < time.time(): - raise MKUserError( - "_ack_expire", - _("You cannot set an expiration date and time that is in the past:") - + f' "{expire_date} {expire_time}"', - ) - expire_text = ";%d" % expire_timestamp +def _action_defaults_url() -> str: + return makeuri_contextless( + request, + [("mode", "edit_configvar"), ("varname", "acknowledge_problems")], + filename="wato.py", + ) + + +def _link_to_notification_rules() -> HTML: + return html.render_a( + _("notification rules"), + makeuri_contextless(request, [("mode", "notifications")], filename="wato.py"), + ) + + +def _expiration_date_and_time(time_until_exp: int) -> tuple[str, str]: + exp_time = time.localtime(time.time() + time_until_exp) + return time.strftime("%Y-%m-%d", exp_time), time.strftime("%H:%M", exp_time) + + +def command_acknowledge_action( # pylint: disable=too-many-branches + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if "aggr_tree" in row: # BI mode + specs = [] + for site, host, service in _find_all_leaves(row["aggr_tree"]): + if service: + spec = f"{host};{service}" + cmdtag = "SVC" else: - expire_text = "" + spec = host + cmdtag = "HOST" + specs.append((site, spec, cmdtag)) - def make_command_ack(spec, cmdtag): - return ( - "ACKNOWLEDGE_" - + cmdtag - + "_PROBLEM;%s;%d;%d;%d;%s" % (spec, sticky, sendnot, perscomm, user.id) - + (";%s" % livestatus.lqencode(non_empty_comment)) - + expire_text + if request.var("_acknowledge"): + comment = request.get_str_input("_ack_comment") + if not comment: + raise MKUserError("_ack_comment", _("You need to supply a comment.")) + if ";" in comment: + raise MKUserError("_ack_comment", _("The comment must not contain semicolons.")) + non_empty_comment = comment + + sticky = 2 if request.var("_ack_sticky") else 0 + sendnot = 1 if request.var("_ack_notify") else 0 + perscomm = 1 if request.var("_ack_persistent") else 0 + + if request.var("_ack_expire"): + expire_date = _vs_date().from_html_vars("_ack_expire_date") + expire_time = _vs_time().from_html_vars("_ack_expire_time") + expire_timestamp = int( + time.mktime( + time.strptime(f"{expire_date} {expire_time}", "%Y-%m-%d %H:%M"), ) + ) - if "aggr_tree" in row: # BI mode - commands = [ - (site, make_command_ack(spec_, cmdtag_)) for site, spec_, cmdtag_ in specs - ] - else: - commands = [make_command_ack(spec, cmdtag)] + if expire_timestamp < time.time(): + raise MKUserError( + "_ack_expire", + _("You cannot set an expiration date and time that is in the past:") + + f' "{expire_date} {expire_time}"', + ) + expire_text = ";%d" % expire_timestamp + else: + expire_text = "" - return commands, self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), + def make_command_ack(spec, cmdtag): + return ( + "ACKNOWLEDGE_" + + cmdtag + + "_PROBLEM;%s;%d;%d;%d;%s" % (spec, sticky, sendnot, perscomm, user.id) + + (";%s" % livestatus.lqencode(non_empty_comment)) + + expire_text ) - return None + if "aggr_tree" in row: # BI mode + commands = [(site, make_command_ack(spec_, cmdtag_)) for site, spec_, cmdtag_ in specs] + else: + commands = [make_command_ack(spec, cmdtag)] - def _vs_date(self) -> DatePicker: - return DatePicker( - title=_("Acknowledge problems date picker"), - onchange="cmk.page_menu.ack_problems_update_expiration_active_state(this);", - ) + return commands, command.confirm_dialog_options(cmdtag, row, action_rows) - def _vs_time(self) -> TimePicker: - return TimePicker( - title=_("Acknowledge problems time picker"), - onchange="cmk.page_menu.ack_problems_update_expiration_active_state(this);", - ) + return None -class CommandRemoveAcknowledgments(Command): - @property - def ident(self) -> str: - return "remove_acknowledgments" +CommandAcknowledge = Command( + ident="acknowledge", + title=_l("Acknowledge problems"), + confirm_title=_l("Acknowledge problems?"), + confirm_button=_l("Yes, acknowledge"), + cancel_button=_l("No, discard"), + deny_button=_l("No, adjust settings"), + deny_js_function='() => cmk.page_menu.toggle_popup("popup_command_acknowledge")', + icon_name="ack", + is_shortcut=True, + is_suggested=True, + permission=PermissionActionAcknowledge, + group=CommandGroupAcknowledge, + tables=["host", "service", "aggr"], + render=command_acknowledge_render, + action=command_acknowledge_action, + confirm_dialog_additions=command_acknowledge_confirm_dialog_additions, +) - @property - def title(self) -> str: - return _("Remove acknowledgments") - @property - def confirm_title(self) -> str: - return _("Remove all acknowledgments?") +def _vs_date() -> DatePicker: + return DatePicker( + title=_("Acknowledge problems date picker"), + onchange="cmk.page_menu.ack_problems_update_expiration_active_state(this);", + ) - @property - def confirm_button(self) -> LazyString: - return _l("Remove all") - @property - def icon_name(self): - return "ack" +def _vs_time() -> TimePicker: + return TimePicker( + title=_("Acknowledge problems time picker"), + onchange="cmk.page_menu.ack_problems_update_expiration_active_state(this);", + ) - @property - def permission(self) -> Permission: - return PermissionActionAcknowledge - @property - def group(self) -> type[CommandGroup]: - return CommandGroupAcknowledge +def command_remove_acknowledgements_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + if (acks := _number_of_acknowledgements(row, action_rows, cmdtag)) is None: + return HTML.empty() - @property - def tables(self) -> list[str]: - return ["host", "service", "aggr"] + return html.render_div(_("Acknowledgments: ") + str(acks)) - @property - def show_command_form(self) -> bool: - return False - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - return ( - html.render_div(_("Acknowledgments: ") + str(self._number_of_acknowledgments)) - if self._number_of_acknowledgments - else HTML.empty() - ) +def command_remove_acknowledgements_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if not request.var("_remove_acknowledgments"): + return None - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if not request.var("_remove_acknowledgments"): - return None + def make_command_rem(spec, cmdtag): + return "REMOVE_" + cmdtag + "_ACKNOWLEDGEMENT;%s" % spec - def make_command_rem(spec, cmdtag): - return "REMOVE_" + cmdtag + "_ACKNOWLEDGEMENT;%s" % spec + if "aggr_tree" in row: # BI mode + specs = [] + for site, host, service in _find_all_leaves(row["aggr_tree"]): + if service: + spec = f"{host};{service}" + cmdtag = "SVC" + else: + spec = host + cmdtag = "HOST" + specs.append((site, spec, cmdtag)) + commands = [(site, make_command_rem(spec, cmdtag)) for site, spec_, cmdtag_ in specs] + else: + commands = [make_command_rem(spec, cmdtag)] - # TODO: Can we also find out the number of acknowledgments for BI aggregation rows? - self._number_of_acknowledgments: int | None = None - if "aggr_tree" in row: # BI mode - specs = [] - for site, host, service in _find_all_leaves(row["aggr_tree"]): - if service: - spec = f"{host};{service}" - cmdtag = "SVC" - else: - spec = host - cmdtag = "HOST" - specs.append((site, spec, cmdtag)) - commands = [(site, make_command_rem(spec, cmdtag)) for site, spec_, cmdtag_ in specs] - else: - commands = [make_command_rem(spec, cmdtag)] - - what = "host" if cmdtag == "HOST" else "service" - unique_acknowledgments: set[tuple[str, str]] = set() - for row_ in action_rows: - unique_acknowledgments.update( - { - # take author and timestamp as unique acknowledgment key - # comment_spec = [id, author, comment, type, timestamp] - (comment_spec[1], comment_spec[4]) - for comment_spec in row_.get(f"{what}_comments_with_extra_info", []) - } - ) - self._number_of_acknowledgments = len(unique_acknowledgments) + return commands, command.confirm_dialog_options(cmdtag, row, action_rows) - return commands, self.confirm_dialog_options(cmdtag, row, len(action_rows)) + +def _number_of_acknowledgements( + row: Row, action_rows: Rows, cmdtag: Literal["HOST", "SVC"] +) -> int | None: + # TODO: Can we also find out the number of acknowledgments for BI aggregation rows? + if "aggr_tree" in row: # BI mode + return None + + return len( + _unique_acknowledgements(action_rows, what="host" if cmdtag == "HOST" else "service") + ) +def _unique_acknowledgements(action_rows: Rows, what: str) -> set[tuple[str, str]]: + unique_acknowledgments: set[tuple[str, str]] = set() + for row in action_rows: + unique_acknowledgments.update( + { + # take author and timestamp as unique acknowledgment key + # comment_spec = [id, author, comment, type, timestamp] + (comment_spec[1], comment_spec[4]) + for comment_spec in row.get(f"{what}_comments_with_extra_info", []) + } + ) + return unique_acknowledgments + + +CommandRemoveAcknowledgments = Command( + ident="remove_acknowledgments", + title=_l("Remove acknowledgments"), + confirm_title=_l("Remove all acknowledgments?"), + confirm_button=_l("Remove all"), + icon_name="ack", + permission=PermissionActionAcknowledge, + group=CommandGroupAcknowledge, + tables=["host", "service", "aggr"], + show_command_form=False, + render=lambda _unused: None, + action=command_remove_acknowledgements_action, + confirm_dialog_additions=command_remove_acknowledgements_confirm_dialog_additions, +) + # . # .--Comments------------------------------------------------------------. # | ____ _ | @@ -1316,68 +1187,58 @@ def make_command_rem(spec, cmdtag): ) -class CommandAddComment(Command): - @property - def ident(self) -> str: - return "add_comment" - - @property - def title(self) -> str: - return _("Add comment") - - @property - def confirm_title(self) -> str: - return _("Add comment?") - - @property - def confirm_button(self) -> LazyString: - return _l("Add") - - @property - def icon_name(self): - return "comment" - - @property - def permission(self) -> Permission: - return PermissionActionAddComment - - @property - def tables(self) -> list[str]: - return ["host", "service"] - - def render(self, what: str) -> None: - html.open_div(class_="group") - html.text_input( - "_comment", - id_="comment", - size=60, - submit="_add_comment", - label=_("Comment"), - required=True, +def command_add_comment_render(what: str) -> None: + html.open_div(class_="group") + html.text_input( + "_comment", + id_="comment", + size=60, + submit="_add_comment", + label=_("Comment"), + required=True, + ) + html.close_div() + + html.open_div(class_="group") + html.button("_add_comment", _("Add comment"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_add_comment_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.var("_add_comment"): + comment = request.get_str_input("_comment") + if not comment: + raise MKUserError("_comment", _("You need to supply a comment.")) + cmd = ( + "ADD_" + + cmdtag + + f"_COMMENT;{spec};1;{user.id}" + + (";%s" % livestatus.lqencode(comment)) ) - html.close_div() - - html.open_div(class_="group") - html.button("_add_comment", _("Add comment"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() + return cmd, command.confirm_dialog_options(cmdtag, row, action_rows) + return None - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.var("_add_comment"): - comment = request.get_str_input("_comment") - if not comment: - raise MKUserError("_comment", _("You need to supply a comment.")) - command = ( - "ADD_" - + cmdtag - + f"_COMMENT;{spec};1;{user.id}" - + (";%s" % livestatus.lqencode(comment)) - ) - return command, self.confirm_dialog_options(cmdtag, row, len(action_rows)) - return None +CommandAddComment = Command( + ident="add_comment", + title=_l("Add comment"), + confirm_title=_l("Add comment?"), + confirm_button=_l("Add"), + icon_name="comment", + permission=PermissionActionAddComment, + tables=["host", "service"], + group=CommandGroupVarious, + render=command_add_comment_render, + action=command_add_comment_action, +) # . # .--Downtimes-----------------------------------------------------------. @@ -1453,59 +1314,24 @@ def title_prefix(self, recurring_number: int) -> str: class CommandScheduleDowntimes(Command): - recurring_downtimes: RecurringDowntimes = NoRecurringDowntimes() - - @property - def ident(self) -> str: - return "schedule_downtimes" - - @property - def title(self) -> str: - return _("Schedule downtimes") - - @property - def confirm_title(self) -> str: - return _("Schedule downtime?") - - @property - def confirm_button(self) -> LazyString: - return _l("Yes, schedule") - - @property - def cancel_button(self) -> LazyString: - return _l("No, discard") - - @property - def deny_button(self) -> LazyString | None: - return _l("No, adjust settings") - - @property - def deny_js_function(self) -> str | None: - return '() => cmk.page_menu.toggle_popup("popup_command_schedule_downtimes")' - - @property - def icon_name(self): - return "downtime" - - @property - def is_shortcut(self) -> bool: - return True - - @property - def is_suggested(self) -> bool: - return True - - @property - def permission(self) -> Permission: - return PermissionActionDowntimes - - @property - def group(self) -> type[CommandGroup]: - return CommandGroupDowntimes - - @property - def tables(self) -> list[str]: - return ["host", "service", "aggr"] + def __init__(self, recurring_downtimes: RecurringDowntimes) -> None: + super().__init__( + ident="schedule_downtimes", + title=_l("Schedule downtimes"), + confirm_title=_l("Schedule a downtime?"), + confirm_button=_l("Yes, schedule"), + cancel_button=_l("No, discard"), + deny_button=_l("No, adjust settings"), + deny_js_function='() => cmk.page_menu.toggle_popup("popup_command_schedule_downtimes")', + icon_name="downtime", + is_shortcut=True, + is_suggested=True, + permission=PermissionActionDowntimes, + group=CommandGroupDowntimes, + tables=["host", "service", "aggr"], + render=CommandScheduleDowntimesForm(recurring_downtimes).render, + action=CommandScheduleDowntimesForm(recurring_downtimes).action, + ) def user_confirm_options( self, len_rows: int, cmdtag: Literal["HOST", "SVC"] @@ -1521,6 +1347,11 @@ def user_confirm_options( ] return super().user_confirm_options(len_rows, cmdtag) + +class CommandScheduleDowntimesForm: + def __init__(self, recurring_downtimes: RecurringDowntimes) -> None: + self.recurring_downtimes = recurring_downtimes + def render(self, what: str) -> None: if self._adhoc_downtime_configured(): self._render_adhoc_comment(what) @@ -1577,8 +1408,8 @@ def _render_date_and_time(self) -> None: # pylint: disable=too-many-statements html.write_text_permissive(_("Start")) html.close_td() html.open_td() - self._vs_date().render_input("_down_from_date", time.strftime("%Y-%m-%d")) - self._vs_time().render_input("_down_from_time", time.strftime("%H:%M")) + _vs_date().render_input("_down_from_date", time.strftime("%Y-%m-%d")) + _vs_time().render_input("_down_from_time", time.strftime("%H:%M")) html.span( timezone_utc_offset_str() + " " @@ -1594,9 +1425,9 @@ def _render_date_and_time(self) -> None: # pylint: disable=too-many-statements html.write_text_permissive(_("End")) html.close_td() html.open_td() - self._vs_date().render_input("_down_to_date", time.strftime("%Y-%m-%d")) + _vs_date().render_input("_down_to_date", time.strftime("%Y-%m-%d")) default_endtime: float = time.time() + 7200 - self._vs_time().render_input( + _vs_time().render_input( "_down_to_time", time.strftime("%H:%M", time.localtime(default_endtime)) ) html.span( @@ -1758,8 +1589,9 @@ def _vs_flexible_options(self) -> Dictionary: ], ) - def _action( # pylint: disable=too-many-arguments + def action( # pylint: disable=too-many-arguments self, + command: Command, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, @@ -1789,47 +1621,20 @@ def _action( # pylint: disable=too-many-arguments delayed_duration = self._flexible_option() mode = determine_downtime_mode(recurring_number, delayed_duration) downtime = DowntimeSchedule(start_time, end_time, mode, delayed_duration, comment) - cmdtag, specs, len_action_rows = self._downtime_specs(cmdtag, row, action_rows, spec) + cmdtag, specs, action_rows = self._downtime_specs(cmdtag, row, action_rows, spec) if "aggr_tree" in row: # BI mode node: CompiledAggrTree = row["aggr_tree"] return ( _bi_commands(downtime, node), - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), + command.confirm_dialog_options(cmdtag, row, action_rows), ) return ( [downtime.livestatus_command(spec_, cmdtag) for spec_ in specs], - self._confirm_dialog_options( - cmdtag, - row, - len_action_rows, - _("Schedule a downtime?"), - ), + command.confirm_dialog_options(cmdtag, row, action_rows), ) return None - def _confirm_dialog_options( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - title: str, - ) -> CommandConfirmDialogOptions: - return CommandConfirmDialogOptions( - title, - self.affected(len_action_rows, cmdtag), - self.confirm_dialog_additions(cmdtag, row, len_action_rows), - self.confirm_dialog_icon_class(), - self.confirm_button, - self.cancel_button, - self.deny_button, - self.deny_js_function, - ) - def _get_adhoc_end_time(self, start_time: float) -> float: return start_time + active_config.adhoc_downtime.get("duration", 0) * 60 @@ -1837,18 +1642,18 @@ def confirm_dialog_additions( self, cmdtag: Literal["HOST", "SVC"], row: Row, - len_action_rows: int, + action_rows: Rows, ) -> HTML: start_at = self._custom_start_time() additions = HTMLWriter.render_table( HTMLWriter.render_tr( HTMLWriter.render_td(_("Start:")) - + HTMLWriter.render_td(self.confirm_dialog_date_and_time_format(start_at)) + + HTMLWriter.render_td(_confirm_dialog_date_and_time_format(start_at)) ) + HTMLWriter.render_tr( HTMLWriter.render_td(_("End:")) + HTMLWriter.render_td( - self.confirm_dialog_date_and_time_format( + _confirm_dialog_date_and_time_format( self._get_adhoc_end_time(start_at) if request.var("_down_adhoc") else self._custom_end_time(start_at) @@ -1905,7 +1710,7 @@ def confirm_dialog_additions( % ungettext( "host", "hosts", - len_action_rows, + len(action_rows), ) if cmdtag == "HOST" else _("Info: Downtime does not apply to host.") @@ -1938,11 +1743,11 @@ def _current_local_time(self) -> float: return time.time() def _custom_start_time(self) -> float: - vs_date = self._vs_date() + vs_date = _vs_date() raw_start_date = vs_date.from_html_vars("_down_from_date") vs_date.validate_value(raw_start_date, "_down_from_date") - vs_time = self._vs_time() + vs_time = _vs_time() raw_start_time = vs_time.from_html_vars("_down_from_time") vs_time.validate_value(raw_start_time, "_down_from_time") @@ -1953,11 +1758,11 @@ def _custom_start_time(self) -> float: return down_from def _custom_end_time(self, start_time: float) -> float: - vs_date = self._vs_date() + vs_date = _vs_date() raw_end_date = vs_date.from_html_vars("_down_to_date") vs_date.validate_value(raw_end_date, "_down_to_date") - vs_time = self._vs_time() + vs_time = _vs_time() raw_end_time = vs_time.from_html_vars("_down_to_time") vs_time.validate_value(raw_end_time, "_down_to_time") @@ -1984,9 +1789,7 @@ def _downtime_specs( row: Row, action_rows: Rows, spec: str, - ) -> tuple[Literal["HOST", "SVC"], list[str], int]: - len_action_rows = len(action_rows) - + ) -> tuple[Literal["HOST", "SVC"], list[str], Rows]: vs_host_downtime = self._vs_host_downtime() included_from_html = vs_host_downtime.from_html_vars("_include_children") vs_host_downtime.validate_value(included_from_html, "_include_children") @@ -1996,10 +1799,20 @@ def _downtime_specs( elif request.var("_down_host"): # set on hosts instead of services specs = [spec.split(";")[0]] cmdtag = "HOST" - len_action_rows = len({row["host_name"] for row in action_rows}) + # We do not want to count the services but the affected hosts in this case. + # Since we can not get actual host rows here, we use one row per affected host + # as an approximation. This is good enough to count the affected hosts. + seen = set() + host_action_rows = [] + for action_row in action_rows: + if row["host_name"] not in seen: + seen.add(action_row["host_name"]) + host_action_rows.append(action_row) + action_rows = host_action_rows + else: specs = [spec] - return cmdtag, specs, len_action_rows + return cmdtag, specs, action_rows def _vs_down_from(self) -> AbsoluteDate: return AbsoluteDate( @@ -2043,6 +1856,18 @@ def _adhoc_downtime_configured(self) -> bool: return bool(active_config.adhoc_downtime and active_config.adhoc_downtime.get("duration")) +def _confirm_dialog_date_and_time_format(timestamp: float, show_timezone: bool = True) -> str: + """Return date, time and if show_timezone is True the local timezone in the format of e.g. + 'Mon, 01. January 2042 at 01:23 [UTC+01:00]'""" + local_time = time.localtime(timestamp) + return ( + time.strftime(_("%a, %d. %B %Y at %H:%M"), local_time) + + (" " + timezone_utc_offset_str(timestamp)) + if show_timezone + else "" + ) + + def _bi_commands(downtime: DowntimeSchedule, node: CompiledAggrTree) -> Sequence[CommandSpec]: """Generate the list of downtime command strings for the BI module""" commands_aggr = [] @@ -2107,119 +1932,89 @@ def time_interval_end( return None -class CommandRemoveDowntime(Command): - @property - def ident(self) -> str: - return "remove_downtimes" - - @property - def title(self) -> str: - return _("Remove downtimes") - - @property - def confirm_title(self) -> str: - return _("Remove downtimes?") - - @property - def confirm_button(self) -> LazyString: - return _l("Remove") - - @property - def permission(self) -> Permission: - return PermissionActionDowntimes +def command_remove_downtime_render(what: str) -> None: + html.button("_remove_downtimes", _("Remove")) - @property - def group(self) -> type[CommandGroup]: - return CommandGroupDowntimes - @property - def tables(self) -> list[str]: - return ["host", "service", "downtime"] +def command_remove_downtime_action( # pylint: disable=too-many-arguments + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if request.has_var("_remove_downtimes"): + if "downtime_id" in row: + return _rm_downtime_from_downtime_datasource(command, cmdtag, spec, row, action_rows) + return _rm_downtime_from_hst_or_svc_datasource(command, cmdtag, row, action_rows) + return None - # we only want to show the button and shortcut in the explicit downtime - # view - @property - def is_shortcut(self) -> bool: - return self.is_suggested - @property - def is_suggested(self) -> bool: - return request.var("view_name", "") in [ - "downtimes", - "downtimes_of_host", - "downtimes_of_service", - ] - - def _confirm_dialog_options( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - title: str, - ) -> CommandConfirmDialogOptions: - return CommandConfirmDialogOptions( - title, - self.affected(len_action_rows, cmdtag), - self.confirm_dialog_additions(cmdtag, row, len_action_rows), - self.confirm_dialog_icon_class(), - self.confirm_button, - self.cancel_button, - self.deny_button, - self.deny_js_function, - ) +def _rm_downtime_from_downtime_datasource( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + action_rows: Rows, +) -> CommandActionResult: + return ( + f"DEL_{cmdtag}_DOWNTIME;{spec}", + command.confirm_dialog_options( + cmdtag, + row, + action_rows, + ), + ) - def render(self, what: str) -> None: - html.button("_remove_downtimes", _("Remove")) - def _action( # pylint: disable=too-many-arguments - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if request.has_var("_remove_downtimes"): - if "downtime_id" in row: - return self._rm_downtime_from_downtime_datasource(cmdtag, spec, row, action_rows) - return self._rm_downtime_from_hst_or_svc_datasource(cmdtag, row, action_rows) +def _rm_downtime_from_hst_or_svc_datasource( + command: Command, cmdtag: Literal["HOST", "SVC"], row: Row, action_rows: Rows +) -> tuple[list[str], CommandConfirmDialogOptions] | None: + if not user.may("action.remove_all_downtimes"): return None - def _rm_downtime_from_downtime_datasource( - self, - cmdtag: Literal["HOST", "SVC"], - spec: str, - row: Row, - action_rows: Rows, - ) -> CommandActionResult: - return ( - f"DEL_{cmdtag}_DOWNTIME;{spec}", - self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ), - ) - - def _rm_downtime_from_hst_or_svc_datasource( - self, cmdtag: Literal["HOST", "SVC"], row: Row, action_rows: Rows - ) -> tuple[list[str], CommandConfirmDialogOptions] | None: - if not user.may("action.remove_all_downtimes"): - return None + downtime_ids = [] + if cmdtag == "HOST": + prefix = "host_" + else: + prefix = "service_" + for id_ in row[prefix + "downtimes"]: + if id_ != "": + downtime_ids.append(int(id_)) + commands = [] + for dtid in downtime_ids: + commands.append(f"DEL_{cmdtag}_DOWNTIME;{dtid}\n") + return commands, command.confirm_dialog_options(cmdtag, row, action_rows) + + +CommandRemoveDowntimesHostServicesTable = Command( + ident="remove_downtimes_hosts_services", + title=_l("Remove downtimes"), + confirm_title=_l("Remove scheduled downtimes?"), + confirm_button=_l("Remove"), + permission=PermissionActionDowntimes, + group=CommandGroupDowntimes, + tables=["host", "service"], + is_shortcut=False, + is_suggested=False, + render=command_remove_downtime_render, + action=command_remove_downtime_action, +) - downtime_ids = [] - if cmdtag == "HOST": - prefix = "host_" - else: - prefix = "service_" - for id_ in row[prefix + "downtimes"]: - if id_ != "": - downtime_ids.append(int(id_)) - commands = [] - for dtid in downtime_ids: - commands.append(f"DEL_{cmdtag}_DOWNTIME;{dtid}\n") - title = _("Remove scheduled downtimes?") - return commands, self._confirm_dialog_options( - cmdtag, - row, - len(action_rows), - title, - ) +CommandRemoveDowntimesDowntimesTable = Command( + ident="remove_downtimes", + title=_l("Remove downtimes"), + confirm_title=_l("Remove scheduled downtimes?"), + confirm_button=_l("Remove"), + permission=PermissionActionDowntimes, + group=CommandGroupDowntimes, + tables=["downtime"], + is_shortcut=True, + is_suggested=True, + render=command_remove_downtime_render, + action=command_remove_downtime_action, +) @request_memoize() @@ -2256,87 +2051,76 @@ def _acknowledgement_needs_removal( ) -class CommandRemoveComments(Command): - @property - def ident(self) -> str: - return "remove_comments" - - @property - def title(self) -> str: - return _("Delete comments") - - @property - def confirm_title(self) -> str: - return "%s?" % self.title - - @property - def confirm_button(self) -> LazyString: - return _l("Delete") - - @property - def is_shortcut(self) -> bool: - return True - - @property - def is_suggested(self) -> bool: - return True - - @property - def permission(self) -> Permission: - return PermissionActionAddComment - - @property - def tables(self) -> list[str]: - return ["comment"] - - def affected(self, len_action_rows: int, cmdtag: Literal["HOST", "SVC"]) -> HTML: - return HTML.empty() - - def confirm_dialog_additions( - self, - cmdtag: Literal["HOST", "SVC"], - row: Row, - len_action_rows: int, - ) -> HTML: - if len_action_rows > 1: - return HTML.without_escaping(_("Total comments: %d") % len_action_rows) - return HTML.without_escaping(_("Author: ")) + row["comment_author"] +def command_remove_comments_confirm_dialog_additions( + cmdtag: Literal["HOST", "SVC"], + row: Row, + action_rows: Rows, +) -> HTML: + if len(action_rows) > 1: + return HTML.without_escaping(_("Total comments: %d") % len(action_rows)) + return HTML.without_escaping(_("Author: ")) + row["comment_author"] + + +def command_remove_comments_render(what: str) -> None: + html.open_div(class_="group") + html.button("_delete_comments", _("Delete"), cssclass="hot") + html.button("_cancel", _("Cancel")) + html.close_div() + + +def command_remove_comments_action( + command: Command, + cmdtag: Literal["HOST", "SVC"], + spec: str, + row: Row, + row_index: int, + action_rows: Rows, +) -> CommandActionResult: + if not request.has_var("_delete_comments"): + return None + # NOTE: To remove an acknowledgement, we have to use the specialized command, not only the + # general one. The latter one only removes the comment itself, not the "acknowledged" state. + # NOTE: We get the commend ID (an int) as a str via the spec parameter (why???), but we need + # the specification of the host or service for REMOVE_FOO_ACKNOWLEDGEMENT. + commands = [] + if row.get("comment_entry_type") == 4: # an acknowledgement + # NOTE: REMOVE_FOO_ACKNOWLEDGEMENT removes all non-persistent acknowledgement comments. + # This means if we remove some acknowledgement comments, we should only fire + # REMOVE_FOO_ACKNOWLEDGEMENT if there are no other acknowledgement comments left. + comments_to_be_removed = {str(r["comment_id"]) for r in action_rows} + if _acknowledgement_needs_removal(cmdtag, comments_to_be_removed): + if cmdtag == "HOST": + rm_ack = f"REMOVE_HOST_ACKNOWLEDGEMENT;{row['host_name']}" + else: + rm_ack = ( + f"REMOVE_SVC_ACKNOWLEDGEMENT;{row['host_name']};{row['service_description']}" + ) + commands.append(rm_ack) + # Nevertheless, we need the general command, too, even for acknowledgements: The + # acknowledgement might be persistent, so REMOVE_FOO_ACKNOWLEDGEMENT leaves the comment + # itself, that's the whole point of being persistent. The only way to get rid of such a + # comment is via DEL_FOO_COMMENT. + del_cmt = f"DEL_HOST_COMMENT;{spec}" if cmdtag == "HOST" else f"DEL_SVC_COMMENT;{spec}" + commands.append(del_cmt) + return commands, command.confirm_dialog_options( + cmdtag, + row, + action_rows, + ) - def render(self, what: str) -> None: - html.open_div(class_="group") - html.button("_delete_comments", _("Delete"), cssclass="hot") - html.button("_cancel", _("Cancel")) - html.close_div() - def _action( - self, cmdtag: Literal["HOST", "SVC"], spec: str, row: Row, row_index: int, action_rows: Rows - ) -> CommandActionResult: - if not request.has_var("_delete_comments"): - return None - # NOTE: To remove an acknowledgement, we have to use the specialized command, not only the - # general one. The latter one only removes the comment itself, not the "acknowledged" state. - # NOTE: We get the commend ID (an int) as a str via the spec parameter (why???), but we need - # the specification of the host or service for REMOVE_FOO_ACKNOWLEDGEMENT. - commands = [] - if row.get("comment_entry_type") == 4: # an acknowledgement - # NOTE: REMOVE_FOO_ACKNOWLEDGEMENT removes all non-persistent acknowledgement comments. - # This means if we remove some acknowledgement comments, we should only fire - # REMOVE_FOO_ACKNOWLEDGEMENT if there are no other acknowledgement comments left. - comments_to_be_removed = {str(r["comment_id"]) for r in action_rows} - if _acknowledgement_needs_removal(cmdtag, comments_to_be_removed): - if cmdtag == "HOST": - rm_ack = f"REMOVE_HOST_ACKNOWLEDGEMENT;{row['host_name']}" - else: - rm_ack = f"REMOVE_SVC_ACKNOWLEDGEMENT;{row['host_name']};{row['service_description']}" - commands.append(rm_ack) - # Nevertheless, we need the general command, too, even for acknowledgements: The - # acknowledgement might be persistent, so REMOVE_FOO_ACKNOWLEDGEMENT leaves the comment - # itself, that's the whole point of being persistent. The only way to get rid of such a - # comment is via DEL_FOO_COMMENT. - del_cmt = f"DEL_HOST_COMMENT;{spec}" if cmdtag == "HOST" else f"DEL_SVC_COMMENT;{spec}" - commands.append(del_cmt) - return commands, self.confirm_dialog_options( - cmdtag, - row, - len(action_rows), - ) +CommandRemoveComments = Command( + ident="remove_comments", + title=_l("Delete comments"), + confirm_title=_l("Delete comments?"), + confirm_button=_l("Delete"), + is_shortcut=True, + is_suggested=True, + permission=PermissionActionAddComment, + group=CommandGroupVarious, + tables=["comment"], + affected_output_cb=lambda _a, _b: HTML.empty(), + render=command_remove_comments_render, + action=command_remove_comments_action, + confirm_dialog_additions=command_remove_comments_confirm_dialog_additions, +) diff --git a/cmk/gui/views/command/form.py b/cmk/gui/views/command/form.py index 842491e332b..f259494a0b4 100644 --- a/cmk/gui/views/command/form.py +++ b/cmk/gui/views/command/form.py @@ -57,8 +57,7 @@ def core_command( # itself to be executed (by examining the HTML variables) # will return a command to execute and confirm dialog options for the # confirmation dialog. - for cmd_class in command_registry.values(): - cmd = cmd_class() + for cmd in command_registry.values(): if user.may(cmd.permission.name): result = cmd.action(cmdtag, spec, row, row_nr, action_rows) confirm_options = cmd.user_confirm_options(len(action_rows), cmdtag) @@ -97,8 +96,7 @@ def should_show_command_form( # information) then the first info is the primary table. So 'what' # will be one of "host", "service", "command" or "downtime". what = datasource.infos[0] - for command_class in command_registry.values(): - command = command_class() + for command in command_registry.values(): if what in command.tables and user.may(command.permission.name): return True @@ -108,8 +106,7 @@ def should_show_command_form( def get_command_groups(info_name: InfoName) -> dict[type[CommandGroup], list[Command]]: by_group: dict[type[CommandGroup], list[Command]] = {} - for command_class in command_registry.values(): - command = command_class() + for command in command_registry.values(): if info_name in command.tables and user.may(command.permission.name): # Some special commands can be shown on special views using this option. It is # currently only used by custom commands, not shipped with Checkmk. diff --git a/cmk/gui/views/command/registry.py b/cmk/gui/views/command/registry.py index dc3866f57ca..6b2b0547bba 100644 --- a/cmk/gui/views/command/registry.py +++ b/cmk/gui/views/command/registry.py @@ -16,9 +16,9 @@ from .group import command_group_registry -class CommandRegistry(Registry[type[Command]]): - def plugin_name(self, instance: type[Command]) -> str: - return instance().ident +class CommandRegistry(Registry[Command]): + def plugin_name(self, instance: Command) -> str: + return instance.ident command_registry = CommandRegistry() @@ -26,27 +26,18 @@ def plugin_name(self, instance: type[Command]) -> str: # TODO: Kept for pre 1.6 compatibility def register_legacy_command(spec: dict[str, Any]) -> None: - ident = re.sub("[^a-zA-Z]", "", spec["title"]).lower() - cls = type( - "LegacyCommand%s" % str(ident).title(), - (Command,), - { - "_ident": ident, - "_spec": spec, - "ident": property(lambda s: s._ident), - "title": property(lambda s: s._spec["title"]), - "confirm_button": property(lambda s: s._spec.get("confirm_button", "Submit")), - "permission": property(lambda s: permission_registry[s._spec["permission"]]), - "tables": property(lambda s: s._spec["tables"]), - "render": lambda s: s._spec["render"](), - "action": lambda s, cmdtag, spec, row, row_index, num_rows: s._spec["action"]( - cmdtag, spec, row + command_registry.register( + Command( + ident=re.sub("[^a-zA-Z]", "", spec["title"]).lower(), + title=spec["title"], + confirm_button=spec.get("confirm_button", "Submit"), + permission=permission_registry[spec["permission"]], + tables=spec["tables"], + render=spec["render"], + action=lambda command, cmdtag, cmd_spec, row, row_index, action_rows: spec["action"]( + cmdtag, cmd_spec, row ), - "_action": lambda s, cmdtag, spec, row, row_index, num_rows: s._spec["_action"]( - cmdtag, spec, row - ), - "group": lambda s: command_group_registry[s._spec.get("group", "various")], - "only_view": lambda s: s._spec.get("only_view"), - }, + group=command_group_registry[spec.get("group", "various")], + only_view=spec.get("only_view"), + ) ) - command_registry.register(cls) diff --git a/cmk/gui/views/inventory/_painters.py b/cmk/gui/views/inventory/_painters.py index 77c1d6f28e8..dd21300496c 100644 --- a/cmk/gui/views/inventory/_painters.py +++ b/cmk/gui/views/inventory/_painters.py @@ -18,6 +18,8 @@ SDRawDeltaTree, SDRawTree, SDValue, + serialize_delta_tree, + serialize_tree, ) from cmk.gui import sites @@ -138,13 +140,13 @@ def render(self, row: Row, cell: Cell) -> CellSpec: return "invtree", code def export_for_python(self, row: Row, cell: Cell) -> SDRawTree: - return self._compute_data(row, cell).serialize() + return serialize_tree(self._compute_data(row, cell)) def export_for_csv(self, row: Row, cell: Cell) -> str | HTML: raise CSVExportError() def export_for_json(self, row: Row, cell: Cell) -> SDRawTree: - return self._compute_data(row, cell).serialize() + return serialize_tree(self._compute_data(row, cell)) class PainterInvhistTime(Painter): @@ -220,13 +222,13 @@ def render(self, row: Row, cell: Cell) -> CellSpec: return "invtree", code def export_for_python(self, row: Row, cell: Cell) -> SDRawDeltaTree: - return self._compute_data(row, cell).serialize() + return serialize_delta_tree(self._compute_data(row, cell)) def export_for_csv(self, row: Row, cell: Cell) -> str | HTML: raise CSVExportError() def export_for_json(self, row: Row, cell: Cell) -> SDRawDeltaTree: - return self._compute_data(row, cell).serialize() + return serialize_delta_tree(self._compute_data(row, cell)) def _paint_invhist_count(row: Row, what: str) -> CellSpec: @@ -507,8 +509,10 @@ def node_painter_from_hint( sorter=hint.ident, paint=lambda row: _paint_host_inventory_tree(row, hint.path, painter_options), export_for_python=lambda row, cell: ( - _compute_node_painter_data(row, hint.path).serialize() + serialize_tree(_compute_node_painter_data(row, hint.path)) ), export_for_csv=lambda row, cell: _export_node_for_csv(), - export_for_json=lambda row, cell: _compute_node_painter_data(row, hint.path).serialize(), + export_for_json=lambda row, cell: serialize_tree( + _compute_node_painter_data(row, hint.path) + ), ) diff --git a/cmk/gui/views/inventory/row_post_processor.py b/cmk/gui/views/inventory/row_post_processor.py index 7b9b6d14be1..01c606154de 100644 --- a/cmk/gui/views/inventory/row_post_processor.py +++ b/cmk/gui/views/inventory/row_post_processor.py @@ -6,7 +6,7 @@ from __future__ import annotations from collections.abc import Iterator, Mapping, Sequence -from typing import NamedTuple +from dataclasses import dataclass from cmk.utils.structured_data import ImmutableTree, SDKey, SDPath, SDValue @@ -165,7 +165,8 @@ def _extract_table_rows( return table_rows_by_master_key -class _MasterKey(NamedTuple): +@dataclass(frozen=True) +class _MasterKey: site: str hostname: str @@ -174,7 +175,8 @@ def make(cls, row: Row) -> _MasterKey: return _MasterKey(row["site"], row["host_name"]) -class _FoundTableRow(NamedTuple): +@dataclass(frozen=True) +class _FoundTableRow: ident: str column_value: str | int | float macros: Mapping[str, str | int | float] diff --git a/cmk/gui/views/page_show_view.py b/cmk/gui/views/page_show_view.py index 1a82428e7b3..7a53d047695 100644 --- a/cmk/gui/views/page_show_view.py +++ b/cmk/gui/views/page_show_view.py @@ -34,7 +34,7 @@ from cmk.gui.http import request from cmk.gui.i18n import _ from cmk.gui.logged_in import user -from cmk.gui.page_menu import make_external_link, PageMenuEntry, PageMenuTopic +from cmk.gui.page_menu import make_external_link, PageMenuDropdown, PageMenuEntry, PageMenuTopic from cmk.gui.painter.v0.base import Cell, columns_of_cells from cmk.gui.painter_options import PainterOptions from cmk.gui.type_defs import ( @@ -62,7 +62,9 @@ from .store import get_all_views, get_permitted_views -def page_show_view() -> None: +def page_show_view( + page_menu_dropdowns_callback: Callable[[View, Rows, list[PageMenuDropdown]], None], +) -> None: """Central entry point for the initial HTML page rendering of a view""" with CPUTracker(log.logger.debug) as page_view_tracker: view_name = request.get_ascii_input_mandatory("view_name", "") @@ -97,7 +99,13 @@ def page_show_view() -> None: painter_options = PainterOptions.get_instance() painter_options.load(view.name) painter_options.update_from_url(view.name, view.painter_options) - process_view(GUIViewRenderer(view, show_buttons=True)) + process_view( + GUIViewRenderer( + view, + show_buttons=True, + page_menu_dropdowns_callback=page_menu_dropdowns_callback, + ) + ) _may_create_slow_view_log_entry(page_view_tracker, view) diff --git a/cmk/gui/views/registration.py b/cmk/gui/views/registration.py index bfeef84e3f8..e9c404d0926 100644 --- a/cmk/gui/views/registration.py +++ b/cmk/gui/views/registration.py @@ -4,6 +4,7 @@ # conditions defined in the file COPYING, which is part of this source code package. from collections.abc import Callable +from functools import partial from cmk.gui.data_source import data_source_registry, register_data_sources from cmk.gui.pages import PageRegistry @@ -51,7 +52,9 @@ def register( ) page_registry.register_page("ajax_reschedule")(PageRescheduleCheck) page_registry.register_page("ajax_initial_view_filters")(AjaxInitialViewFilters) - page_registry.register_page_handler("view", page_show_view) + page_registry.register_page_handler( + "view", partial(page_show_view, page_menu_dropdowns_callback=lambda x, y, z: None) + ) page_registry.register_page_handler("create_view", page_select_datasource) page_registry.register_page_handler("edit_view", page_edit_view) page_registry.register_page_handler("edit_views", page_edit_views) diff --git a/cmk/gui/visuals/__init__.py b/cmk/gui/visuals/__init__.py index 81639786d12..5c70d12c426 100644 --- a/cmk/gui/visuals/__init__.py +++ b/cmk/gui/visuals/__init__.py @@ -3,22 +3,24 @@ # 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 cmk.ccc.version as cmk_version +from collections.abc import Callable + from cmk.ccc import store from cmk.utils import paths from cmk.gui import hooks, utils from cmk.gui.pages import PageRegistry -from cmk.gui.valuespec import autocompleter_registry +from cmk.gui.type_defs import FilterHTTPVariables +from cmk.gui.valuespec import AutocompleterRegistry -from . import _filters, info +from . import _filters, _site_filters, info from ._add_to_visual import ( add_to_dashboard_choices_autocompleter, - add_to_report_choices_autocompleter, ajax_add_visual, ajax_popup_add, ) +from ._add_to_visual import get_visual_choices as get_visual_choices from ._add_to_visual import page_menu_dropdown_add_to_visual as page_menu_dropdown_add_to_visual from ._add_to_visual import page_menu_topic_add_to as page_menu_topic_add_to from ._add_to_visual import set_page_context as set_page_context @@ -49,9 +51,6 @@ from ._filter_valuespecs import PageAjaxVisualFilterListGetChoice from ._filter_valuespecs import VisualFilterList as VisualFilterList from ._filter_valuespecs import VisualFilterListWithAddPopup as VisualFilterListWithAddPopup -from ._filters import cre_site_filter_heading_info as cre_site_filter_heading_info -from ._filters import MultipleSitesFilter as MultipleSitesFilter -from ._filters import SiteFilter as SiteFilter from ._livestatus import get_filter_headers as get_filter_headers from ._livestatus import get_livestatus_filter_headers as get_livestatus_filter_headers from ._livestatus import get_only_sites_from_context as get_only_sites_from_context @@ -66,6 +65,8 @@ from ._page_edit_visual import single_infos_spec as single_infos_spec from ._page_list import page_list as page_list from ._permissions import declare_visual_permissions as declare_visual_permissions +from ._site_filters import default_site_filter_heading_info as default_site_filter_heading_info +from ._site_filters import SiteFilter as SiteFilter from ._store import available as available from ._store import available_by_owner as available_by_owner from ._store import declare_custom_permissions as declare_custom_permissions @@ -100,6 +101,9 @@ def register( page_registry: PageRegistry, _visual_info_registry: VisualInfoRegistry, _filter_registry: FilterRegistry, + autocompleter_registry: AutocompleterRegistry, + site_choices: Callable[[], list[tuple[str, str]]], + site_filter_heading_info: Callable[[FilterHTTPVariables], str | None], ) -> None: page_registry.register_page("ajax_visual_filter_list_get_choice")( PageAjaxVisualFilterListGetChoice @@ -108,13 +112,12 @@ def register( page_registry.register_page_handler("ajax_add_visual", ajax_add_visual) info.register(_visual_info_registry) _filters.register(page_registry, filter_registry) + _site_filters.register( + filter_registry, autocompleter_registry, site_choices, site_filter_heading_info + ) autocompleter_registry.register_autocompleter( "add_to_dashboard_choices", add_to_dashboard_choices_autocompleter ) - if cmk_version.edition(paths.omd_root) is not cmk_version.Edition.CRE: - autocompleter_registry.register_autocompleter( - "add_to_report_choices", add_to_report_choices_autocompleter - ) hooks.register_builtin("snapshot-pushed", invalidate_all_caches) hooks.register_builtin( diff --git a/cmk/gui/visuals/_add_to_visual.py b/cmk/gui/visuals/_add_to_visual.py index 65f666a05ff..166170514e7 100644 --- a/cmk/gui/visuals/_add_to_visual.py +++ b/cmk/gui/visuals/_add_to_visual.py @@ -212,20 +212,13 @@ def page_menu_topic_add_to(visual_type: str, name: str, source_type: str) -> lis def add_to_dashboard_choices_autocompleter(value: str, params: dict) -> Choices: - return _get_visual_choices( + return get_visual_choices( visual_type="dashboards", value=value, ) -def add_to_report_choices_autocompleter(value: str, params: dict) -> Choices: - return _get_visual_choices( - visual_type="reports", - value=value, - ) - - -def _get_visual_choices(visual_type: str, value: str) -> Choices: +def get_visual_choices(visual_type: str, value: str) -> Choices: match_pattern = re.compile(value, re.IGNORECASE) matching_visuals = [] for name, content in sorted(visual_type_registry[f"{visual_type}"]().permitted_visuals.items()): diff --git a/cmk/gui/visuals/_filters.py b/cmk/gui/visuals/_filters.py index 6a997dcbeba..d0fd46e42bf 100644 --- a/cmk/gui/visuals/_filters.py +++ b/cmk/gui/visuals/_filters.py @@ -21,7 +21,6 @@ from cmk.gui.http import request from cmk.gui.i18n import _, _l from cmk.gui.pages import AjaxPage, PageRegistry, PageResult -from cmk.gui.site_config import get_site_config from cmk.gui.type_defs import ( Choices, ColumnName, @@ -35,7 +34,7 @@ from cmk.gui.utils.regex import validate_regex from cmk.gui.utils.speaklater import LazyString from cmk.gui.utils.user_errors import user_errors -from cmk.gui.valuespec import DualListChoice, LabelGroups +from cmk.gui.valuespec import LabelGroups from ._livestatus import get_only_sites_from_context from .filter import ( @@ -66,7 +65,6 @@ def register(page_registry: PageRegistry, filter_registry: FilterRegistry) -> No register_host_and_service_detail_filters(filter_registry) register_contact_filters(filter_registry) register_group_table_filters(filter_registry) - register_site_filters(filter_registry) register_comment_filters(filter_registry) register_downtime_filters(filter_registry) register_log_filters(filter_registry) @@ -939,112 +937,6 @@ def register_host_and_service_flag_filters(filter_registry: FilterRegistry) -> N ) -class SiteFilter(Filter): - heading_hook: Callable[[FilterHTTPVariables], str | None] - - def __init__( - self, - *, - title: str | LazyString, - sort_index: int, - query_filter: query_filters.Query, - description: None | str | LazyString = None, - is_show_more: bool = False, - ) -> None: - self.query_filter = query_filter - - super().__init__( - ident=self.query_filter.ident, - title=title, - sort_index=sort_index, - info="host", - htmlvars=self.query_filter.request_vars, - link_columns=[], - description=description, - is_show_more=is_show_more, - ) - - def display(self, value: FilterHTTPVariables) -> None: - current_value = value.get(self.query_filter.request_vars[0], "") - choices = [(current_value, current_value)] if current_value else [] - - html.dropdown( - self.query_filter.request_vars[0], - choices, - current_value, - style="width: 250px;", - class_=["ajax-vals"], - data_autocompleter=json.dumps( - AutocompleterConfig( - ident="sites", - strict=self.query_filter.ident == "site", - ).config - ), - ) - - def heading_info(self, value: FilterHTTPVariables) -> str | None: - return SiteFilter.heading_hook(value) - - def request_vars_from_row(self, row: Row) -> dict[str, str]: - return {"site": row["site"]} - - -def cre_site_filter_heading_info(value: FilterHTTPVariables) -> str | None: - current_value = value.get("site") - return ( - get_site_config(active_config, livestatus.SiteId(current_value))["alias"] - if current_value - else None - ) - - -class MultipleSitesFilter(SiteFilter): - # Poor man's composition: Renderer differs between CME and non-CME. - sites_options: Callable[[], list[tuple[str, str]]] | None = None - - def get_request_sites(self, value: FilterHTTPVariables) -> list[str]: - return [x for x in value.get(self.htmlvars[0], "").strip().split("|") if x] - - def display(self, value: FilterHTTPVariables) -> None: - sites_options = type(self).sites_options - assert sites_options is not None - sites_vs = DualListChoice(choices=sites_options, rows=4) - sites_vs.render_input(self.htmlvars[0], self.get_request_sites(value)) - - -def register_site_filters(filter_registry: FilterRegistry) -> None: - filter_registry.register( - SiteFilter( - title=_l("Site"), - sort_index=500, - query_filter=query_filters.Query( - ident="siteopt", - request_vars=["site"], - ), - description=_l("Optional selection of a site"), - ) - ) - - filter_registry.register( - SiteFilter( - title=_l("Site (enforced)"), - sort_index=501, - query_filter=query_filters.Query(ident="site", request_vars=["site"]), - description=_l("Selection of site is enforced, use this filter for joining"), - is_show_more=True, - ) - ) - - filter_registry.register( - MultipleSitesFilter( - title=_l("Multiple sites"), - sort_index=502, - query_filter=query_filters.Query(ident="sites", request_vars=["sites"]), - description=_l("Associative selection of multiple sites"), - ) - ) - - def register_host_and_service_detail_filters(filter_registry: FilterRegistry) -> None: filter_registry.register( FilterNumberRange( diff --git a/cmk/gui/visuals/_site_filters.py b/cmk/gui/visuals/_site_filters.py new file mode 100644 index 00000000000..e8dfa113401 --- /dev/null +++ b/cmk/gui/visuals/_site_filters.py @@ -0,0 +1,160 @@ +#!/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 Callable +from functools import partial + +import livestatus + +from cmk.gui import query_filters +from cmk.gui.config import active_config +from cmk.gui.htmllib.html import html +from cmk.gui.i18n import _l +from cmk.gui.site_config import get_site_config +from cmk.gui.type_defs import Choices, FilterHTTPVariables, Row +from cmk.gui.utils.autocompleter_config import AutocompleterConfig +from cmk.gui.utils.speaklater import LazyString +from cmk.gui.valuespec import AutocompleterRegistry, DualListChoice + +from .filter import Filter, FilterRegistry + + +def register( + filter_registry: FilterRegistry, + autocompleter_registry: AutocompleterRegistry, + site_choices: Callable[[], list[tuple[str, str]]], + site_filter_heading_info: Callable[[FilterHTTPVariables], str | None], +) -> None: + filter_registry.register( + SiteFilter( + title=_l("Site"), + sort_index=500, + query_filter=query_filters.Query( + ident="siteopt", + request_vars=["site"], + ), + description=_l("Optional selection of a site"), + heading_info=site_filter_heading_info, + ) + ) + + filter_registry.register( + SiteFilter( + title=_l("Site (enforced)"), + sort_index=501, + query_filter=query_filters.Query(ident="site", request_vars=["site"]), + description=_l("Selection of site is enforced, use this filter for joining"), + is_show_more=True, + heading_info=site_filter_heading_info, + ) + ) + + filter_registry.register(MultipleSitesFilter(site_choices, site_filter_heading_info)) + + autocompleter_registry.register_autocompleter( + "sites", partial(sites_autocompleter, sites_options=site_choices) + ) + + +class SiteFilter(Filter): + def __init__( + self, + *, + title: str | LazyString, + sort_index: int, + query_filter: query_filters.Query, + description: None | str | LazyString = None, + is_show_more: bool = False, + heading_info: Callable[[FilterHTTPVariables], str | None], + ) -> None: + super().__init__( + ident=query_filter.ident, + title=title, + sort_index=sort_index, + info="host", + htmlvars=query_filter.request_vars, + link_columns=[], + description=description, + is_show_more=is_show_more, + ) + self.query_filter = query_filter + self._heading_info = heading_info + + def display(self, value: FilterHTTPVariables) -> None: + current_value = value.get(self.query_filter.request_vars[0], "") + choices = [(current_value, current_value)] if current_value else [] + + html.dropdown( + self.query_filter.request_vars[0], + choices, + current_value, + style="width: 250px;", + class_=["ajax-vals"], + data_autocompleter=json.dumps( + AutocompleterConfig( + ident="sites", + strict=self.query_filter.ident == "site", + ).config + ), + ) + + def heading_info(self, value: FilterHTTPVariables) -> str | None: + return self._heading_info(value) + + def request_vars_from_row(self, row: Row) -> dict[str, str]: + return {"site": row["site"]} + + +def default_site_filter_heading_info(value: FilterHTTPVariables) -> str | None: + current_value = value.get("site") + return ( + get_site_config(active_config, livestatus.SiteId(current_value))["alias"] + if current_value + else None + ) + + +class MultipleSitesFilter(SiteFilter): + def __init__( + self, + site_choices: Callable[[], list[tuple[str, str]]], + heading_info: Callable[[FilterHTTPVariables], str | None], + ) -> None: + super().__init__( + title=_l("Multiple sites"), + sort_index=502, + query_filter=query_filters.Query(ident="sites", request_vars=["sites"]), + description=_l("Associative selection of multiple sites"), + heading_info=heading_info, + ) + self._site_choices = site_choices + + def get_request_sites(self, value: FilterHTTPVariables) -> list[str]: + return [x for x in value.get(self.htmlvars[0], "").strip().split("|") if x] + + def display(self, value: FilterHTTPVariables) -> None: + sites_vs = DualListChoice(choices=self._site_choices(), rows=4) + sites_vs.render_input(self.htmlvars[0], self.get_request_sites(value)) + + +def sites_autocompleter( + value: str, params: dict, sites_options: Callable[[], list[tuple[str, str]]] +) -> Choices: + """Return the matching list of dropdown choices + Called by the webservice with the current input field value and the completions_params to get the list of choices + """ + + choices: Choices = [v for v in sites_options() if _matches_id_or_title(value, v)] + + # This part should not exists as the optional(not enforce) would better be not having the filter at all + if not params.get("strict"): + empty_choice: Choices = [("", "All Sites")] + choices = empty_choice + choices + return choices + + +def _matches_id_or_title(ident: str, choice: tuple[str | None, str]) -> bool: + return ident.lower() in (choice[0] or "").lower() or ident.lower() in choice[1].lower() diff --git a/cmk/gui/wato/__init__.py b/cmk/gui/wato/__init__.py index 3cc84627b05..9dab5f492e9 100644 --- a/cmk/gui/wato/__init__.py +++ b/cmk/gui/wato/__init__.py @@ -165,6 +165,7 @@ from .pages._simple_modes import SimpleListMode as SimpleListMode from .pages._simple_modes import SimpleModeType as SimpleModeType from .pages._tile_menu import TileMenuRenderer as TileMenuRenderer +from .pages.user_profile.mega_menu import default_user_menu_topics as default_user_menu_topics # Has to be kept for compatibility with pre 1.6 register_rule() and register_check_parameters() # calls in the Setup plug-in context diff --git a/cmk/gui/wato/_main_module_topics.py b/cmk/gui/wato/_main_module_topics.py index 8921610736c..5de70544183 100644 --- a/cmk/gui/wato/_main_module_topics.py +++ b/cmk/gui/wato/_main_module_topics.py @@ -22,14 +22,6 @@ def register(main_module_topic_registry: MainModuleTopicRegistry) -> None: main_module_topic_registry.register(MainModuleTopicExporter) -MainModuleTopicQuickSetup = MainModuleTopic( - name="quick_setups", - title=_l("Quick Setup"), - icon_name="topic_quick_setups", - sort_index=1, -) - - MainModuleTopicHosts = MainModuleTopic( name="hosts", title=_l("Hosts"), @@ -51,6 +43,13 @@ def register(main_module_topic_registry: MainModuleTopicRegistry) -> None: sort_index=40, ) +MainModuleTopicQuickSetup = MainModuleTopic( + name="quick_setups", + title=_l("Quick Setup"), + icon_name="topic_quick_setups", + sort_index=45, +) + MainModuleTopicEvents = MainModuleTopic( name="events", title=_l("Events"), diff --git a/cmk/gui/wato/_notification_parameter/_base.py b/cmk/gui/wato/_notification_parameter/_base.py index 25cfc8fb45c..d231fd8280c 100644 --- a/cmk/gui/wato/_notification_parameter/_base.py +++ b/cmk/gui/wato/_notification_parameter/_base.py @@ -5,7 +5,10 @@ from abc import ABC, abstractmethod -from cmk.gui.valuespec import Dictionary +from cmk.gui.form_specs.private.dictionary_extended import DictionaryExtended +from cmk.gui.valuespec import Dictionary as ValueSpecDictionary + +from cmk.rulesets.v1.form_specs import Dictionary class NotificationParameter(ABC): @@ -16,5 +19,8 @@ def ident(self) -> str: @property @abstractmethod - def spec(self) -> Dictionary: + def spec(self) -> ValueSpecDictionary: + raise NotImplementedError() + + def _form_spec(self) -> DictionaryExtended | Dictionary: raise NotImplementedError() diff --git a/cmk/gui/wato/_notification_parameter/_helpers.py b/cmk/gui/wato/_notification_parameter/_helpers.py index 757ef079267..9d6d6ce6269 100644 --- a/cmk/gui/wato/_notification_parameter/_helpers.py +++ b/cmk/gui/wato/_notification_parameter/_helpers.py @@ -4,12 +4,25 @@ # conditions defined in the file COPYING, which is part of this source code package. import socket +from typing import Any from cmk.ccc.site import url_prefix from cmk.gui.i18n import _ from cmk.gui.valuespec import CascadingDropdown, DEF_VALUE, TextInput, Transform +from cmk.rulesets.v1 import Help, Title +from cmk.rulesets.v1.form_specs import ( + CascadingSingleChoice, + CascadingSingleChoiceElement, + DefaultValue, + DictElement, + DictGroup, + FixedValue, + String, +) +from cmk.rulesets.v1.form_specs.validators import Url, UrlProtocol + def notification_macro_help() -> str: return _( @@ -91,3 +104,65 @@ def _transform_to_valuespec_html_mail_url_prefix(p): return f"{k}_{v}" return ("manual", v) + + +def _get_url_prefix_setting( + is_cse: bool = False, default_value: str = "automatic_https", group_title: str | None = None +) -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("%s") % group_title if group_title else None, + ), + parameter_form=CascadingSingleChoice( + title=Title("URL prefix for links to Checkmk"), + help_text=Help( + "If you use Automatic HTTP/s, the URL prefix for " + "host and service links within the notification is filled " + "automatically. If you specify an URL prefix here, then " + "several parts of the notification are armed with hyperlinks " + "to your Checkmk GUI. In both cases, the recipient of the " + "notification can directly visit the host or service in " + "question in Checkmk. Specify an absolute URL including the " + ".../check_mk/." + ), + elements=[ + CascadingSingleChoiceElement( + name="automatic_http", + title=Title("Automatic HTTP"), + parameter_form=FixedValue( + value=None, + ), + ), + CascadingSingleChoiceElement( + name="automatic_https", + title=Title("Automatic HTTPs"), + parameter_form=FixedValue( + value=None, + ), + ), + CascadingSingleChoiceElement( + name="manual", + title=Title("Specify URL prefix"), + parameter_form=String( + prefill=DefaultValue(local_site_url()), + custom_validate=[Url([UrlProtocol.HTTP, UrlProtocol.HTTPS])], + ), + ), + ], + migrate=_migrate_html_mail_url_prefix, + prefill=DefaultValue(default_value), + ), + render_only=is_cse, + ) + + +def _migrate_html_mail_url_prefix(p: object) -> tuple[str, str | None]: + if isinstance(p, tuple): + return p + if isinstance(p, dict): + for key, value in p.items(): + if key == "manual": + return (key, value) + return (f"{key}_{value}", None) + + raise ValueError(f"Invalid format for URL prefix: {p}") diff --git a/cmk/gui/wato/_notification_parameter/_ilert.py b/cmk/gui/wato/_notification_parameter/_ilert.py index 7a8ee72911e..166af18bc6e 100644 --- a/cmk/gui/wato/_notification_parameter/_ilert.py +++ b/cmk/gui/wato/_notification_parameter/_ilert.py @@ -3,13 +3,30 @@ # 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.valuespec import CascadingDropdown, Dictionary, DropdownChoice, FixedValue, TextInput -from cmk.gui.wato import HTTPProxyReference -from cmk.gui.watolib.password_store import passwordstore_choices +from typing import Literal + +import cmk.utils.password_store as password_store + +from cmk.gui.form_specs.vue.visitors.recomposers.unknown_form_spec import recompose +from cmk.gui.valuespec import Dictionary as ValueSpecDictionary + +from cmk.rulesets.v1 import Help, Label, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + FieldSize, + FixedValue, + InputHint, + Password, + Proxy, + SingleChoice, + SingleChoiceElement, + String, +) from ._base import NotificationParameter -from ._helpers import get_url_prefix_specs, local_site_url +from ._helpers import _get_url_prefix_setting class NotificationParameterILert(NotificationParameter): @@ -18,73 +35,99 @@ def ident(self) -> str: return "ilert" @property - def spec(self) -> Dictionary: + def spec(self) -> ValueSpecDictionary: + # TODO needed because of mixed Form Spec and old style setup + return recompose(self._form_spec()).valuespec # type: ignore[return-value] # expects Valuespec[Any] + + def _form_spec(self) -> Dictionary: return Dictionary( - title=_("Create notification with the following parameters"), - optional_keys=["ignore_ssl", "proxy_url"], - elements=[ - ( - "ilert_api_key", - CascadingDropdown( - title=_("iLert alert source API key"), - help=_("API key for iLert alert server"), - choices=[ - ( - "ilert_api_key", - _("API key"), - TextInput(size=80, allow_empty=False), - ), - ( - "store", - _("API key from password store"), - DropdownChoice(sorted=True, choices=passwordstore_choices), - ), - ], + # optional_keys=["ignore_ssl", "proxy_url"], + title=Title("Create notification with the following parameters"), + elements={ + "ilert_api_key": DictElement( + parameter_form=Password( + title=Title("iLert alert source API key"), + help_text=Help("API key for iLert alert server"), + migrate=_migrate_to_password, ), + required=True, ), - ( - "ignore_ssl", - FixedValue( + "ignore_ssl": DictElement( + parameter_form=FixedValue( value=True, - title=_("Disable SSL certificate verification"), - totext=_("Disable SSL certificate verification"), - help=_("Ignore unverified HTTPS request warnings. Use with caution."), - ), - ), - ("proxy_url", HTTPProxyReference()), - ( - "ilert_priority", - DropdownChoice( - sorted=True, - choices=[ - ("HIGH", _("High (with escalation)")), - ("LOW", _("Low (without escalation")), - ], - title=_( - "Notification priority (This will override the priority configured in the alert source)" + title=Title("Disable SSL certificate verification"), + label=Label("Disable SSL certificate verification"), + help_text=Help( + "Ignore unverified HTTPS request warnings. Use with caution." ), - default_value="HIGH", ), ), - ( - "ilert_summary_host", - TextInput( - title=_("Custom incident summary for host alerts"), - default_value="$NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ - $HOSTOUTPUT$", - size=64, - ), + "proxy_url": DictElement( + parameter_form=Proxy(), ), - ( - "ilert_summary_service", - TextInput( - title=_("Custom incident summary for service alerts"), - default_value="$NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ - $SERVICEOUTPUT$", - size=64, - ), + "ilert_priority": DictElement( + parameter_form=SingleChoice( + title=Title( + "Notification priority (This will override the " + "priority configured in the alert source)" + ), + prefill=DefaultValue("HIGH"), + elements=[ + SingleChoiceElement( + name="HIGH", + title=Title("High (with escalation)"), + ), + SingleChoiceElement( + name="LOW", + title=Title("Low (without escalation"), + ), + ], + ) + ), + "ilert_summary_host": DictElement( + parameter_form=String( + title=Title("Custom incident summary for host alerts"), + prefill=InputHint( + "$NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is " + "$HOSTSTATE$ - $HOSTOUTPUT$" + ), + field_size=FieldSize.LARGE, + ) ), - ( - "url_prefix", - get_url_prefix_specs(local_site_url, default_value="automatic_https"), + "ilert_summary_service": DictElement( + parameter_form=String( + title=Title("Custom incident summary for service alerts"), + prefill=InputHint( + "$NOTIFICATIONTYPE$ Service Alert: " + "$HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ - " + "$SERVICEOUTPUT$" + ), + field_size=FieldSize.LARGE, + ) ), - ], + "url_prefix": _get_url_prefix_setting(), + }, ) + + +def _migrate_to_password( + password: object, +) -> tuple[ + Literal["cmk_postprocessed"], Literal["explicit_password", "stored_password"], tuple[str, str] +]: + if isinstance(password, tuple): + if password[0] == "store": + return ("cmk_postprocessed", "stored_password", (password[1], "")) + + if password[0] == "ilert_api_key": + return ( + "cmk_postprocessed", + "explicit_password", + (password_store.ad_hoc_password_id(), password[1]), + ) + + # Already migrated + assert len(password) == 3 + return password + + raise ValueError(f"Invalid password format: {password}") diff --git a/cmk/gui/wato/_notification_parameter/_mail.py b/cmk/gui/wato/_notification_parameter/_mail.py index a58e9a411fe..ec6d8305666 100644 --- a/cmk/gui/wato/_notification_parameter/_mail.py +++ b/cmk/gui/wato/_notification_parameter/_mail.py @@ -3,28 +3,38 @@ # 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 Sequence +from collections.abc import Mapping +from typing import Any from cmk.ccc.version import Edition, edition from cmk.utils import paths +from cmk.gui.form_specs.private.dictionary_extended import DictionaryExtended +from cmk.gui.form_specs.vue.visitors.recomposers.unknown_form_spec import recompose from cmk.gui.http import request -from cmk.gui.i18n import _ -from cmk.gui.valuespec import ( +from cmk.gui.valuespec.definitions import Dictionary as ValueSpecDictionary + +from cmk.rulesets.v1 import Help, Label, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + DictGroup, Dictionary, - DictionaryEntry, - DropdownChoice, - EmailAddress, + FieldSize, FixedValue, Integer, - ListChoice, - TextAreaUnicode, - TextInput, + MultilineText, + MultipleChoice, + MultipleChoiceElement, + SingleChoice, + SingleChoiceElement, + String, ) +from cmk.rulesets.v1.form_specs.validators import EmailAddress as ValidateEmailAddress from ._base import NotificationParameter -from ._helpers import get_url_prefix_specs, local_site_url +from ._helpers import _get_url_prefix_setting class NotificationParameterMail(NotificationParameter): @@ -33,106 +43,38 @@ def ident(self) -> str: return "mail" @property - def spec(self) -> Dictionary: - return Dictionary( - title=_("Create notification with the following parameters"), + def spec(self) -> ValueSpecDictionary: + # TODO needed because of mixed Form Spec and old style setup + return recompose(self._form_spec()).valuespec # type: ignore[return-value] # expects Valuespec[Any] + + def _form_spec(self) -> DictionaryExtended: + # TODO register CSE specific version + return DictionaryExtended( + title=Title("HTML Email parameters"), # must be called at run time!! - elements=self._parameter_elements, - hidden_keys=( - ["from", "url_prefix", "disable_multiplexing", "smtp"] - if edition(paths.omd_root) == Edition.CSE - else [] - ), + elements=self._parameter_elements(is_cse=edition(paths.omd_root) == Edition.CSE), ) - def _parameter_elements(self) -> list[DictionaryEntry]: - return _vs_add_common_mail_elements( - [ - ( - "elements", - ListChoice( - title=_("Display additional information"), - choices=[ - ("omdsite", _("Site ID")), - ("hosttags", _("Tags of the host")), - ("address", _("IP address of host")), - ("abstime", _("Absolute time of alert")), - ("reltime", _("Relative time of alert")), - ("longoutput", _("Additional plug-in output")), - ("ack_author", _("Acknowledgement author")), - ("ack_comment", _("Acknowledgement comment")), - ("notification_author", _("Notification author")), - ("notification_comment", _("Notification comment")), - ("perfdata", _("Metrics")), - ("graph", _("Time series graph")), - ("notesurl", _("Custom host/service notes URL")), - ("context", _("Complete variable list (for testing)")), - ], - default_value=["graph", "abstime", "address", "longoutput"], - ), - ), - ( - "insert_html_section", - TextAreaUnicode( - title=_("Add HTML section above table (e.g. title, description…)"), - default_value="CONTENT", - cols=76, - rows=3, - ), - ), - ( - "url_prefix", - get_url_prefix_specs( - local_site_url, - "automatic_https" if request.is_ssl_request else "automatic_http", - ), - ), - ( - "no_floating_graphs", - FixedValue( - value=True, - title=_("Display graphs among each other"), - totext=_("Graphs are shown among each other"), - help=_( - "By default all multiple graphs in emails are displayed floating " - "nearby. You can enable this option to show the graphs among each " - "other." - ), - ), - ), - ( - "graphs_per_notification", - Integer( - title=_("Graphs per notification (default: 5)"), - label=_("Show up to"), - unit=_("graphs"), - help=_( - "Sets a limit for the number of graphs that are displayed in a notification." - ), - default_value=5, - minvalue=0, - ), - ), - ( - "notifications_with_graphs", - Integer( - title=_("Bulk notifications with graphs (default: 5)"), - label=_("Show graphs for the first"), - unit=_("Notifications"), - help=_( - "Sets a limit for the number of notifications in a bulk for which graphs " - "are displayed. If you do not use bulk notifications this option is ignored. " - "Note that each graph increases the size of the mail and takes time to render" - "on the monitoring server. Therefore, large bulks may exceed the maximum " - "size for attachements or the plug-in may run into a timeout so that a failed " - "notification is produced." - ), - default_value=5, - minvalue=0, - ), - ), - ] - ) + def _parameter_elements(self, is_cse: bool) -> dict[str, DictElement[Any]]: + return { + **self._settings_elements(is_cse), + **_header_elements(is_cse), + **_content_elements(), + **_testing_elements(), + **_bulk_elements(), + } + + def _settings_elements(self, is_cse: bool) -> dict[str, DictElement[Any]]: + return self._url_prefix_setting(is_cse) + + def _url_prefix_setting(self, is_cse: bool) -> dict[str, DictElement[Any]]: + return { + "url_prefix": _get_url_prefix_setting( + is_cse, + default_value="automatic_https" if request.is_ssl_request else "automatic_http", + group_title="Settings", + ) + } class NotificationParameterASCIIMail(NotificationParameter): @@ -141,182 +83,386 @@ def ident(self) -> str: return "asciimail" @property - def spec(self) -> Dictionary: - elements = _vs_add_common_mail_elements( - [ - ( - "common_body", - TextAreaUnicode( - title=_("Body head for both host and service notifications"), - rows=7, - cols=58, - monospaced=True, - default_value="""Host: $HOSTNAME$ + def spec(self) -> ValueSpecDictionary: + # TODO needed because of mixed Form Spec and old style setup + # return recompose(self._form_spec()).valuespec # type: ignore[return-value] + return recompose(self._form_spec()).valuespec # type: ignore[return-value] + + def _form_spec(self) -> DictionaryExtended: + return DictionaryExtended( + title=Title("Create notification with the following parameters"), + elements=_elements_ascii(is_cse=edition(paths.omd_root) == Edition.CSE), + ) + + +def _elements_ascii(is_cse: bool) -> Mapping[str, DictElement[Any]]: + elements = { + "from": _from_address_element(is_cse), + "reply_to": _reply_to(), + "host_subject": _host_subject(), + "service_subject": _service_subject(), + "common_body": DictElement( + parameter_form=MultilineText( + title=Title("Body head for both host and service notifications"), + prefill=DefaultValue( + """Host: $HOSTNAME$ Alias: $HOSTALIAS$ Address: $HOSTADDRESS$ -""", - ), +""" ), - ( - "host_body", - TextAreaUnicode( - title=_("Body tail for host notifications"), - rows=9, - cols=58, - monospaced=True, - default_value="""Event: $EVENT_TXT$ + macro_support=True, + ), + ), + "host_body": DictElement( + parameter_form=MultilineText( + title=Title("Body tail for host notifications"), + prefill=DefaultValue( + """Event: $EVENT_TXT$ Output: $HOSTOUTPUT$ Perfdata: $HOSTPERFDATA$ $LONGHOSTOUTPUT$ -""", - ), +""" ), - ( - "service_body", - TextAreaUnicode( - title=_("Body tail for service notifications"), - rows=11, - cols=58, - monospaced=True, - default_value="""Service: $SERVICEDESC$ -Event: $EVENT_TXT$ -Output: $SERVICEOUTPUT$ -Perfdata: $SERVICEPERFDATA$ -$LONGSERVICEOUTPUT$ -""", - ), + macro_support=True, + ), + ), + "service_body": DictElement( + parameter_form=MultilineText( + title=Title("Body tail for service notifications"), + prefill=DefaultValue( + """Service: $SERVICEDESC$ ++ Event: $EVENT_TXT$ ++ Output: $SERVICEOUTPUT$ ++ Perfdata: $SERVICEPERFDATA$ ++ $LONGSERVICEOUTPUT$ +""" ), - ] - ) - return Dictionary( - title=_("Create notification with the following parameters"), - elements=elements, - hidden_keys=( - ["from", "disable_multiplexing"] if edition(paths.omd_root) == Edition.CSE else [] + macro_support=True, ), - ) + ), + "bulk_sort_order": _bulk_sort_order(), + "disable_multiplexing": _disable_multiplexing(is_cse), + } + return elements -def _vs_add_common_mail_elements(elements: Sequence[DictionaryEntry]) -> list[DictionaryEntry]: - header: list[DictionaryEntry] = [ - ( - "from", - Dictionary( - title="From", - elements=[ - ( - "address", - EmailAddress( - title=_("Email address"), - size=73, - allow_empty=False, - ), - ), - ( - "display_name", - TextInput( - title=_("Display name"), - size=73, - allow_empty=False, - ), - ), - ], - help=_( - "The email address and visible name used in the From header " - "of notifications messages. If no email address is specified " - "the default address is OMD_SITE@FQDN is used. If the " - "environment variable OMD_SITE is not set it defaults " - "to checkmk." - ), + +def _header_elements(is_cse: bool) -> dict[str, DictElement[Any]]: + return { + "from": _from_address_element(is_cse), + "reply_to": _reply_to(), + "disable_multiplexing": _disable_multiplexing(is_cse), + "host_subject": _host_subject(), + "service_subject": _service_subject(), + } + + +def _content_elements() -> dict[str, DictElement[Any]]: + return { + "insert_html_section": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=MultilineText( + title=Title("Custom HTML section (e.g. title, description…)"), + prefill=DefaultValue("CONTENT"), + macro_support=True, ), ), - ( - "reply_to", - Dictionary( - title="Reply to", + # TODO should be old ListChoice style + "elements": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=MultipleChoice( + title=Title("Additional details"), elements=[ - ( - "address", - EmailAddress( - title=_("Email address"), - size=73, - allow_empty=False, - ), + MultipleChoiceElement( + name="omdsite", + title=Title("Site ID"), + ), + MultipleChoiceElement( + name="address", + title=Title("IP Address of Hosts"), ), - ( - "display_name", - TextInput( - title=_("Display name"), - size=73, - allow_empty=False, - ), + MultipleChoiceElement( + name="abstime", + title=Title("Absolute time of alert"), + ), + MultipleChoiceElement( + name="reltime", + title=Title("Relative time of alert"), + ), + MultipleChoiceElement( + name="longoutput", + title=Title("Plugin output"), + ), + MultipleChoiceElement( + name="ack_author", + title=Title("Acknowledgment author"), + ), + MultipleChoiceElement( + name="ack_comment", + title=Title("Acknowledgement comment"), + ), + MultipleChoiceElement( + name="perfdata", + title=Title("Metrics"), + ), + MultipleChoiceElement( + name="graph", + title=Title("Time series graph"), + ), + MultipleChoiceElement( + name="notesurl", + title=Title("Custom host/service notes URL"), + ), + MultipleChoiceElement( + name="context", + title=Title("Complete variable list"), ), ], - required_keys=["address"], - help=_( - "The email address and visible name used in the Reply-To header " - "of notifications messages." - ), + prefill=DefaultValue(["abstime", "longoutput", "graph"]), ), ), - ( - "host_subject", - TextInput( - title=_("Subject for host notifications"), - help=_( - "Here you are allowed to use all macros that are defined in the " - "notification context." - ), - default_value="Check_MK: $HOSTNAME$ - $EVENT_TXT$", - size=76, + "contact_groups": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=FixedValue( + title=Title("Show contact groups"), + value=True, ), ), - ( - "service_subject", - TextInput( - title=_("Subject for service notifications"), - help=_( - "Here you are allowed to use all macros that are defined in the " - "notification context." + "svc_labels": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=FixedValue( + title=Title("Show service labels"), + value=True, + ), + ), + "host_labels": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=FixedValue( + title=Title("Show host labels"), + value=True, + ), + ), + "host_tags": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=FixedValue( + title=Title("Show host tags"), + value=True, + ), + ), + "graphs_per_notification": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=Integer( + title=Title("Number of graphs per notification (default: 5)"), + label=Label("Show up to"), + unit_symbol="graphs", + prefill=DefaultValue(5), + help_text=Help( + "Sets a limit for the number of " + "graphs that are displayed in " + "a notification." ), - default_value="Check_MK: $HOSTNAME$/$SERVICEDESC$ $EVENT_TXT$", - size=76, ), ), - ] - - footer: list[DictionaryEntry] = [ - ( - "bulk_sort_order", - DropdownChoice( - choices=[ - ("oldest_first", _("Oldest first")), - ("newest_first", _("Newest first")), - ], - help=_( - "With this option you can specify, whether the oldest (default) or " - "the newest notification should get shown at the top of the notification mail." + "no_floating_graphs": DictElement( + group=DictGroup( + title=Title("Email body/content"), + ), + parameter_form=FixedValue( + value=True, + ), + render_only=True, + ), + } + + +def _bulk_elements() -> dict[str, DictElement[Any]]: + return { + "bulk_sort_order": _bulk_sort_order(), + "notifications_with_graphs": DictElement( + group=DictGroup( + title=Title("Bulk notifications"), + ), + parameter_form=Integer( + title=Title("Number of graphs per event (default: 5)"), + label=Label("Show graphs for the first"), + unit_symbol="notifications", + prefill=DefaultValue(5), + help_text=Help( + "Sets a limit for the number of notifications in a bulk for " + "which graphs are displayed. If you do not use bulk " + "notifications this option is ignored. Note that each graph " + "increases the size of the mail and takes time to render on " + "the monitoring server. Therefore, large bulks may exceed " + "the maximum size for attachements or the plug-in may run " + "into a timeout so that a failed notification is produced." ), - title=_("Notification sort order for bulk notifications"), - default_value="oldest_first", ), ), - ( - "disable_multiplexing", - FixedValue( + } + + +def _testing_elements() -> dict[str, DictElement[Any]]: + return { + "notification_rule": DictElement( + group=DictGroup( + title=Title("Troubleshooting/testing settings"), + ), + parameter_form=FixedValue( + title=Title("Show notification rule that triggered the notification"), value=True, - title=_("Send separate notifications to every recipient"), - totext=_( - "A separate notification is send to every recipient. Recipients " - "cannot see which other recipients were notified." + ), + ), + } + + +def _from_address_element(is_cse: bool) -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Email header"), + ), + parameter_form=Dictionary( + title=Title('Custom sender ("From")'), + elements={ + "address": DictElement( + parameter_form=String( + title=Title("Email address"), + custom_validate=[ValidateEmailAddress()], + ), ), - help=_( - "Per default only one notification is generated for all recipients. " - "Therefore, all recipients can see who was notified and reply to " - "all other recipients." + "display_name": DictElement( + parameter_form=String( + title=Title("Display name"), + ), + ), + }, + ), + render_only=is_cse, + ) + + +def _reply_to() -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Email header"), + ), + parameter_form=Dictionary( + title=Title('Custom recipient of "Reply to"'), + elements={ + "address": DictElement( + parameter_form=String( + title=Title("Email address"), + custom_validate=[ValidateEmailAddress()], + ), + required=True, ), + "display_name": DictElement( + parameter_form=String( + title=Title("Display name"), + ), + ), + }, + ), + ) + + +def _disable_multiplexing(is_cse: bool) -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Email header"), + ), + parameter_form=FixedValue( + title=Title("Hide other recipients: Send individual notifications to each recipient"), + help_text=Help( + "Per default only " + "one notification is generated " + "for all recipients. Therefore, " + "all recipients can see who was " + "notified and reply to all other " + "recipients." + ), + value=True, + label=Label( + "A separate notification is " + "send to every recipient. Recipients " + "cannot see which other recipients " + "were notified." ), ), - ] + render_only=is_cse, + ) - return header + list(elements) + footer + +def _host_subject() -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Email header"), + ), + parameter_form=String( + title=Title("Subject line for host notifications"), + help_text=Help( + "Here you are allowed to use " + "all macros that are defined in " + "the notification context." + ), + prefill=DefaultValue("Check_MK: $HOSTNAME$ - $EVENT_TXT$"), + field_size=FieldSize.LARGE, + macro_support=True, + ), + ) + + +def _service_subject() -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Email header"), + ), + parameter_form=String( + title=Title("Subject line for service notifications"), + help_text=Help( + "Here you are allowed to use " + "all macros that are defined in " + "the notification context." + ), + prefill=DefaultValue("Check_MK: $HOSTNAME$/$SERVICEDESC$ $EVENT_TXT$"), + field_size=FieldSize.LARGE, + macro_support=True, + ), + ) + + +def _bulk_sort_order() -> DictElement[Any]: + return DictElement( + group=DictGroup( + title=Title("Bulk notifications"), + ), + parameter_form=SingleChoice( + title=Title("Notification sort order for bulk notifications"), + elements=[ + SingleChoiceElement(name="oldest_first", title=Title("Oldest first")), + SingleChoiceElement(name="newest_first", title=Title("Newest first")), + ], + help_text=Help( + "With this option you can " + "specify, whether the oldest " + "(default) or the newest " + "notification should get shown " + "at the top of the notification " + "mail." + ), + prefill=DefaultValue("oldest_first"), + ), + ) diff --git a/cmk/gui/wato/_notification_parameter/_registry.py b/cmk/gui/wato/_notification_parameter/_registry.py index e66aa48a95e..82c9c2744c5 100644 --- a/cmk/gui/wato/_notification_parameter/_registry.py +++ b/cmk/gui/wato/_notification_parameter/_registry.py @@ -5,15 +5,24 @@ # pylint: disable=protected-access +from cmk.ccc.i18n import _ from cmk.ccc.plugin_registry import Registry +from cmk.ccc.version import edition +from cmk.utils.paths import omd_root from cmk.utils.rulesets.definition import RuleGroup +import cmk.gui.rulespec as _rulespec import cmk.gui.watolib.rulespecs as _rulespecs -from cmk.gui.i18n import _ +from cmk.gui.exceptions import MKUserError +from cmk.gui.form_specs.private import Catalog, CommentTextArea, not_empty, Topic +from cmk.gui.utils.rule_specs.loader import LoadedRuleSpec from cmk.gui.watolib.rulespec_groups import RulespecGroupMonitoringConfigurationNotifications from cmk.gui.watolib.users import notification_script_title +from cmk.rulesets.v1 import Help, rule_specs, Title +from cmk.rulesets.v1.form_specs import DictElement, Dictionary, FieldSize, String + from ._base import NotificationParameter @@ -26,19 +35,91 @@ def plugin_name(self, instance): def registration_hook(self, instance): plugin = instance() - script_title = notification_script_title(plugin.ident) + # TODO Add FormSpec converted plugins here, remove else if all are converted + if plugin.ident in ["mail"]: + loaded_rulespec = rule_specs.NotificationParameters( + title=Title("%s") % notification_script_title(plugin.ident), + name=plugin.ident, + topic=rule_specs.Topic.NOTIFICATIONS, + parameter_form=plugin._form_spec, + ) + _rulespec.register_plugins( + [LoadedRuleSpec(rule_spec=loaded_rulespec, edition_only=edition(omd_root))] + ) + else: + _rulespecs.rulespec_registry.register( + _rulespecs.HostRulespec( + name=RuleGroup.NotificationParameters(plugin.ident), + title=lambda: notification_script_title(plugin.ident), + group=RulespecGroupMonitoringConfigurationNotifications, + valuespec=lambda: plugin.spec, + match_type="dict", + ) + ) - valuespec = plugin.spec - # TODO: Cleanup this hack - valuespec._title = _("Call with the following parameters:") + def form_spec(self, method: str) -> Catalog: + try: + param_form_spec = self._entries[method]()._form_spec() + except KeyError: + raise MKUserError(None, _("No notification parameters for method '%s' found") % method) + except NotImplementedError: + raise MKUserError( + None, + _("No FormSpec implementation for method '%s' found.") % method, + ) - _rulespecs.register_rule( - RulespecGroupMonitoringConfigurationNotifications, - RuleGroup.NotificationParameters(plugin.ident), - valuespec, - _("Parameters for %s") % script_title, - itemtype=None, - match="dict", + return Catalog( + topics=[ + Topic( + ident="general", + dictionary=Dictionary( + title=Title("Parameter properties"), + elements={ + "description": DictElement( + parameter_form=String( + title=Title("Description"), + field_size=FieldSize.LARGE, + custom_validate=[not_empty()], + ), + required=True, + ), + "comment": DictElement( + parameter_form=CommentTextArea( + title=Title("Comment"), + ) + ), + "docu_url": DictElement( + parameter_form=String( + title=Title("Documentation URL"), + help_text=Help( + ( + "An optional URL pointing to documentation or any other page. This will be " + "displayed as an icon and open " + "a new page when clicked. You can use either global URLs (beginning with " + "http://), absolute local urls (beginning with /) or relative " + "URLs (that are relative to check_mk/)." + ) + ), + ) + ), + }, + ), + ), + Topic( + ident="parameter_properties", + # TODO if sections are not rendered by fixed DictGroup(), + # we will need this: + # dictionary=FormSpecDictionary( + # title=Title("Parameter properties"), + # elements={ + # "properties": DictElement( + # parameter_form=param_form_spec, + # ) + # }, + # ), + dictionary=param_form_spec, + ), + ] ) diff --git a/cmk/gui/wato/_omd_configuration.py b/cmk/gui/wato/_omd_configuration.py index 0a66587052f..30a80b92d2f 100644 --- a/cmk/gui/wato/_omd_configuration.py +++ b/cmk/gui/wato/_omd_configuration.py @@ -32,7 +32,6 @@ Tuple, ValueSpec, ) -from cmk.gui.watolib.activate_changes import add_replication_paths from cmk.gui.watolib.config_domain_name import ( ABCConfigDomain, ConfigDomainName, @@ -44,12 +43,14 @@ wato_fileheader, ) from cmk.gui.watolib.config_domains import ConfigDomainOMD -from cmk.gui.watolib.config_sync import ReplicationPath +from cmk.gui.watolib.config_sync import ReplicationPath, ReplicationPathRegistry from cmk.gui.watolib.config_variable_groups import ConfigVariableGroupSiteManagement def register( - config_domain_registry: ConfigDomainRegistry, config_variable_registry: ConfigVariableRegistry + config_domain_registry: ConfigDomainRegistry, + config_variable_registry: ConfigVariableRegistry, + replication_path_registry: ReplicationPathRegistry, ) -> None: config_domain_registry.register(ConfigDomainDiskspace) config_domain_registry.register(ConfigDomainApache) @@ -60,6 +61,14 @@ def register( config_variable_registry.register(ConfigVariableSiteDiskspaceCleanup) config_variable_registry.register(ConfigVariableSiteApacheProcessTuning) config_variable_registry.register(ConfigVariableSiteRRDCachedTuning) + replication_path_registry.register( + ReplicationPath( + "file", + "diskspace", + str(ConfigDomainDiskspace.diskspace_config.relative_to(cmk.utils.paths.omd_root)), + [], + ) + ) # . @@ -395,17 +404,6 @@ def valuespec(self) -> ValueSpec: ) -add_replication_paths( - [ - ReplicationPath( - "file", - "diskspace", - str(ConfigDomainDiskspace.diskspace_config.relative_to(cmk.utils.paths.omd_root)), - [], - ), - ] -) - # . # .--Apache--------------------------------------------------------------. # | _ _ | diff --git a/cmk/gui/wato/pages/__init__.py b/cmk/gui/wato/pages/__init__.py index 1e4b5bf917c..36636f2e985 100644 --- a/cmk/gui/wato/pages/__init__.py +++ b/cmk/gui/wato/pages/__init__.py @@ -3,14 +3,17 @@ # 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.ccc.version import Edition, edition - -from cmk.utils import paths +from collections.abc import Callable from cmk.gui.background_job import BackgroundJobRegistry +from cmk.gui.main_menu import MegaMenuRegistry +from cmk.gui.page_menu import PageMenuDropdown from cmk.gui.pages import PageRegistry +from cmk.gui.quick_setup.v0_unstable._registry import QuickSetupRegistry +from cmk.gui.type_defs import TopicMenuTopic from cmk.gui.watolib.automation_commands import AutomationCommandRegistry from cmk.gui.watolib.mode import ModeRegistry +from cmk.gui.watolib.search import MatchItemGeneratorRegistry from . import ( activate_changes, @@ -66,8 +69,14 @@ def register( page_registry: PageRegistry, mode_registry: ModeRegistry, + quick_setup_registry: QuickSetupRegistry, automation_command_registry: AutomationCommandRegistry, job_registry: BackgroundJobRegistry, + match_item_generator_registry: MatchItemGeneratorRegistry, + mega_menu_registry: MegaMenuRegistry, + user_menu_topics: Callable[[], list[TopicMenuTopic]], + edition_supports_ldap: bool, + edition_supports_managing_roles: bool, ) -> None: activate_changes.register(page_registry, mode_registry, automation_command_registry) analyze_configuration.register(mode_registry) @@ -82,18 +91,18 @@ def register( download_agents.register(mode_registry) fetch_agent_output.register(page_registry, automation_command_registry, job_registry) folders.register(page_registry, mode_registry) - global_settings.register(mode_registry) + global_settings.register(mode_registry, match_item_generator_registry) groups.register(mode_registry) gui_timings.register(page_registry) host_diagnose.register(page_registry, mode_registry) host_rename.register(mode_registry) hosts.register(mode_registry) not_implemented.register(mode_registry) - notifications.register(mode_registry) + notifications.register(mode_registry, quick_setup_registry) object_parameters.register(mode_registry) parentscan.register(mode_registry) password_store.register(mode_registry) - pattern_editor.register(mode_registry) + pattern_editor.register(mode_registry, match_item_generator_registry) predefined_conditions.register(mode_registry) random_hosts.register(mode_registry) read_only.register(mode_registry) @@ -104,10 +113,11 @@ def register( tags.register(mode_registry) timeperiods.register(mode_registry) user_migrate.register(mode_registry) - user_profile.register(page_registry) + user_profile.register(page_registry, mega_menu_registry, user_menu_topics) users.register(mode_registry) certificate_overview.register(mode_registry) - if edition(paths.omd_root) is not Edition.CSE: # disabled in CSE + if edition_supports_ldap: ldap.register(mode_registry) + if edition_supports_managing_roles: roles.register(mode_registry) diff --git a/cmk/gui/wato/pages/_simple_modes.py b/cmk/gui/wato/pages/_simple_modes.py index d24b10bae5f..d33ccbc7244 100644 --- a/cmk/gui/wato/pages/_simple_modes.py +++ b/cmk/gui/wato/pages/_simple_modes.py @@ -13,17 +13,25 @@ import abc import copy +import json from collections.abc import Mapping from typing import Any, cast, Generic, TypeVar from livestatus import SiteId +from cmk.utils.urls import is_allowed_url + import cmk.gui.watolib.changes as _changes from cmk.gui import forms from cmk.gui.breadcrumb import Breadcrumb from cmk.gui.default_name import unique_default_name_suggestion from cmk.gui.exceptions import MKUserError -from cmk.gui.htmllib.html import html +from cmk.gui.form_specs.generators.setup_site_choice import create_setup_site_choice +from cmk.gui.form_specs.private import Catalog, CommentTextArea, LegacyValueSpec +from cmk.gui.form_specs.vue.form_spec_visitor import parse_data_from_frontend, render_form_spec +from cmk.gui.form_specs.vue.visitors import DataOrigin, DEFAULT_VALUE +from cmk.gui.form_specs.vue.visitors.catalog import Dict2CatalogConverter, Headers +from cmk.gui.htmllib.html import ExperimentalRenderMode, html from cmk.gui.http import request from cmk.gui.i18n import _ from cmk.gui.page_menu import ( @@ -50,17 +58,24 @@ FixedValue, ID, RuleComment, - SetupSiteChoice, TextInput, ValueSpec, ) +from cmk.gui.valuespec import SetupSiteChoice as VSSetupSiteChoice from cmk.gui.watolib.config_domain_name import ABCConfigDomain from cmk.gui.watolib.hosts_and_folders import make_action_link from cmk.gui.watolib.mode import mode_url, redirect, WatoMode from cmk.gui.watolib.simple_config_file import WatoSimpleConfigFile +from cmk.rulesets.v1 import form_specs, Help, Label, Message, Title +from cmk.rulesets.v1.form_specs import DictElement, FormSpec +from cmk.rulesets.v1.form_specs import Dictionary as FormSpecDictionary +from cmk.rulesets.v1.form_specs.validators import ValidationError + _T = TypeVar("_T", bound=Mapping[str, Any]) +DoValidate = bool + class SimpleModeType(Generic[_T], abc.ABC): @abc.abstractmethod @@ -80,8 +95,8 @@ def is_site_specific(self) -> bool: """ raise NotImplementedError() - def site_valuespec(self) -> DualListChoice | SetupSiteChoice: - return SetupSiteChoice() + def site_valuespec(self) -> DualListChoice | VSSetupSiteChoice: + return VSSetupSiteChoice() @abc.abstractmethod def can_be_disabled(self) -> bool: @@ -330,10 +345,18 @@ def _show_delete_action(self, nr: int, ident: str, entry: _T) -> None: class SimpleEditMode(_SimpleWatoModeBase[_T], abc.ABC): """Base class for edit modes""" - @abc.abstractmethod def _vs_individual_elements(self) -> list[DictionaryEntry]: raise NotImplementedError() + def _fs_individual_elements(self) -> dict[str, DictElement]: + raise NotImplementedError() + + def _individual_elements(self) -> dict[str, DictElement]: + return self._fs_individual_elements() + + def _fs_mandatory_elements(self) -> dict[str, DictElement]: + return self._fs_general_properties() + def from_vars(self, ident_var: str) -> None: self._from_vars(ident_var) @@ -372,10 +395,15 @@ def _from_vars(self, ident_var: str = "ident") -> None: self._new = True self._ident = None + self._entry = self._default_entry() def _clone_entry(self, entry: _T) -> _T: return copy.deepcopy(entry) + def _default_entry(self) -> _T: + # This is only relevant when rendering with form specs + return cast(_T, {}) + def title(self) -> str: if self._new: return _("Add %s") % self._mode_type.name_singular() @@ -386,6 +414,26 @@ def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: _("Actions"), breadcrumb, form_name="edit", button_name="_save" ) + def _get_catalog_converter( + self, + ) -> Dict2CatalogConverter: + general_elements = self._fs_mandatory_elements() + general_keys = general_elements.keys() + individual_elements = self._individual_elements() + individual_keys = individual_elements.keys() + headers: Headers = [ + (_("General properties"), list(general_keys)), + (_("%s properties") % self._mode_type.name_singular().title(), list(individual_keys)), + ] + return Dict2CatalogConverter.build_from_dictionary( + FormSpecDictionary(elements={**general_elements, **individual_elements}), + headers, + ) + + def catalog(self) -> Catalog | None: + # Note: We may skip the CatalogConverter and build the Catalog ourselves + return self._get_catalog_converter().catalog + def valuespec(self) -> Dictionary: general_elements = self._vs_mandatory_elements() general_keys = [k for k, _v in general_elements] @@ -480,6 +528,100 @@ def _vs_mandatory_elements(self) -> list[DictionaryEntry]: return elements + def _fs_general_properties(self) -> dict[str, form_specs.DictElement]: + elements: dict[str, form_specs.DictElement[Any]] = {} + if self._new: + elements["ident"] = form_specs.DictElement( + parameter_form=form_specs.String( + title=Title("Unique ID"), + help_text=Help( + "The ID must be unique. It acts as internal key when objects reference it." + ), + prefill=form_specs.DefaultValue(self._default_id()), + custom_validate=(form_specs.validators.LengthInRange(min_value=1),), + ), + ) + else: + assert self._ident is not None + elements["ident"] = form_specs.DictElement( + required=True, + parameter_form=form_specs.FixedValue( + title=Title("Unique ID"), + help_text=Help( + "The ID must be unique. It acts as internal key when objects reference it." + ), + value=self._ident, + ), + ) + + if "locked_by" in self._entry: + elements["locked_by"] = form_specs.DictElement( + required=True, + parameter_form=form_specs.FixedValue( + title=Title("Locked by"), + value=repr(self._entry["locked_by"]), + ), + ) + + elements["title"] = form_specs.DictElement( + parameter_form=form_specs.String( + title=Title("Title"), + help_text=Help("Name your %s for easy recognition.") + % self._mode_type.name_singular(), + custom_validate=(form_specs.validators.LengthInRange(min_value=1),), + ), + ) + elements["comment"] = form_specs.DictElement( + parameter_form=CommentTextArea( + title=Title("Comment"), + help_text=Help( + "Optionally, add a comment to explain the purpose of this " + "object. The comment is only visible in this dialog and can help " + "other users to understand the intentions of the configured " + "attributes." + ), + ), + ) + + def _validate_documentation_url(value: str) -> None: + if not is_allowed_url(value, cross_domain=True, schemes=["http", "https"]): + raise ValidationError( + Message("Not a valid URL (Only http and https URLs are allowed)."), + ) + + elements["docu_url"] = form_specs.DictElement( + parameter_form=form_specs.String( + title=Title("Documentation URL"), + help_text=Help( + "Optionally, add a URL linking to a documentation or any other " + "page. An icon links to the page and opens in a new tab when " + "clicked. You can use either global URLs (starting with " + "http://), absolute local URLs (starting with " + "/) or relative URLs (relative to " + "check_mk/)." + ), # % str(html.render_icon("url")), + custom_validate=(_validate_documentation_url,), + ), + ) + + if self._mode_type.can_be_disabled(): + elements["disabled"] = form_specs.DictElement( + parameter_form=form_specs.BooleanChoice( + title=Title("Activation"), + help_text=Help( + "Selecting this option will disable the %s, but " + "it will remain in the configuration." + ) + % self._mode_type.name_singular(), + label=Label("do not activate this %s") % self._mode_type.name_singular(), + ), + ) + + if self._mode_type.is_site_specific(): + elements["site"] = form_specs.DictElement(parameter_form=create_setup_site_choice()) + + return elements + def _default_id(self) -> str: return unique_default_name_suggestion( self._mode_type.name_singular(), @@ -489,12 +631,16 @@ def _default_id(self) -> str: def _vs_optional_keys(self) -> list[str]: return [] - def action(self) -> ActionResult: - check_csrf_token() - - if not transactions.transaction_valid(): - return redirect(mode_url(self._mode_type.list_mode_name())) + def _update_entry_from_vars(self) -> None: + render_mode, form_spec = self._get_render_mode() + match render_mode: + case ExperimentalRenderMode.FRONTEND | ExperimentalRenderMode.BACKEND_AND_FRONTEND: + assert form_spec is not None + self._update_entry_from_vars_form_spec(form_spec) + case ExperimentalRenderMode.BACKEND: + self._update_entry_from_vars_valuespec() + def _update_entry_from_vars_valuespec(self) -> None: vs = self.valuespec() config = vs.from_html_vars("_edit") @@ -512,6 +658,39 @@ def action(self) -> ActionResult: # No typing support from valuespecs here, so we need to cast self._entry = cast(_T, config) + def _update_entry_from_vars_form_spec(self, form_spec: FormSpec) -> None: + config = parse_data_from_frontend( + form_spec, + self._vue_field_id(), + ) + + # The form spec was rendered via a Catalog form spec, which introduced needless topics + # We need to convert the config back to a flat dictionary + config = self._get_catalog_converter().convert_catalog_to_flat_config(config) + + if "ident" in config: + self._ident = config.pop("ident") + assert self._ident is not None + entries = self._store.load_for_modification() + + # Keep the "locked_by" attribute if it exists in the current entry + if self._ident in entries and "locked_by" in entries[self._ident]: + config = {**config, "locked_by": entries[self._ident]["locked_by"]} + + # No typing support from form specs here, so we need to cast + self._entry = cast(_T, config) + + def action(self) -> ActionResult: + check_csrf_token() + + if not transactions.transaction_valid(): + return redirect(mode_url(self._mode_type.list_mode_name())) + + self._update_entry_from_vars() + assert self._ident is not None + + entries = self._store.load_for_modification() + if self._new and self._ident in entries: raise MKUserError("ident", _("This ID is already in use. Please choose another one.")) @@ -558,13 +737,79 @@ def page(self, form_name: str = "edit") -> None: html.prevent_password_auto_completion() - vs = self.valuespec() + self._page_form_render_entry() - vs.render_input("_edit", dict(self._entry) if not self._new else {}) - vs.set_focus("_edit") forms.end() - html.hidden_fields() def _page_form_quick_setup_warning(self) -> None: pass + + def _get_render_mode(self) -> tuple[ExperimentalRenderMode, FormSpec | None]: + # No longer depends on global switch, but on the global switch + # but on existence of the fs_individual_elements implementation + try: + self._fs_individual_elements() + except NotImplementedError: + return ExperimentalRenderMode.BACKEND, None + + # Frontend rendering is done via the Catalog class. There is no valuespec fallback + return ExperimentalRenderMode.FRONTEND, self.catalog() + + def _page_form_render_entry(self) -> None: + render_mode, form_spec = self._get_render_mode() + match render_mode: + case ExperimentalRenderMode.BACKEND: + self._page_form_render_entry_valuespec() + + case ExperimentalRenderMode.FRONTEND: + assert form_spec is not None + # This prevents sending the form when pressing enter in an input field + html.form_has_submit_button = True + self._page_form_render_entry_form_spec(form_spec) + + def _page_form_render_entry_valuespec(self) -> None: + vs = self.valuespec() + vs.render_input("_edit", dict(self._entry) if not self._new else {}) + vs.set_focus("_edit") + + def _page_form_render_entry_form_spec(self, form_spec: FormSpec) -> None: + value, origin, do_validate = self._get_render_settings() + render_form_spec(form_spec, self._vue_field_id(), value, origin, do_validate) + + def _vue_field_id(self) -> str: + return f"_edit_{self._mode_type.type_name()}" + + def _get_render_settings(self) -> tuple[Any, DataOrigin, DoValidate]: + if request.has_var(self._vue_field_id()): + # The form was submitted, always validate data + return ( + json.loads(request.get_str_input_mandatory(self._vue_field_id())), + DataOrigin.FRONTEND, + True, + ) + + if self._new: + # New form, no validation + return DEFAULT_VALUE, DataOrigin.DISK, False + + # Existing entry from disk + catalog_converter = self._get_catalog_converter() + + # The ident is not part of the saved config + # So, the entry is not longer a type _T + cloned_entry: Any = self._clone_entry(self._entry) + cloned_entry["ident"] = self._ident + catalog_config = catalog_converter.convert_flat_to_catalog_config(cloned_entry) + return catalog_config, DataOrigin.DISK, True + + +def convert_dict_elements_vs2fs(elements: list[DictionaryEntry]) -> dict[str, DictElement]: + # Transitional helper function, can be removed once all SimpleEditMode pages are converted + # Wraps legacy dictionary valuespec elements into form spec elements + fs_elements: dict[str, form_specs.DictElement[Any]] = {} + for key, element in elements: + fs_elements[key] = DictElement( + parameter_form=LegacyValueSpec.wrap(element), + ) + return fs_elements diff --git a/cmk/gui/wato/pages/activate_changes.py b/cmk/gui/wato/pages/activate_changes.py index 44b8376ee4b..a2f329b0b9a 100644 --- a/cmk/gui/wato/pages/activate_changes.py +++ b/cmk/gui/wato/pages/activate_changes.py @@ -38,6 +38,7 @@ from cmk.gui.logged_in import user from cmk.gui.page_menu import ( make_checkbox_selection_topic, + make_javascript_action, make_javascript_link, make_simple_link, PageMenu, @@ -45,6 +46,7 @@ PageMenuEntry, PageMenuTopic, show_confirm_cancel_dialog, + show_success_dialog, ) from cmk.gui.pages import AjaxPage, PageRegistry, PageResult from cmk.gui.sites import SiteStatus @@ -364,6 +366,9 @@ def _change_table(changes: list[tuple[str, dict]], title: str) -> None: class ModeActivateChanges(WatoMode, activate_changes.ActivateChanges): + VAR_ORIGIN = "origin" + VAR_SPECIAL_AGENT_NAME = "special_agent_name" + @classmethod def name(cls) -> str: return "changelog" @@ -377,6 +382,7 @@ def __init__(self) -> None: super().__init__() super().load() self._license_usage_report_validity = get_license_usage_report_validity() + self._quick_setup_origin = request.get_ascii_input(self.VAR_ORIGIN) == "quick_setup" def title(self) -> str: return _("Activate pending changes") @@ -534,6 +540,8 @@ def _may_activate_changes(self) -> bool: return self._license_allows_activation() def page(self) -> None: + self._quick_setup_activation_msg() + self._quick_setup_following_step() self._activation_msg() self._activation_form() @@ -544,6 +552,60 @@ def page(self) -> None: if self.has_pending_changes(): _change_table(self._pending_changes, _("Pending changes")) + def _quick_setup_activation_msg(self): + if not (self._quick_setup_origin and self.has_pending_changes()): + return + + message = html.render_div( + ( + html.render_div( + _("Activate the changes by clicking the Activate on selected sites button.") + ) + + html.render_div(_("This action will affect all pending changes you have made.")) + ), + class_="confirm_info", + ) + + confirm_url = "javascript:" + make_javascript_action( + 'cmk.activation.activate_changes("selected")' + ) + + show_confirm_cancel_dialog( + title=_("Activate pending changes"), + confirm_url=confirm_url, + confirm_text=_("Activate on selected sites"), + message=message, + show_cancel_button=False, + ) + + def _quick_setup_following_step(self): + if not self._quick_setup_origin or self.has_pending_changes(): + return + + special_agent_name = request.get_ascii_input(self.VAR_SPECIAL_AGENT_NAME, "") + + message = html.render_div( + ( + html.render_div(_("The changes have been activated successfully.")) + + html.render_div( + _( + "Go to the Monitor > All Hosts page or click the Go to All hosts button to start monitoring your %s services." + ) + % special_agent_name + ) + ), + class_="confirm_info", + ) + + show_success_dialog( + title=_("Changes activated"), + confirm_url=makeuri_contextless( + request, [("view_name", "allhosts")], filename="view.py" + ), + confirm_text=_('Go to "All hosts"'), + message=message, + ) + def _activation_msg(self): html.open_div(id_="async_progress_msg") if message := self._get_initial_message(): diff --git a/cmk/gui/wato/pages/global_settings.py b/cmk/gui/wato/pages/global_settings.py index f36831eba0b..16d95193e37 100644 --- a/cmk/gui/wato/pages/global_settings.py +++ b/cmk/gui/wato/pages/global_settings.py @@ -8,7 +8,7 @@ settings""" import abc -from collections.abc import Callable, Collection, Iterable, Iterator +from collections.abc import Callable, Collection, Iterable, Iterator, Sequence from typing import Any, Final from cmk.ccc.exceptions import MKGeneralException @@ -58,15 +58,25 @@ from cmk.gui.watolib.mode import mode_url, ModeRegistry, redirect, WatoMode from cmk.gui.watolib.search import ( ABCMatchItemGenerator, - match_item_generator_registry, MatchItem, + MatchItemGeneratorRegistry, MatchItems, ) -def register(mode_registry: ModeRegistry) -> None: - mode_registry.register(ModeEditGlobals) - mode_registry.register(ModeEditGlobalSetting) +def register( + mode_registry: ModeRegistry, + match_item_generator_registry: MatchItemGeneratorRegistry, +) -> None: + mode_registry.register(DefaultModeEditGlobals) + mode_registry.register(DefaultModeEditGlobalSetting) + match_item_generator_registry.register( + MatchItemGeneratorSettings( + "global_settings", + _("Global settings"), + DefaultModeEditGlobals, + ) + ) class ABCGlobalSettingsMode(WatoMode): @@ -360,7 +370,7 @@ def action(self) -> ActionResult: new_value = self._valuespec.from_html_vars("ve") self._valuespec.validate_value(new_value, "ve") - current = self._current_settings[self._varname] + current = self._current_settings.get(self._varname) self._current_settings[self._varname] = new_value msg = HTML.without_escaping( _("Changed global configuration variable %s to %s.") @@ -469,8 +479,6 @@ def _show_global_setting(self): class ModeEditGlobals(ABCGlobalSettingsMode): - page_menu_dropdowns_hook: Callable[[], PageMenuDropdown] | None = None - @classmethod def name(cls) -> str: return "globalvars" @@ -479,9 +487,15 @@ def name(cls) -> str: def static_permissions() -> Collection[PermissionName]: return ["global"] - def __init__(self) -> None: + def __init__( + self, + page_menu_dropdowns_postprocess: Callable[ + [Sequence[PageMenuDropdown]], list[PageMenuDropdown] + ], + ) -> None: super().__init__() self._current_settings = dict(load_configuration_settings()) + self._page_menu_dropdowns_postprocess = page_menu_dropdowns_postprocess def title(self) -> str: if self._search: @@ -491,9 +505,6 @@ def title(self) -> str: def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: dropdowns = [] - if ModeEditGlobals.page_menu_dropdowns_hook is not None: - dropdowns.append(ModeEditGlobals.page_menu_dropdowns_hook()) - dropdowns.append( PageMenuDropdown( name="related", @@ -507,6 +518,8 @@ def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: ), ) + dropdowns = self._page_menu_dropdowns_postprocess(dropdowns) + menu = PageMenu( dropdowns=dropdowns, breadcrumb=breadcrumb, @@ -567,6 +580,11 @@ def page(self) -> None: self._show_configuration_variables() +class DefaultModeEditGlobals(ModeEditGlobals): + def __init__(self) -> None: + super().__init__(list) + + class ModeEditGlobalSetting(ABCEditGlobalSettingMode): @classmethod def name(cls) -> str: @@ -590,6 +608,12 @@ def _back_url(self) -> str: return ModeEditGlobals.mode_url() +class DefaultModeEditGlobalSetting(ModeEditGlobalSetting): + @classmethod + def parent_mode(cls) -> type[WatoMode] | None: + return DefaultModeEditGlobals + + def is_a_checkbox(vs: ValueSpec) -> bool: """Checks if a valuespec is a Checkbox""" if isinstance(vs, Checkbox): @@ -647,12 +671,3 @@ def is_affected_by_change(_change_action_name: str) -> bool: @property def is_localization_dependent(self) -> bool: return True - - -match_item_generator_registry.register( - MatchItemGeneratorSettings( - "global_settings", - _("Global settings"), - ModeEditGlobals, - ) -) diff --git a/cmk/gui/wato/pages/hosts.py b/cmk/gui/wato/pages/hosts.py index d403f7a0b95..8730ad8ace0 100644 --- a/cmk/gui/wato/pages/hosts.py +++ b/cmk/gui/wato/pages/hosts.py @@ -50,6 +50,7 @@ from cmk.gui.watolib.hosts_and_folders import ( folder_from_request, folder_preserving_link, + folder_tree, Host, validate_all_hosts, ) @@ -214,7 +215,7 @@ def page(self) -> None: errors = None if self._mode == "edit": errors = ( - validate_all_hosts([self._host.name()]).get(self._host.name(), []) + validate_all_hosts(folder_tree(), [self._host.name()]).get(self._host.name(), []) + self._host.validation_errors() ) diff --git a/cmk/gui/wato/pages/notifications/__init__.py b/cmk/gui/wato/pages/notifications/__init__.py new file mode 100644 index 00000000000..f1f5981a9a1 --- /dev/null +++ b/cmk/gui/wato/pages/notifications/__init__.py @@ -0,0 +1,14 @@ +#!/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.gui.quick_setup.v0_unstable._registry import QuickSetupRegistry +from cmk.gui.watolib.mode import ModeRegistry + +from . import modes, quick_setup + + +def register(mode_registry: ModeRegistry, quick_setup_registry: QuickSetupRegistry) -> None: + modes.register(mode_registry) + quick_setup.register(quick_setup_registry) diff --git a/cmk/gui/wato/pages/notifications.py b/cmk/gui/wato/pages/notifications/modes.py similarity index 82% rename from cmk/gui/wato/pages/notifications.py rename to cmk/gui/wato/pages/notifications/modes.py index 0726c62c860..7b3fe914285 100644 --- a/cmk/gui/wato/pages/notifications.py +++ b/cmk/gui/wato/pages/notifications/modes.py @@ -7,7 +7,7 @@ import abc import json import time -from collections.abc import Collection, Iterator, Mapping +from collections.abc import Collection, Generator, Iterator, Mapping from copy import deepcopy from dataclasses import asdict from datetime import datetime @@ -21,7 +21,15 @@ from cmk.utils import paths from cmk.utils.labels import Labels from cmk.utils.notify import NotificationContext -from cmk.utils.notify_types import EventRule, is_always_bulk, NotifyAnalysisInfo +from cmk.utils.notify_types import ( + EventRule, + is_always_bulk, + NotificationParameterGeneralInfos, + NotificationParameterID, + NotificationParameterItem, + NotificationParameterSpecs, + NotifyAnalysisInfo, +) from cmk.utils.statename import host_state_name, service_state_name from cmk.utils.user import UserId @@ -32,18 +40,9 @@ from cmk.gui.breadcrumb import Breadcrumb from cmk.gui.config import active_config from cmk.gui.exceptions import MKUserError -from cmk.gui.form_specs.vue.shared_type_defs import ( - CoreStats, - CoreStatsI18n, - FallbackWarning, - FallbackWarningI18n, - Notifications, - NotificationStats, - NotificationStatsI18n, - Rule, - RuleSection, - RuleTopic, -) +from cmk.gui.form_specs.private import Catalog +from cmk.gui.form_specs.vue.form_spec_visitor import parse_data_from_frontend, render_form_spec +from cmk.gui.form_specs.vue.visitors import DataOrigin, DEFAULT_VALUE from cmk.gui.htmllib.foldable_container import foldable_container from cmk.gui.htmllib.generator import HTMLWriter from cmk.gui.htmllib.html import html @@ -62,9 +61,10 @@ PageMenuSearch, PageMenuTopic, ) +from cmk.gui.quick_setup.v0_unstable._registry import quick_setup_registry from cmk.gui.site_config import has_wato_slave_sites, site_is_local, wato_slave_sites from cmk.gui.table import Table, table_element -from cmk.gui.type_defs import ActionResult, MegaMenu, PermissionName +from cmk.gui.type_defs import ActionResult, HTTPVariables, MegaMenu, PermissionName from cmk.gui.user_async_replication import user_profile_async_replication_dialog from cmk.gui.utils.autocompleter_config import ContextAutocompleterConfig from cmk.gui.utils.csrf_token import check_csrf_token @@ -115,6 +115,11 @@ Tuple, UUID, ) +from cmk.gui.wato._group_selection import ContactGroupSelection +from cmk.gui.wato._notification_parameter import ( + notification_parameter_registry, + NotificationParameter, +) from cmk.gui.wato.pages.events import ABCEventsMode from cmk.gui.wato.pages.user_profile.page_menu import page_menu_dropdown_user_related from cmk.gui.wato.pages.users import ModeEditUser @@ -127,16 +132,34 @@ from cmk.gui.watolib.global_settings import load_configuration_settings from cmk.gui.watolib.hosts_and_folders import folder_preserving_link, make_action_link from cmk.gui.watolib.mode import mode_url, ModeRegistry, redirect, WatoMode -from cmk.gui.watolib.notifications import load_user_notification_rules, NotificationRuleConfigFile +from cmk.gui.watolib.notification_types import ( + CoreStats, + CoreStatsI18n, + FallbackWarning, + FallbackWarningI18n, + NotificationParametersOverview, + Notifications, + NotificationStats, + NotificationStatsI18n, + Rule, + RuleSection, + RuleTopic, +) +from cmk.gui.watolib.notifications import ( + load_user_notification_rules, + NotificationParameterConfigFile, + NotificationRuleConfigFile, +) from cmk.gui.watolib.rulesets import AllRulesets -from cmk.gui.watolib.sample_config import get_default_notification_rule, new_notification_rule_id +from cmk.gui.watolib.sample_config import ( + get_default_notification_rule, + new_notification_parameter_id, + new_notification_rule_id, +) from cmk.gui.watolib.timeperiods import TimeperiodSelection from cmk.gui.watolib.user_scripts import load_notification_scripts from cmk.gui.watolib.users import notification_script_choices -from .._group_selection import ContactGroupSelection -from .._notification_parameter import notification_parameter_registry - def register(mode_registry: ModeRegistry) -> None: mode_registry.register(ModeNotifications) @@ -147,6 +170,11 @@ def register(mode_registry: ModeRegistry) -> None: mode_registry.register(ModeEditNotificationRule) mode_registry.register(ModeEditUserNotificationRule) mode_registry.register(ModeEditPersonalNotificationRule) + mode_registry.register(ModeNotificationParametersOverview) + mode_registry.register(ModeEditNotificationRuleQuickSetup) + + mode_registry.register(ModeNotificationParameters) + mode_registry.register(ModeEditNotificationParameter) class ABCNotificationsMode(ABCEventsMode): @@ -375,8 +403,8 @@ def _render_notification_rules( # pylint: disable=too-many-branches html.icon_button( links.clone, _("Create a copy of this notification rule"), "clone" ) - html.element_dragger_url("tr", base_url=links.drag) html.icon_button(links.delete, _("Delete this notification rule"), "delete") + html.element_dragger_url("tr", base_url=links.drag) else: table.cell("", css=["buttons"]) for _x in range(4): @@ -395,13 +423,21 @@ def _render_notification_rules( # pylint: disable=too-many-branches notify_method = (None, []) notify_plugin = notify_method[0] - table.cell(_("Type"), css=["narrow"]) + table.cell(_("Method"), notify_plugin or _("Plain email"), css=["narrow nowrap"]) + + table.cell(_("Effect"), css=["narrow"]) if notify_method[1] is None: - html.icon("cross_bg_white", _("Cancel notifications for this plug-in type")) + html.icon( + "cancel_notifications", _("Cancel notifications for this plug-in type") + ) else: - html.icon("checkmark", _("Create a notification")) - - table.cell(_("Method"), notify_plugin or _("Plain email"), css=["narrow nowrap"]) + html.icon( + { + "icon": "notifications", + "emblem": "enable", + }, + _("Create a notification"), + ) table.cell(_("Bulk"), css=["narrow"]) if "bulk" in rule or "bulk_period" in rule: @@ -585,7 +621,7 @@ def __init__(self) -> None: self._show_user_rules = options.get("show_user_rules", False) def title(self) -> str: - return _("Notification configuration") + return _("Notifications") def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: menu = PageMenu( @@ -606,6 +642,17 @@ def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: is_shortcut=True, is_suggested=True, ), + PageMenuEntry( + title=_("Parameters for notification methods"), + icon_name="clipboard", + item=make_simple_link( + folder_preserving_link( + [("mode", ModeNotificationParametersOverview.name())] + ) + ), + is_shortcut=True, + is_suggested=True, + ), ], ), PageMenuTopic( @@ -717,10 +764,7 @@ def _extend_display_dropdown(self, menu: PageMenu) -> None: title=( _("Hide user rules") if self._show_user_rules else _("Show user rules") ), - icon_name={ - "icon": "checkbox", - "emblem": "disable" if self._show_user_rules else "enable", - }, + icon_name="toggle_on" if self._show_user_rules else "toggle_off", item=make_simple_link( makeactionuri( request, @@ -905,7 +949,11 @@ def _get_vue_data() -> Notifications: i18n=FallbackWarningI18n( title=_("No fallback email address configured"), message=_( - "If your monitoring produces a notification that is not matched by any of your notification rules, the notification will not be sent out. To prevent that, we recommend configuring either the global setting or enable the fallback contact option for at least one of your users." + "Without a fallback email address, you may miss alerts " + "that are not covered by a notification rule. To ensure " + "full notification coverage, we recommend that you " + "configure the fallback email address to which all " + "alerts that don't match a notification rule are sent." ), setup_link_title=_("Configure fallback email address"), do_not_show_again_title=_("Do not show again"), @@ -1908,10 +1956,7 @@ def _vs_general_test_options(self) -> Dictionary: def _vs_dispatched_option(self) -> Checkbox: return Checkbox( title=_("Dispatch notification"), - label=_( - "Send out HTML/ASCII email notification according " - "to notification rules (uncheck to avoid spam)" - ), + label=_("Send out HTML/ASCII email notification according to notification rules"), default_value=False, ) @@ -2891,3 +2936,549 @@ def title(self) -> str: if self._new: return _("Create new notification rule") return _("Edit notification rule %d") % self._edit_nr + + +class ModeNotificationParametersOverview(WatoMode): + @classmethod + def name(cls) -> str: + return "notification_parameters_overview" + + @staticmethod + def static_permissions() -> Collection[PermissionName]: + return ["notifications"] + + @classmethod + def parent_mode(cls) -> type[WatoMode] | None: + return ModeNotifications + + def title(self) -> str: + return _("Parameters for notification methods") + + def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: + menu = PageMenu( + dropdowns=[ + PageMenuDropdown( + name="notification_rules", + title=_("Parameters for notification methods"), + topics=[ + PageMenuTopic( + title=_("Add"), + entries=[ + PageMenuEntry( + title=_("Define parameters for HTML mail"), + icon_name="new", + item=make_simple_link( + folder_preserving_link( + [ + ("mode", "notification_parameters"), + ("method", "mail"), + ("back_mode", self.name()), + ("rule_folder", ""), + ] + ) + ), + is_shortcut=True, + is_suggested=True, + ), + ], + ), + ], + ), + PageMenuDropdown( + name="related", + title=_("Related"), + topics=[], # TODO: add related topics here + ), + ], + breadcrumb=breadcrumb, + inpage_search=PageMenuSearch(), + ) + menu.add_doc_reference(_("Notifications"), DocReference.NOTIFICATIONS) + return menu + + def page(self) -> None: + html.vue_app( + app_name="notification_parameters_overview", + data=asdict(self._get_notification_parameters_data()), + ) + + def _get_parameter_rulesets( + self, + all_parameters: NotificationParameterSpecs, + ) -> Generator[Rule]: + for script_name, title in notification_script_choices(): + # TODO remove this if all NotificationParameters are converted to FormSpecs + if script_name not in ["mail", "ilert"]: + continue + method_parameters: dict[NotificationParameterID, NotificationParameterItem] | None = ( + all_parameters.get(script_name) + ) + yield Rule( + i18n=title, + count="0" if method_parameters is None else f"{len(method_parameters)}", + link=makeuri( + request, + [ + ("mode", "notification_parameters"), + ("method", script_name), + ("back_mode", self.name()), + ], + ), + ) + + def _get_notification_parameters_data(self) -> NotificationParametersOverview: + all_parameters = NotificationParameterConfigFile().load_for_reading() + return NotificationParametersOverview( + parameters=[ + RuleSection( + i18n=_("Parameters for"), + topics=[ + RuleTopic( + i18n=None, + rules=list(self._get_parameter_rulesets(all_parameters)), + ) + ], + ) + ] + ) + + +class ABCNotificationParameterMode(WatoMode): + @classmethod + def name(cls): + return "notification_parameter" + + @staticmethod + def static_permissions() -> Collection[PermissionName]: + return ["notifications"] + + def title(self) -> str: + raise NotImplementedError() + + def _back_mode(self) -> ActionResult: + raise NotImplementedError() + + def _load_parameters(self) -> NotificationParameterSpecs: + if transactions.is_transaction(): + return NotificationParameterConfigFile().load_for_modification() + return NotificationParameterConfigFile().load_for_reading() + + def _save_parameters( + self, + parameters: NotificationParameterSpecs, + ) -> None: + NotificationParameterConfigFile().save(parameters) + + def _add_change(self, log_what, log_text): + _changes.add_change(log_what, log_text, need_restart=False) + + def _log_text(self, edit_nr: int) -> str: + raise NotImplementedError() + + def _from_vars(self) -> None: + self._edit_nr = request.get_integer_input_mandatory("edit_nr", -1) + self._edit_parameter = request.get_str_input_mandatory("parameter", "") + clone_id = request.get_str_input_mandatory("clone", "") + self._clone_id = NotificationParameterID(clone_id) + + self._parameters = self._load_parameters() + method_parameters: dict[NotificationParameterID, NotificationParameterItem] + self._new = ( + not (method_parameters := self._parameters.get(self._method(), {})) + or self._edit_parameter not in method_parameters + ) + + if self._new: + if self._clone_id and not request.var("_clear"): + try: + self._parameter = deepcopy(method_parameters[self._clone_id]) + except IndexError: + raise MKUserError(None, _("This %s does not exist.") % "notification parameter") + else: + self._parameter = NotificationParameterItem( + general=NotificationParameterGeneralInfos( + description="", + comment="", + docu_url="", + ), + parameter_properties=DEFAULT_VALUE, # type: ignore[typeddict-item] # can not import in cmk.utils.notify_types + ) + else: + try: + self._parameter = method_parameters[NotificationParameterID(self._edit_parameter)] + except IndexError: + raise MKUserError(None, _("This %s does not exist.") % "notification parameter") + + def _notification_parameter(self) -> type[NotificationParameter]: + try: + return notification_parameter_registry[self._method()] + except KeyError: + raise MKUserError( + None, _("No notification parameters for method '%s' found") % self._method() + ) + + def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: + return make_simple_form_page_menu( + _("Notification parameter"), breadcrumb, form_name="parameter", button_name="_save" + ) + + def action(self) -> ActionResult: + check_csrf_token() + + self._parameters = self._load_parameters() + if (method_parameters := self._parameters.get(self._method())) is None: + return redirect(mode_url("notification_parameters", method=self._method())) + + method_parameter_list = list(method_parameters.items()) + if request.has_var("_delete"): + parameter_id = request.get_str_input_mandatory("_delete") + method_parameters.pop(NotificationParameterID(parameter_id), None) + self._parameters[self._method()] = method_parameters + self._save_parameters(self._parameters) + + parameter_number = next( + i for i, v in enumerate(method_parameter_list) if v[0] == parameter_id + ) + self._add_change( + "notification-delete-notification-parameter", + _("Deleted notification parameter %d") % parameter_number, + ) + + elif request.has_var("_move"): + from_pos = request.get_integer_input_mandatory("_move") + to_pos = request.get_integer_input_mandatory("_index") + + parameter = method_parameter_list[from_pos] + del method_parameter_list[from_pos] # make to_pos now match! + method_parameter_list[to_pos:to_pos] = [parameter] + method_parameter_dict = dict(method_parameter_list) + self._parameters[self._method()] = method_parameter_dict + self._save_parameters(self._parameters) + + self._add_change( + "notification-move-notification-parameter", + _("Changed position of notification parameter %d") % from_pos, + ) + + if back_mode := request.var("back_mode"): + return redirect(mode_url(back_mode, method=self._method())) + + return redirect(mode_url("notification_parameters", method=self._method())) + + def _vue_field_id(self) -> str: + return "_vue_edit_notification_parameter" + + def _get_parameter_value_and_origin(self) -> tuple[NotificationParameterItem, DataOrigin]: + if request.has_var(self._vue_field_id()): + return ( + json.loads(request.get_str_input_mandatory(self._vue_field_id())), + DataOrigin.FRONTEND, + ) + + return self._parameter, DataOrigin.DISK + + def _method(self) -> str: + return request.get_str_input_mandatory("method") + + +class ModeNotificationParameters(ABCNotificationParameterMode): + """Show notification parameter for a specific method""" + + @classmethod + def name(cls) -> str: + return "notification_parameters" + + @classmethod + def parent_mode(cls) -> type[WatoMode] | None: + return ModeNotificationParametersOverview + + def _breadcrumb_url(self) -> str: + """Ensure the URL is computed correctly when linking from man pages to the topic""" + return self.mode_url(method=self._method()) + + def title(self) -> str: + return _("Parameters for %s") % request.var("method") + + def _log_text(self, edit_nr: int) -> str: + if self._new: + return _("Created new notification parameter") + return _("Changed notification parameter %d") % edit_nr + + def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: + return PageMenu( + dropdowns=[ + PageMenuDropdown( + name="parameters", + title=_("Notification parameter"), + topics=[ + PageMenuTopic( + title=_("Parameter"), + entries=[ + PageMenuEntry( + title=_("Add parameter"), + icon_name="new", + item=make_simple_link( + folder_preserving_link( + [ + ("mode", "edit_notification_parameter"), + ("method", self._method()), + ] + ) + ), + is_shortcut=True, + is_suggested=True, + ), + ], + ) + ], + ), + ], + breadcrumb=breadcrumb, + inpage_search=PageMenuSearch(), + ) + + def page(self) -> None: + if self._method() not in load_notification_scripts(): + raise MKUserError(None, _("Notification method '%s' does not exist") % self._method()) + + parameters = self._load_parameters() + if not (method_parameters := parameters.get(self._method())): + html.show_message( + _("You have not created any parameters for this notification method yet.") + ) + return + self._render_notification_parameters(method_parameters) + + def _render_notification_parameters( + self, + parameters, + ): + notification_parameter = self._notification_parameter() + with table_element(title=_("Parameters"), limit=None, sortable=False) as table: + for nr, (parameter_id, parameter) in enumerate(parameters.items()): + table.row() + + table.cell("#", css=["narrow nowrap"]) + html.write_text_permissive(nr) + table.cell(_("Actions"), css=["buttons"]) + links = self._parameter_links(parameter, parameter_id, nr) + html.icon_button(links.edit, _("Edit this notification parameter"), "edit") + html.icon_button( + links.clone, _("Create a copy of this notification parameter"), "clone" + ) + html.element_dragger_url("tr", base_url=links.drag) + html.icon_button(links.delete, _("Delete this notification parameter"), "delete") + + table.cell(_("Method"), self._method()) + + table.cell(_("Description")) + url = parameter.get("docu_url") + if url: + html.icon_button( + url, _("Context information about this parameter"), "url", target="_blank" + ) + html.write_text_permissive(" ") + html.write_text_permissive(parameter["general"]["description"]) + + table.cell(_("Parameter properties")) + num_properties = len(parameter["parameter_properties"]) + title = _("%d defined parameter properties") % num_properties + with foldable_container( + treename="parameter_{nr}", + id_=str(nr), + isopen=False, + title=title, + indent=False, + ): + html.write_text_permissive( + notification_parameter().spec.value_to_html( + parameter["parameter_properties"] + ) + ) + + def _add_change(self, log_what, log_text): + _changes.add_change(log_what, log_text, need_restart=False) + + def _parameter_links( + self, + parameter: dict[str, Any], + parameter_id: NotificationParameterID, + nr: int, + ) -> NotificationRuleLinks: + listmode = "notification_parameters" + mode = "edit_notification_parameter" + + additional_vars: HTTPVariables = [ + ("back_mode", "notification_parameters"), + ("method", self._method()), + ] + + delete_url = make_confirm_delete_link( + url=make_action_link( + [ + ("mode", listmode), + ("_delete", parameter_id), + ] + + additional_vars + ), + title=_("Delete notification parameter #%d") % nr, + suffix=parameter.get("description", ""), + ) + drag_url = make_action_link( + [ + ("mode", listmode), + ("_move", str(nr)), + ] + + additional_vars + ) + edit_url = folder_preserving_link( + [ + ("mode", mode), + ("parameter", parameter_id), + ("edit", str(nr)), + ] + + additional_vars + ) + clone_url = folder_preserving_link( + [ + ("mode", mode), + ("clone", parameter_id), + ] + + additional_vars + ) + + return NotificationRuleLinks( + delete=delete_url, edit=edit_url, drag=drag_url, clone=clone_url + ) + + +class ModeEditNotificationParameter(ABCNotificationParameterMode): + """Edit a notification parameter""" + + @classmethod + def name(cls) -> str: + return "edit_notification_parameter" + + @staticmethod + def static_permissions() -> Collection[PermissionName]: + return ["notifications"] + + @classmethod + def parent_mode(cls) -> type[WatoMode] | None: + return ModeNotificationParameters + + def breadcrumb(self) -> Breadcrumb: + with request.stashed_vars(): + request.set_var("method", self._method()) + return super().breadcrumb() + + def _back_mode(self) -> ActionResult: + return redirect(mode_url("notification_parameters", method=self._method())) + + def title(self) -> str: + if self._new: + return _("Add %s notification parameter") % self._method() + return _("Edit %s notification parameter %s") % (self._method(), self._edit_nr) + + def _log_text(self, edit_nr: int) -> str: + if self._new: + return _("Created new notification parameter") + return _("Changed notification parameter %s") % edit_nr + + def _form_spec(self) -> Catalog: + return notification_parameter_registry.form_spec(self._method()) + + def action(self) -> ActionResult: + check_csrf_token() + + if not transactions.check_transaction(): + return self._back_mode() + + value = parse_data_from_frontend( + self._form_spec(), + self._vue_field_id(), + ) + + self._parameter = value + + if self._new and self._clone_id: + self._parameters[self._method()][new_notification_parameter_id()] = self._parameter + elif self._new: + self._parameters.setdefault(self._method(), {}) + self._parameters[self._method()][new_notification_parameter_id()] = self._parameter + else: + self._parameters[self._method()][NotificationParameterID(self._edit_parameter)] = ( + self._parameter + ) + + self._save_parameters(self._parameters) + + log_what = "new-notification-parameter" if self._new else "edit-notification-parameter" + self._add_change(log_what, self._log_text(self._edit_nr)) + + if back_mode := request.var("back_mode"): + return redirect(mode_url(back_mode, method=self._method())) + + return self._back_mode() + + def page(self) -> None: + value, origin = self._get_parameter_value_and_origin() + + with html.form_context("parameter", method="POST"): + render_form_spec( + self._form_spec(), + self._vue_field_id(), + value, + origin, + True, + ) + + forms.end() + html.hidden_fields() + + +class ModeEditNotificationRuleQuickSetup(WatoMode): + @classmethod + def name(cls) -> str: + return "notification_rule_quick_setup" + + @classmethod + def parent_mode(cls) -> type[WatoMode] | None: + return ModeNotifications + + def _from_vars(self) -> None: + self._edit_nr = request.get_integer_input_mandatory("edit", -1) + self._new = self._edit_nr < 0 + quick_setup = quick_setup_registry["notification_rule"] + self._quick_setup_id = quick_setup.id + + @staticmethod + def static_permissions() -> Collection[PermissionName]: + return ["notifications"] + + def title(self) -> str: + if self._new: + return _("Add notification rule") + return _("Edit notification rule %d") % self._edit_nr + + def breadcrumb(self) -> Breadcrumb: + with request.stashed_vars(): + return super().breadcrumb() + + def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: + return make_simple_form_page_menu( + title=_("Notification rule"), + breadcrumb=breadcrumb, + add_cancel_link=True, + cancel_url=mode_url(mode_name=ModeNotifications.name()), + ) + + def page(self) -> None: + html.vue_app( + app_name="quick_setup", + data={ + "quick_setup_id": self._quick_setup_id, + "mode": "guided" if self._new else "overview", + "toggle_enabled": True, + }, + ) diff --git a/cmk/gui/wato/pages/notifications/quick_setup.py b/cmk/gui/wato/pages/notifications/quick_setup.py new file mode 100644 index 00000000000..afa46d33c39 --- /dev/null +++ b/cmk/gui/wato/pages/notifications/quick_setup.py @@ -0,0 +1,515 @@ +#!/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 Sequence +from typing import Literal + +from cmk.utils.urls import is_allowed_url +from cmk.utils.user import UserId + +from cmk.gui.form_specs.converter import Tuple +from cmk.gui.form_specs.private import ( + CommentTextArea, + DictionaryExtended, + ListExtended, + ListOfStrings, + not_empty, + SingleChoiceElementExtended, + SingleChoiceExtended, +) +from cmk.gui.form_specs.vue.shared_type_defs import DictionaryLayout, ListOfStringsLayout +from cmk.gui.i18n import _ +from cmk.gui.quick_setup.v0_unstable._registry import QuickSetupRegistry +from cmk.gui.quick_setup.v0_unstable.predefined import recaps +from cmk.gui.quick_setup.v0_unstable.setups import QuickSetup, QuickSetupSaveAction, QuickSetupStage +from cmk.gui.quick_setup.v0_unstable.type_defs import ( + GeneralStageErrors, + ParsedFormData, + QuickSetupId, + StageIndex, +) +from cmk.gui.quick_setup.v0_unstable.widgets import FormSpecId, FormSpecWrapper, Widget +from cmk.gui.userdb import load_users +from cmk.gui.wato._group_selection import sorted_contact_group_choices +from cmk.gui.watolib.mode import mode_url + +from cmk.rulesets.v1 import Label, Message, Title +from cmk.rulesets.v1.form_specs import ( + CascadingSingleChoice, + CascadingSingleChoiceElement, + DefaultValue, + DictElement, + Dictionary, + FieldSize, + FixedValue, + HostState, + InputHint, + ServiceState, + SingleChoice, + SingleChoiceElement, + String, +) +from cmk.rulesets.v1.form_specs.validators import EmailAddress, ValidationError + + +def _host_states() -> Sequence[tuple[int, Title]]: + return [ + (-1, Title("Any")), + (HostState.UP, Title("UP")), + (HostState.DOWN, Title("DOWN")), + (HostState.UNREACH, Title("UNREACHABLE")), + ] + + +def _service_states() -> Sequence[tuple[int, Title]]: + return [ + (-1, Title("Any")), + (ServiceState.OK, Title("OK")), + (ServiceState.WARN, Title("WARN")), + (ServiceState.CRIT, Title("CRIT")), + (ServiceState.UNKNOWN, Title("UNKNOWN")), + ] + + +def _get_states(what: Literal["host", "service"]) -> Sequence[tuple[int, Title]]: + match what: + case "host": + return _host_states() + case "service": + return _service_states() + case _: + raise ValueError(f"Invalid value for 'what': {what}") + + +def _event_choices(what: Literal["host", "service"]) -> Sequence[CascadingSingleChoiceElement]: + return [ + CascadingSingleChoiceElement( + name="status_change", + title=Title("Status change"), + parameter_form=Tuple( + layout="horizontal", + elements=[ + SingleChoiceExtended( + label=Label("From"), + prefill=DefaultValue(-1), + type=int, + elements=[ + SingleChoiceElementExtended(name=state, title=title) + for state, title in _get_states(what) + ], + ), + SingleChoiceExtended( + label=Label("to"), + prefill=DefaultValue(1) if what == "host" else DefaultValue(2), + type=int, + elements=[ + SingleChoiceElementExtended(name=state, title=title) + for state, title in _get_states(what) + ], + ), + ], + ), + ), + CascadingSingleChoiceElement( + name="downtime", + title=Title("Start or end of downtime"), + parameter_form=FixedValue(value=None), + ), + CascadingSingleChoiceElement( + name="acknowledgement", + title=Title("Acknowledgement of problem"), + parameter_form=FixedValue(value=None), + ), + CascadingSingleChoiceElement( + name="flapping_state", + title=Title("Start or end of flapping state"), + parameter_form=FixedValue(value=None), + ), + CascadingSingleChoiceElement( + name="alert_handler", + title=Title("Alert handler execution"), + parameter_form=SingleChoice( + prefill=DefaultValue("success"), + elements=[ + SingleChoiceElement(name="success", title=Title("Success")), + SingleChoiceElement(name="failure", title=Title("Failure")), + ], + ), + ), + ] + + +def _validate_at_least_one_event( + _quick_setup_id: QuickSetupId, + _stage_index: StageIndex, + form_data: ParsedFormData, +) -> GeneralStageErrors: + if not form_data[FormSpecId("triggering_events")].get("host_events") and not form_data[ + FormSpecId("triggering_events") + ].get("service_events"): + return [ + "No triggering events selected. " + "Please select at least one event to trigger the notification." + ] + return [] + + +def triggering_events() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [ + FormSpecWrapper( + id=FormSpecId("triggering_events"), + form_spec=DictionaryExtended( + layout=DictionaryLayout.two_columns, + prefill=DefaultValue( + { + "host_events": [ + ("status_change", (-1, HostState.DOWN)), + ("status_change", (-1, HostState.UP)), + ], + "service_events": [ + ("status_change", (-1, ServiceState.CRIT)), + ("status_change", (-1, ServiceState.UNKNOWN)), + ("status_change", (-1, ServiceState.WARN)), + ("status_change", (-1, ServiceState.OK)), + ], + } + ), + elements={ + "host_events": DictElement( + parameter_form=ListExtended( + title=Title("Host events"), + prefill=DefaultValue([]), + element_template=CascadingSingleChoice( + # TODO: add horizontal layout (CMK-18894) + elements=_event_choices("host"), + ), + add_element_label=Label("Add event"), + editable_order=False, + ) + ), + "service_events": DictElement( + parameter_form=ListExtended( + title=Title("Service events"), + prefill=DefaultValue([]), + element_template=CascadingSingleChoice( + # TODO: add horizontal layout (CMK-18894) + elements=_event_choices("service"), + ), + add_element_label=Label("Add event"), + editable_order=False, + ) + ), + "ec_alerts": DictElement( + parameter_form=FixedValue( + title=Title("Event console alerts"), + value="Enabled", + ), + ), + }, + ), + ) + ] + + return QuickSetupStage( + title=_("Triggering events"), + sub_title=_("Define any events you want to be notified about."), + configure_components=_components, + custom_validators=[_validate_at_least_one_event], + recap=[recaps.recaps_form_spec], + button_label=_("Next step: Specify host/services"), + ) + + +def filter_for_hosts_and_services() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [] + + return QuickSetupStage( + title=_("Filter for hosts/services"), + sub_title=_( + "Apply filters to specify which hosts and services are affected by this " + "notification rule." + ), + configure_components=_components, + custom_validators=[], + recap=[], + button_label=_("Next step: Notification method (plug-in)"), + ) + + +def notification_method() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [] + + return QuickSetupStage( + title=_("Notification method (plug-in)"), + sub_title=_("What should be send out?"), + configure_components=_components, + custom_validators=[], + recap=[], + button_label=_("Next step: Recipient"), + ) + + +def _get_sorted_users() -> list[tuple[UserId, str]]: + return sorted( + (name, f"{name} - {user.get("alias", name)}") for name, user in load_users().items() + ) + + +def _contact_group_choice() -> SingleChoice: + return SingleChoice( + prefill=InputHint(Title("Select contact group")), + elements=[ + SingleChoiceElement( + name=ident, + title=Title(title), # pylint: disable=localization-of-non-literal-string + ) + for ident, title in sorted_contact_group_choices() + ], + ) + + +def recipient() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [ + FormSpecWrapper( + id=FormSpecId("recipient"), + form_spec=ListExtended( + title=Title("Recipients"), + prefill=DefaultValue([("all_contacts_affected", None)]), + element_template=CascadingSingleChoice( + # TODO: add horizontal layout (CMK-18894) + elements=[ + CascadingSingleChoiceElement( + title=Title("All contacts of the affected object"), + name="all_contacts_affected", + parameter_form=FixedValue(value=None), + ), + CascadingSingleChoiceElement( + title=Title("All users with an email address"), + name="all_email_users", + parameter_form=FixedValue(value=None), + ), + CascadingSingleChoiceElement( + title=Title("Contact group"), + name="contact_group", + parameter_form=_contact_group_choice(), + ), + CascadingSingleChoiceElement( + title=Title("Explicit email addresses"), + name="explicit_email_addresses", + parameter_form=ListOfStrings( + layout=ListOfStringsLayout.vertical, + string_spec=String(custom_validate=[EmailAddress()]), + ), + ), + CascadingSingleChoiceElement( + title=Title("Restrict previous options to"), + name="restrict_previous", + parameter_form=CascadingSingleChoice( + # TODO: add horizontal layout (CMK-18894) + prefill=DefaultValue("contact_group"), + elements=[ + CascadingSingleChoiceElement( + name="contact_group", + title=Title("Users of contact groups"), + parameter_form=ListOfStrings( + string_spec=_contact_group_choice(), + ), + ), + CascadingSingleChoiceElement( + name="custom_macros", + title=Title("Custom macros"), + parameter_form=ListExtended( + prefill=DefaultValue([]), + element_template=Tuple( + title=Title("Custom macro"), + elements=[ + String( + title=Title("Name of the macro"), + ), + String( + title=Title( + "Required match (regular expression)" + ), + ), + ], + ), + add_element_label=Label("Add condition"), + ), + ), + ], + ), + ), + CascadingSingleChoiceElement( + title=Title("Specific users"), + name="specific_users", + parameter_form=SingleChoice( + prefill=InputHint(Title("Select user")), + elements=[ + SingleChoiceElement( + name=ident, + title=Title(title), # pylint: disable=localization-of-non-literal-string + ) + for ident, title in _get_sorted_users() + ], + ), + ), + CascadingSingleChoiceElement( + title=Title("All users"), + name="all_users", + parameter_form=FixedValue(value=None), + ), + ], + ), + add_element_label=Label("Add recipient"), + editable_order=False, + custom_validate=[ + not_empty(error_msg=Message("Please add at least one recipient")) + ], + ), + ) + ] + + return QuickSetupStage( + title=_("Recipient"), + sub_title=_("Who should receive the notification?"), + configure_components=_components, + custom_validators=[], + recap=[recaps.recaps_form_spec], + button_label=_("Next step: Sending conditions"), + ) + + +def sending_conditions() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [] + + return QuickSetupStage( + title=_("Sending conditions"), + sub_title=_( + "Specify when and how notifications are sent based on frequency, timing, and " + "content criteria." + ), + configure_components=_components, + custom_validators=[], + recap=[], + button_label=_("Next step: General properties"), + ) + + +def _validate_documentation_url(value: str) -> None: + if not is_allowed_url(value, cross_domain=True, schemes=["http", "https"]): + raise ValidationError( + Message("Not a valid URL (Only http and https URLs are allowed)."), + ) + + +def general_properties() -> QuickSetupStage: + def _components() -> Sequence[Widget]: + return [ + FormSpecWrapper( + id=FormSpecId("general_properties"), + form_spec=DictionaryExtended( + layout=DictionaryLayout.two_columns, + elements={ + "description": DictElement( + required=True, + parameter_form=String( + title=Title("Description"), + field_size=FieldSize.LARGE, + ), + ), + "settings": DictElement( + required=True, + parameter_form=Dictionary( + title=Title("Settings"), + elements={ + "disable_rule": DictElement( + parameter_form=FixedValue( + title=Title("Disable rule"), value=None + ) + ), + "allow_users_to_disable": DictElement( + parameter_form=FixedValue( + title=Title( + "Allow users to deactivate this notification" + ), + value=None, + ) + ), + }, + ), + ), + "comment": DictElement( + required=True, + parameter_form=CommentTextArea( + title=Title("Comment"), + ), + ), + "documentation_url": DictElement( + required=True, + parameter_form=String( + title=Title("Documentation"), + field_size=FieldSize.LARGE, + custom_validate=(_validate_documentation_url,), + ), + ), + }, + ), + ) + ] + + return QuickSetupStage( + title=_("General properties"), + sub_title=_( + "Review your notification rule before applying it. They will take effect right " + 'away without "Activate changes".' + ), + configure_components=_components, + custom_validators=[], + recap=[recaps.recaps_form_spec], + button_label=_("Next step: Saving"), + ) + + +def save_and_test_action(all_stages_form_data: ParsedFormData) -> str: + return mode_url("test_notifications") + + +def save_and_new_action(all_stages_form_data: ParsedFormData) -> str: + return mode_url("test_notifications") + + +def register(quick_setup_registry: QuickSetupRegistry) -> None: + quick_setup_registry.register(quick_setup_notifications) + + +quick_setup_notifications = QuickSetup( + title=_("Notification rule"), + id=QuickSetupId("notification_rule"), + stages=[ + triggering_events, + filter_for_hosts_and_services, + notification_method, + recipient, + sending_conditions, + general_properties, + ], + save_actions=[ + QuickSetupSaveAction( + id="apply_and_test", + label=_("Apply & test notification rule"), + action=save_and_test_action, + ), + QuickSetupSaveAction( + id="apply_and_create_new", + label=_("Apply & create another rule"), + action=save_and_new_action, + ), + ], +) diff --git a/cmk/gui/wato/pages/password_store.py b/cmk/gui/wato/pages/password_store.py index 829bcc15728..440dfc760ea 100644 --- a/cmk/gui/wato/pages/password_store.py +++ b/cmk/gui/wato/pages/password_store.py @@ -30,7 +30,12 @@ ValueSpec, ) from cmk.gui.valuespec import Password as PasswordValuespec -from cmk.gui.wato.pages._simple_modes import SimpleEditMode, SimpleListMode, SimpleModeType +from cmk.gui.wato.pages._simple_modes import ( + convert_dict_elements_vs2fs, + SimpleEditMode, + SimpleListMode, + SimpleModeType, +) from cmk.gui.watolib.config_domain_name import ABCConfigDomain from cmk.gui.watolib.config_domains import ConfigDomainCore from cmk.gui.watolib.groups_io import load_contact_group_information @@ -38,6 +43,8 @@ from cmk.gui.watolib.password_store import PasswordStore from cmk.gui.watolib.passwords import sorted_contact_group_choices +from cmk.rulesets.v1.form_specs import DictElement + def register(mode_registry: ModeRegistry) -> None: mode_registry.register(ModePasswords) @@ -201,6 +208,9 @@ def _vs_mandatory_elements(self) -> list[DictionaryEntry]: return elements + def _mandatory_elements(self) -> dict[str, DictElement]: + return convert_dict_elements_vs2fs(self._vs_mandatory_elements()) + def _vs_individual_elements(self) -> list[DictionaryEntry]: if user.may("wato.edit_all_passwords"): admin_element: list[ValueSpec] = [ diff --git a/cmk/gui/wato/pages/pattern_editor.py b/cmk/gui/wato/pages/pattern_editor.py index 24f36bd4ca5..013397ccb41 100644 --- a/cmk/gui/wato/pages/pattern_editor.py +++ b/cmk/gui/wato/pages/pattern_editor.py @@ -41,15 +41,21 @@ from cmk.gui.watolib.rulesets import rules_grouped_by_folder, SingleRulesetRecursively from cmk.gui.watolib.search import ( ABCMatchItemGenerator, - match_item_generator_registry, MatchItem, + MatchItemGeneratorRegistry, MatchItems, ) from cmk.gui.watolib.utils import mk_repr -def register(mode_registry: ModeRegistry) -> None: +def register( + mode_registry: ModeRegistry, + match_item_generator_registry: MatchItemGeneratorRegistry, +) -> None: mode_registry.register(ModePatternEditor) + match_item_generator_registry.register( + MatchItemGeneratorLogfilePatternAnalyzer("logfile_pattern_analyzer") + ) class ModePatternEditor(WatoMode): @@ -378,8 +384,3 @@ def is_affected_by_change(_change_action_name: str) -> bool: @property def is_localization_dependent(self) -> bool: return True - - -match_item_generator_registry.register( - MatchItemGeneratorLogfilePatternAnalyzer("logfile_pattern_analyzer") -) diff --git a/cmk/gui/wato/pages/rulesets.py b/cmk/gui/wato/pages/rulesets.py index 1978e3daf28..092046fb485 100644 --- a/cmk/gui/wato/pages/rulesets.py +++ b/cmk/gui/wato/pages/rulesets.py @@ -49,9 +49,6 @@ RenderMode, ) from cmk.gui.form_specs.vue.visitors import DataOrigin - -# The following import will be fixed by the upcoming registry rework -from cmk.gui.form_specs.vue.visitors._registry import form_spec_registry from cmk.gui.hooks import call as call_hooks from cmk.gui.htmllib.generator import HTMLWriter from cmk.gui.htmllib.html import ExperimentalRenderMode, get_render_mode, html @@ -139,6 +136,7 @@ visible_rulesets, ) from cmk.gui.watolib.rulespecs import ( + FormSpecNotImplementedError, get_rulegroup, main_module_from_rulespec_group_name, MatchType, @@ -1445,7 +1443,7 @@ def _show_rule_frontend(form_spec: FormSpec) -> None: display_mode=RenderMode.READONLY, ) - render_mode, form_spec = _get_render_mode(self._rulespec.name, self._rulespec.valuespec) + render_mode, form_spec = _get_render_mode(self._rulespec) match render_mode: case ExperimentalRenderMode.BACKEND: _show_rule_backend() @@ -1813,20 +1811,17 @@ def render_hidden_if_locked(vs: ValueSpec, varprefix: str, value: object, locked html.close_div() -def _get_render_mode( - name: str, - valuespec: ValueSpec, -) -> tuple[ExperimentalRenderMode, FormSpec | None]: - # NOTE: This code is still experimental +def _get_render_mode(rulespec: Rulespec) -> tuple[ExperimentalRenderMode, FormSpec | None]: configured_mode = get_render_mode() if configured_mode == ExperimentalRenderMode.BACKEND: return configured_mode, None - if (form_spec := form_spec_registry.get(name.split(":")[-1])) is not None: - assert form_spec.rule_spec.parameter_form is not None - return configured_mode, form_spec.rule_spec.parameter_form() + try: + return configured_mode, rulespec.form_spec + except FormSpecNotImplementedError: + pass - return configured_mode, LegacyValueSpec(valuespec=valuespec) + return configured_mode, LegacyValueSpec(valuespec=rulespec.valuespec) class ABCEditRuleMode(WatoMode): @@ -2061,9 +2056,7 @@ def _update_rule_from_vars(self) -> HTTPRedirect | None: self._rule.update_conditions(rule_conditions) # VALUE - render_mode, registered_form_spec = _get_render_mode( - self._ruleset.name, self._ruleset.rulespec.valuespec - ) + render_mode, registered_form_spec = _get_render_mode(self._ruleset.rulespec) self._do_validate_on_render = True match render_mode: case ExperimentalRenderMode.FRONTEND | ExperimentalRenderMode.BACKEND_AND_FRONTEND: @@ -2183,10 +2176,7 @@ def _page_form(self) -> None: html.form_has_submit_button = True html.prevent_password_auto_completion() try: - # Experimental rendering: Only render form_spec if they are in the form_spec_registry - render_mode, registered_form_spec = _get_render_mode( - self._ruleset.name, self._ruleset.rulespec.valuespec - ) + render_mode, registered_form_spec = _get_render_mode(self._ruleset.rulespec) match render_mode: case ExperimentalRenderMode.BACKEND: valuespec.validate_datatype(self._rule.value, "ve") diff --git a/cmk/gui/wato/pages/user_profile/__init__.py b/cmk/gui/wato/pages/user_profile/__init__.py index ed9451aba02..2335037fa61 100644 --- a/cmk/gui/wato/pages/user_profile/__init__.py +++ b/cmk/gui/wato/pages/user_profile/__init__.py @@ -3,13 +3,21 @@ # 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 Callable + +from cmk.gui.main_menu import MegaMenuRegistry from cmk.gui.pages import PageRegistry +from cmk.gui.type_defs import TopicMenuTopic from . import async_replication, change_password, edit_profile, mega_menu, replicate, two_factor -def register(page_registry: PageRegistry) -> None: - mega_menu.register(page_registry) +def register( + page_registry: PageRegistry, + mega_menu_registry: MegaMenuRegistry, + user_menu_topics: Callable[[], list[TopicMenuTopic]], +) -> None: + mega_menu.register(page_registry, mega_menu_registry, user_menu_topics) two_factor.register(page_registry) two_factor.register(page_registry) edit_profile.register(page_registry) diff --git a/cmk/gui/wato/pages/user_profile/mega_menu.py b/cmk/gui/wato/pages/user_profile/mega_menu.py index 630d4b82ec6..5deded0e96c 100644 --- a/cmk/gui/wato/pages/user_profile/mega_menu.py +++ b/cmk/gui/wato/pages/user_profile/mega_menu.py @@ -5,18 +5,13 @@ """The user profile mega menu and related AJAX endpoints""" -import cmk.ccc.version as cmk_version - -import cmk.utils.paths - -if cmk_version.edition(cmk.utils.paths.omd_root) is cmk_version.Edition.CSE: - from cmk.gui.cse.utils.roles import user_may_see_saas_onboarding +from collections.abc import Callable from cmk.gui.exceptions import MKUserError from cmk.gui.http import request from cmk.gui.i18n import _, _l from cmk.gui.logged_in import user -from cmk.gui.main_menu import mega_menu_registry +from cmk.gui.main_menu import MegaMenuRegistry from cmk.gui.pages import AjaxPage, PageRegistry, PageResult from cmk.gui.type_defs import MegaMenu, TopicMenuItem, TopicMenuTopic from cmk.gui.userdb import remove_custom_attr, validate_start_url @@ -26,15 +21,25 @@ from cmk.gui.utils.urls import makeuri_contextless -def register(page_registry: PageRegistry) -> None: +def register( + page_registry: PageRegistry, + mega_menu_registry: MegaMenuRegistry, + user_menu_topics: Callable[[], list[TopicMenuTopic]], +) -> None: page_registry.register_page("ajax_ui_theme")(ModeAjaxCycleThemes) page_registry.register_page("ajax_sidebar_position")(ModeAjaxCycleSidebarPosition) page_registry.register_page("ajax_set_dashboard_start_url")(ModeAjaxSetStartURL) - if cmk_version.edition(cmk.utils.paths.omd_root) == cmk_version.Edition.CSE: - page_registry.register_page("ajax_saas_onboarding_button_toggle")( - ModeAjaxCycleSaasOnboardingButtonToggle + mega_menu_registry.register( + MegaMenu( + name="user", + title=_l("User"), + icon="main_user", + sort_index=20, + topics=user_menu_topics, + info_line=lambda: f"{user.id} ({'+'.join(user.role_ids)})", ) + ) def _get_current_theme_title() -> str: @@ -52,17 +57,6 @@ def _get_sidebar_position() -> str: return sidebar_position or "right" -def _get_saas_onboarding_visibility_status() -> str | None: - assert user.id is not None - saas_onboarding_button_toggle = load_custom_attr( - user_id=user.id, - key="ui_saas_onboarding_button_toggle", - parser=lambda x: None if x == "None" else x, - ) - - return saas_onboarding_button_toggle - - def _sidebar_position_title(stored_value: str) -> str: return _("Left") if stored_value == "left" else _("Right") @@ -71,7 +65,9 @@ def _sidebar_position_id(stored_value: str) -> str: return "left" if stored_value == "left" else "right" -def _user_menu_topics() -> list[TopicMenuTopic]: +def default_user_menu_topics( + add_change_password_menu_item: bool = True, add_two_factor_menu_item: bool = True +) -> list[TopicMenuTopic]: quick_items = [ TopicMenuItem( name="ui_theme", @@ -93,25 +89,6 @@ def _user_menu_topics() -> list[TopicMenuTopic]: ), ] - if cmk_version.edition( - cmk.utils.paths.omd_root - ) == cmk_version.Edition.CSE and user_may_see_saas_onboarding(user.id): - quick_items.append( - TopicMenuItem( - name="saas_onboarding_button_toggle", - title=_("Toggle onboarding button"), - url='javascript:cmk.sidebar.toggle_user_attribute("ajax_saas_onboarding_button_toggle.py")', - target="", - sort_index=30, - icon="sidebar_position", - button_title=( - _("Visible") - if _get_saas_onboarding_visibility_status() is None - else _("Invisible") - ), - ), - ) - items = [ TopicMenuItem( name="user_profile", @@ -122,24 +99,26 @@ def _user_menu_topics() -> list[TopicMenuTopic]: ), ] - if cmk_version.edition(cmk.utils.paths.omd_root) != cmk_version.Edition.CSE: - items.extend( - [ - TopicMenuItem( - name="change_password", - title=_("Change password"), - url="user_change_pw.py", - sort_index=30, - icon="topic_change_password", - ), - TopicMenuItem( - name="two_factor", - title=_("Two-factor authentication"), - url="user_two_factor_overview.py", - sort_index=30, - icon="topic_two_factor", - ), - ] + if add_change_password_menu_item: + items.append( + TopicMenuItem( + name="change_password", + title=_("Change password"), + url="user_change_pw.py", + sort_index=30, + icon="topic_change_password", + ) + ) + + if add_two_factor_menu_item: + items.append( + TopicMenuItem( + name="two_factor", + title=_("Two-factor authentication"), + url="user_two_factor_overview.py", + sort_index=30, + icon="topic_two_factor", + ), ) items.append( @@ -167,13 +146,13 @@ def _user_menu_topics() -> list[TopicMenuTopic]: return [ TopicMenuTopic( - name="user", + name="user_interface", title=_("User interface"), icon="topic_user_interface", items=quick_items, ), TopicMenuTopic( - name="user", + name="user_profile", title=_("User profile"), icon="topic_profile", items=items, @@ -181,18 +160,6 @@ def _user_menu_topics() -> list[TopicMenuTopic]: ] -mega_menu_registry.register( - MegaMenu( - name="user", - title=_l("User"), - icon="main_user", - sort_index=20, - topics=_user_menu_topics, - info_line=lambda: f"{user.id} ({'+'.join(user.role_ids)})", - ) -) - - class ModeAjaxCycleThemes(AjaxPage): """AJAX handler for quick access option 'Interface theme" in user menu""" @@ -226,18 +193,6 @@ def page(self) -> PageResult: return {} -class ModeAjaxCycleSaasOnboardingButtonToggle(AjaxPage): - """AJAX handler for quick access option 'Toggle onboarding button" in user menu""" - - def page(self) -> PageResult: - check_csrf_token() - _set_user_attribute( - "ui_saas_onboarding_button_toggle", - (None if _get_saas_onboarding_visibility_status() == "invisible" else "invisible"), - ) - return {} - - class ModeAjaxSetStartURL(AjaxPage): """AJAX handler to set the start URL of a user to a dashboard""" diff --git a/cmk/gui/wato/registration.py b/cmk/gui/wato/registration.py index 9297ece46a9..5bf4958fe07 100644 --- a/cmk/gui/wato/registration.py +++ b/cmk/gui/wato/registration.py @@ -4,6 +4,8 @@ # conditions defined in the file COPYING, which is part of this source code package. +from collections.abc import Callable + from cmk.ccc import version from cmk.ccc.version import edition_supports_nagvis @@ -14,7 +16,9 @@ from cmk.gui.pages import PageRegistry from cmk.gui.painter.v0.base import PainterRegistry from cmk.gui.permissions import PermissionRegistry, PermissionSectionRegistry +from cmk.gui.quick_setup.v0_unstable._registry import QuickSetupRegistry from cmk.gui.sidebar import SnapinRegistry +from cmk.gui.type_defs import TopicMenuTopic from cmk.gui.views.icon import IconRegistry from cmk.gui.views.sorter import SorterRegistry from cmk.gui.visuals.filter import FilterRegistry @@ -26,6 +30,7 @@ ConfigVariableGroupRegistry, ConfigVariableRegistry, ) +from cmk.gui.watolib.config_sync import ReplicationPathRegistry from cmk.gui.watolib.groups import ContactGroupUsageFinderRegistry from cmk.gui.watolib.hosts_and_folders import ajax_popup_host_action_menu from cmk.gui.watolib.main_menu import MainModuleRegistry, MainModuleTopicRegistry @@ -74,6 +79,7 @@ def register( job_registry: BackgroundJobRegistry, filter_registry: FilterRegistry, mode_registry: ModeRegistry, + quick_setup_registry: QuickSetupRegistry, permission_section_registry: PermissionSectionRegistry, permission_registry: PermissionRegistry, main_module_topic_registry: MainModuleTopicRegistry, @@ -88,6 +94,10 @@ def register( ac_test_registry: ACTestRegistry, contact_group_usage_finder_registry: ContactGroupUsageFinderRegistry, notification_parameter_registry: NotificationParameterRegistry, + replication_path_registry: ReplicationPathRegistry, + user_menu_topics: Callable[[], list[TopicMenuTopic]], + edition_supports_ldap: bool, + edition_supports_managing_roles: bool, ) -> None: painter_registry.register(PainterHostFilename) painter_registry.register(PainterWatoFolderAbs) @@ -108,7 +118,18 @@ def register( ) filters.register(filter_registry) - wato_pages.register(page_registry, mode_registry, automation_command_registry, job_registry) + wato_pages.register( + page_registry, + mode_registry, + quick_setup_registry, + automation_command_registry, + job_registry, + match_item_generator_registry, + mega_menu_registry, + user_menu_topics, + edition_supports_ldap, + edition_supports_managing_roles, + ) _permissions.register(permission_section_registry, permission_registry) _main_module_topics.register(main_module_topic_registry) _main_modules.register(main_module_registry) @@ -120,7 +141,11 @@ def register( contact_group_usage_finder_registry, ) _ac_tests.register(ac_test_registry) - _omd_configuration.register(config_domain_registry, config_variable_registry) + _omd_configuration.register( + config_domain_registry, + config_variable_registry, + replication_path_registry, + ) _tracing.register(config_variable_registry) if edition_supports_nagvis(version.edition(paths.omd_root)): _nagvis_auth.register(permission_section_registry, permission_registry) diff --git a/cmk/gui/watolib/activate_changes.py b/cmk/gui/watolib/activate_changes.py index 4e2d8514c1d..c2edc705320 100644 --- a/cmk/gui/watolib/activate_changes.py +++ b/cmk/gui/watolib/activate_changes.py @@ -77,7 +77,14 @@ from cmk.gui.log import logger from cmk.gui.logged_in import user from cmk.gui.nodevis.utils import topology_dir -from cmk.gui.site_config import enabled_sites, get_site_config, is_single_local_site, site_is_local +from cmk.gui.site_config import ( + configured_sites, + enabled_sites, + get_site_config, + is_single_local_site, + is_wato_slave_site, + site_is_local, +) from cmk.gui.sites import SiteStatus from cmk.gui.sites import states as sites_states from cmk.gui.type_defs import Users @@ -89,7 +96,7 @@ from cmk.gui.utils.ntop import is_ntop_configured from cmk.gui.utils.request_context import copy_request_context from cmk.gui.utils.urls import makeuri_contextless -from cmk.gui.watolib import backup_snapshots, broker_certificates, config_domain_name, piggyback_hub +from cmk.gui.watolib import backup_snapshots, broker_certificates, config_domain_name from cmk.gui.watolib.audit_log import log_audit from cmk.gui.watolib.automation_commands import AutomationCommand from cmk.gui.watolib.broker_connections import BrokerConnectionsConfigFile @@ -105,22 +112,37 @@ create_distributed_wato_files, create_rabbitmq_definitions_file, get_site_globals, + replication_path_registry, ReplicationPath, + ReplicationPathRegistry, SnapshotSettings, ) -from cmk.gui.watolib.global_settings import save_site_global_settings +from cmk.gui.watolib.global_settings import load_configuration_settings, save_site_global_settings from cmk.gui.watolib.hosts_and_folders import ( collect_all_hosts, folder_preserving_link, + folder_tree, validate_all_hosts, ) from cmk.gui.watolib.paths import wato_var_dir +from cmk.gui.watolib.piggyback_hub import ( + distribute_piggyback_hub_configs as distribute_piggyback_hub_configs, # might be replcaed by the CME version +) +from cmk.gui.watolib.piggyback_hub import has_piggyback_hub_relevant_changes from cmk.gui.watolib.site_changes import ChangeSpec, SiteChanges from cmk import mkp_tool, trace from cmk.bi.type_defs import frozen_aggregations_dir +from cmk.crypto.certificate import CertificateWithPrivateKey from cmk.discover_plugins import addons_plugins_local_path, plugins_local_path -from cmk.messaging import rabbitmq +from cmk.messaging import ( + ca_key_file, + cacert_file, + rabbitmq, + site_cert_file, + trusted_cas_file, +) +from cmk.messaging.rabbitmq import DEFINITIONS_PATH as RABBITMQ_DEFINITIONS_PATH # TODO: Make private Phase = str # TODO: Make dedicated type @@ -148,14 +170,14 @@ ACTIVATION_TMP_BASE_DIR = str(cmk.utils.paths.tmp_dir / "wato/activation") ACTIVATION_PERISTED_DIR = cmk.utils.paths.var_dir + "/wato/activation" +RABBITMQ_DEFS_HASH_PATH = ACTIVATION_PERISTED_DIR + "/rabbitmq_defs_hash" +RABBITMQ_CERTS_HASH_PATH = ACTIVATION_PERISTED_DIR + "/rabbitmq_certs_hash" + var_dir = cmk.utils.paths.var_dir + "/wato/" GENERAL_DIR_EXCLUDE = "__pycache__" -# Directories and files to synchronize during replication -_replication_paths: list[ReplicationPath] = [] - ConfigWarnings = dict[ConfigDomainName, list[str]] ActivationId = str SiteActivationState = dict[str, Any] @@ -165,6 +187,11 @@ tracer = trace.get_tracer() +# might be replaced by the CME version +BrokerCertificateSync: type[broker_certificates.BrokerCertificateSync] = ( + broker_certificates.CREBrokerCertificateSync +) + class SiteReplicationStatus(TypedDict, total=False): last_activation: ActivationId | None @@ -191,24 +218,8 @@ def get_free_message(format_html: bool = False) -> str: return "{}\n{}{}".format(subject, body, "https://checkmk.com/contact") -# TODO: find a way to make this more obvious/transparent in code -def add_replication_paths(repl_paths: list[ReplicationPath]) -> None: - """Addition of any edition-specific replication paths (i.e. config files) that need - to be synchronised in a distributed set-up. - - This addition is done dynamically by the various edition plugins. - {enterprise,managed}/cmk/gui/{cee,cme}/plugins/wato - """ - _replication_paths.extend(repl_paths) - - -def get_replication_paths() -> list[ReplicationPath]: - """A list of replication paths common to all editions. - - NOTE: This list is enriched further by edition plugins. See - 'add_replication_paths'. - """ - repl_paths: list[ReplicationPath] = [ +def register(replication_path_registry_: ReplicationPathRegistry) -> None: + for repl_path in [ ReplicationPath( "dir", "check_mk", @@ -292,7 +303,7 @@ def get_replication_paths() -> list[ReplicationPath]: ReplicationPath( ty="dir", ident="rabbitmq", - site_path="etc/rabbitmq/definitions.d", + site_path=RABBITMQ_DEFINITIONS_PATH, excludes=["00-default.json"], ), ReplicationPath( @@ -319,18 +330,8 @@ def get_replication_paths() -> list[ReplicationPath]: site_path="etc/check_mk/piggyback_hub.d/wato", excludes=[], ), - ] - - # Include rule configuration into backup/restore/replication. Current - # status is not backed up. - if active_config.mkeventd_enabled: - _rule_pack_dir = str(ec.rule_pack_dir().relative_to(cmk.utils.paths.omd_root)) - repl_paths.append(ReplicationPath("dir", "mkeventd", _rule_pack_dir, [])) - - _mkp_rule_pack_dir = str(ec.mkp_rule_pack_dir().relative_to(cmk.utils.paths.omd_root)) - repl_paths.append(ReplicationPath("dir", "mkeventd_mkp", _mkp_rule_pack_dir, [])) - - return repl_paths + _replication_paths + ]: + replication_path_registry.register(repl_path) # If the site is not up-to-date, synchronize it first. @@ -1306,20 +1307,24 @@ def get_rabbitmq_definitions( return rabbitmq.compute_distributed_definitions(connection_info) -def create_broker_certificates(dirty_sites: list[tuple[SiteId, SiteConfiguration]]) -> None: - local_broker_ca = broker_certificates.load_or_create_broker_central_certs() - for site_id, settings in dirty_sites: - # only remote - if site_id == omd_site(): - continue +def create_and_activate_central_rabbitmq_changes( + rabbitmq_definitions: Mapping[str, rabbitmq.Definitions], +) -> None: + old_certs_hash = store.load_text_from_file(RABBITMQ_CERTS_HASH_PATH) + new_certs_hash = _create_broker_certs_hash() - if broker_certificates.broker_certs_created(site_id): - continue + old_definitions_hash = store.load_text_from_file(RABBITMQ_DEFS_HASH_PATH) + create_rabbitmq_definitions_file(paths.omd_root, rabbitmq_definitions[omd_site()]) + new_definitions_hash = _create_folder_content_hash( + str(paths.omd_root.joinpath(RABBITMQ_DEFINITIONS_PATH)) + ) - remote_broker_certs = broker_certificates.create_remote_broker_certs( - local_broker_ca, site_id, settings - ) - broker_certificates.sync_remote_broker_certs(settings, remote_broker_certs) + _restart_rabbitmq_when_changed( + old_certs_hash, new_certs_hash, old_definitions_hash, new_definitions_hash + ) + + store.save_text_to_file(RABBITMQ_CERTS_HASH_PATH, new_certs_hash) + store.save_text_to_file(RABBITMQ_DEFS_HASH_PATH, new_definitions_hash) class ActivateChangesManager(ActivateChanges): @@ -1385,28 +1390,6 @@ def load_activation(self, activation_id: ActivationId) -> None: for key in self.info_keys: setattr(self, key, from_file[key]) - def _distribute_piggyback_config(self) -> None: - def piggyback_config_change(change): - return ( - change["action_name"] == "edit-configvar" and "piggyback_hub" in change["domains"] - ) - - host_changes = ( - "edit-host", - "create-host", - "delete-host", - "rename-host", - "move-host", - "edit-folder", - ) - - if any( - piggyback_config_change(change) or change["action_name"] in host_changes - for _id, change in self._pending_changes - ): - logger.debug("Starting config distribution") - piggyback_hub.distribute_config() - # Creates the snapshot and starts the single site sync processes. In case these # steps could not be started, exceptions are raised and have to be handled by # the caller. @@ -1499,14 +1482,27 @@ def start( self._save_activation() self._start_activation() - create_broker_certificates(self.dirty_sites()) - self._distribute_piggyback_config() - create_rabbitmq_definitions_file(paths.omd_root, rabbitmq_definitions[omd_site()]) + create_and_activate_central_rabbitmq_changes(rabbitmq_definitions) + + if has_piggyback_hub_relevant_changes([change for _, change in self._pending_changes]): + logger.debug("Starting piggyback hub config distribution") + distribute_piggyback_hub_configs( + load_configuration_settings(), + configured_sites(), + {site_id for site_id, _site_config in self.dirty_sites()}, + { + host_name: host.site_id() + for host_name, host in folder_tree() + .root_folder() + .all_hosts_recursively() + .items() + }, + ) return self._activation_id def _verify_valid_host_config(self): - defective_hosts = validate_all_hosts([], force_all=True) + defective_hosts = validate_all_hosts(folder_tree(), [], force_all=True) if defective_hosts: raise MKUserError( None, @@ -2040,7 +2036,7 @@ def _clone_site_config_directories( copy_pool.starmap(_clone_site_config_directory, clone_args) def get_generic_components(self) -> list[ReplicationPath]: - return get_replication_paths() + return list(replication_path_registry.values()) def get_site_components( self, snapshot_settings: SnapshotSettings @@ -2307,7 +2303,7 @@ def _prepare_for_activation_tasks( source: ActivationSource, ) -> tuple[Mapping[SiteId, ConfigSyncFileInfos], Mapping[SiteId, SiteActivationState]]: config_sync_file_infos_per_inode = _get_config_sync_file_infos_per_inode( - get_replication_paths() + list(replication_path_registry.values()) ) central_file_infos_per_site = {} site_activation_states_per_site = {} @@ -2413,6 +2409,10 @@ def sync_and_activate( task_pool = ThreadPool(processes=len(site_snapshot_settings)) + site_activation_states = _create_broker_certificates_for_remote_sites( + omd_site(), site_activation_states, site_snapshot_settings, task_pool + ) + active_tasks = ActiveTasks( fetch_sync_state={}, calc_sync_delta={}, @@ -2475,6 +2475,82 @@ def sync_and_activate( _cleanup_activation(activation_site_id, activation_id, source) +def create_broker_certificates( + broker_cert_sync: broker_certificates.BrokerCertificateSync, + central_ca: CertificateWithPrivateKey, + customer_ca: CertificateWithPrivateKey | None, + settings: SiteConfiguration, + site_activation_state: SiteActivationState, + origin_span: trace.Span, +) -> SiteActivationState | None: + site_id = site_activation_state["_site_id"] + site_logger = logger.getChild(f"site[{site_id}]") + + with tracer.start_as_current_span( + f"create_broker_certificates[{site_id}]", + context=trace.set_span_in_context(origin_span), + ): + sync_start = time.time() + try: + _set_sync_state(site_activation_state, _("Syncing broker certificates")) + broker_cert_sync.create_broker_certificates(site_id, settings, central_ca, customer_ca) + return site_activation_state + except Exception as e: + duration = time.time() - sync_start + update_activation_time(site_id, ACTIVATION_TIME_SYNC, duration) + _handle_activation_changes_exception(site_logger, str(e), site_activation_state) + return None + + +def _create_broker_certificates_for_remote_sites( + myself: SiteId, + site_activation_states: Mapping[SiteId, SiteActivationState], + site_snapshot_settings: Mapping[SiteId, SnapshotSettings], + task_pool: ThreadPool, +) -> Mapping[SiteId, SiteActivationState]: + site_activation_states_certs_synced = dict(site_activation_states) + + broker_sync = BrokerCertificateSync() + if not ( + required_sites := broker_sync.get_site_to_sync( + myself, + [ + (site_id, settings.site_config) + for site_id, settings in site_snapshot_settings.items() + ], + ) + ): + return site_activation_states_certs_synced + + central_ca = broker_sync.load_central_ca() + map_args = [] + for customer, sites in required_sites.items(): + customer_ca = broker_sync.load_or_create_customer_ca(customer) # pylint: disable=assignment-from-none + for site_id, settings in sites: + map_args.append( + ( + broker_sync, + central_ca, + customer_ca, + settings, + site_activation_states[site_id], + trace.get_current_span(), + ) + ) + site_activation_states_certs_synced.pop(site_id) + + for result in task_pool.starmap( + copy_request_context(func=create_broker_certificates), + map_args, + ): + if result is None: + continue + site_activation_states_certs_synced[result["_site_id"]] = result + + broker_sync.update_trusted_cas() + return site_activation_states_certs_synced + + def _cleanup_activation( site_id: SiteId, activation_id: ActivationId, source: ActivationSource ) -> None: @@ -2648,10 +2724,69 @@ def execute_activate_changes(domain_requests: DomainRequests) -> ConfigWarnings: _add_extensions_for_license_usage() _update_links_for_agent_receiver() + # Only the remote sites are dealt with here, since the central site is dealt with separately. + # The rabbitmq definition of the central site has to be updated anytime the definition of a + # remote site is activated, not only when the central site is activated. + if is_wato_slave_site(): + _activate_local_rabbitmq_changes() return results +def _create_folder_content_hash(folder_path: str) -> str: + sha256_hash = hashlib.sha256() + for root, _dir, files in sorted(os.walk(folder_path)): + for filename in sorted(files): + file_path = os.path.join(root, filename) + with open(file_path, "rb") as f: + while chunk := f.read(8192): + sha256_hash.update(chunk) + + return sha256_hash.hexdigest() + + +def _create_broker_certs_hash() -> str: + sha256_hash = hashlib.sha256() + cert_file_paths = ( + trusted_cas_file(paths.omd_root), + cacert_file(paths.omd_root), + ca_key_file(paths.omd_root), + site_cert_file(paths.omd_root), + ) + for file_path in cert_file_paths: + if not file_path.exists(): + continue + with open(str(file_path), "rb") as f: + while chunk := f.read(8192): + sha256_hash.update(chunk) + + return sha256_hash.hexdigest() + + +def _restart_rabbitmq_when_changed( + old_certs_hash: str, new_certs_hash: str, old_definitions_hash: str, new_definitions_hash: str +) -> None: + if old_certs_hash != new_certs_hash or old_definitions_hash != new_definitions_hash: + subprocess.check_output(["omd", "restart", "rabbitmq"]) + + +def _activate_local_rabbitmq_changes(): + old_certs_hash = store.load_text_from_file(RABBITMQ_CERTS_HASH_PATH) + new_certs_hash = _create_broker_certs_hash() + + old_definitions_hash = store.load_text_from_file(RABBITMQ_DEFS_HASH_PATH) + new_definitions_hash = _create_folder_content_hash( + str(paths.omd_root.joinpath(RABBITMQ_DEFINITIONS_PATH)) + ) + + _restart_rabbitmq_when_changed( + old_certs_hash, new_certs_hash, old_definitions_hash, new_definitions_hash + ) + + store.save_text_to_file(RABBITMQ_CERTS_HASH_PATH, new_certs_hash) + store.save_text_to_file(RABBITMQ_DEFS_HASH_PATH, new_definitions_hash) + + def _add_extensions_for_license_usage(): save_extensions( LicenseUsageExtensions( @@ -2894,7 +3029,7 @@ def _get_replication_components(site_config: SiteConfiguration) -> list[Replicat particular site. """ - repl_paths = get_replication_paths()[:] + repl_paths = list(replication_path_registry.values()) # Remove Event Console settings, if this site does not want it (might # be removed in some future day) diff --git a/cmk/gui/watolib/appendstore.py b/cmk/gui/watolib/appendstore.py index 62b2d6ca0cc..377e9712186 100644 --- a/cmk/gui/watolib/appendstore.py +++ b/cmk/gui/watolib/appendstore.py @@ -26,6 +26,8 @@ class ABCAppendStore(Generic[_VT], abc.ABC): The file holds basic python structures separated by "\\0". """ + separator = b"\0" + @staticmethod @abc.abstractmethod def _serialize(entry: _VT) -> object: @@ -62,7 +64,7 @@ def __read(self) -> list[_VT]: with self._path.open("rb") as f: return [ self._deserialize(ast.literal_eval(entry.decode("utf-8"))) - for entry in f.read().split(b"\0") + for entry in f.read().split(self.separator) if entry ] except FileNotFoundError: @@ -87,7 +89,7 @@ def append(self, entry: _VT) -> None: with store.locked(self._path): try: with self._path.open("ab+") as f: - f.write(repr(self._serialize(entry)).encode("utf-8") + b"\0") + f.write(repr(self._serialize(entry)).encode("utf-8") + self.separator) f.flush() os.fsync(f.fileno()) self._path.chmod(0o660) diff --git a/cmk/gui/watolib/attributes.py b/cmk/gui/watolib/attributes.py index fae53ab1078..ed1aaec3cae 100644 --- a/cmk/gui/watolib/attributes.py +++ b/cmk/gui/watolib/attributes.py @@ -5,7 +5,8 @@ from cmk.ccc.exceptions import MKGeneralException -from cmk.gui.form_specs.private import LegacyValueSpec +from cmk.gui.form_specs.converter import SimplePassword +from cmk.gui.form_specs.private import not_empty from cmk.gui.i18n import _ from cmk.gui.valuespec import ( Alternative, @@ -58,11 +59,8 @@ def create_ipmi_parameters() -> form_specs.Dictionary: ), "password": form_specs.DictElement( required=True, - parameter_form=LegacyValueSpec.wrap( - Password( - title=_("Password"), - allow_empty=False, - ), + parameter_form=SimplePassword( + title=Title("Password"), custom_validate=[not_empty()] ), ), }, diff --git a/cmk/gui/watolib/audit_log.py b/cmk/gui/watolib/audit_log.py index 38e5d20fa46..faaa5c58110 100644 --- a/cmk/gui/watolib/audit_log.py +++ b/cmk/gui/watolib/audit_log.py @@ -47,6 +47,8 @@ class AuditLogFilterRaw(TypedDict, total=False): class AuditLogStore(ABCAppendStore["AuditLogStore.Entry"]): + separator = b"\n" + def __init__(self, filepath: Path = wato_var_dir() / "log" / "wato_audit.log") -> None: super().__init__(path=filepath) diff --git a/cmk/gui/watolib/automations.py b/cmk/gui/watolib/automations.py index e8e30f18872..3e96c0b6eec 100644 --- a/cmk/gui/watolib/automations.py +++ b/cmk/gui/watolib/automations.py @@ -11,6 +11,7 @@ import ast import json import logging +import os import re import subprocess import time @@ -136,6 +137,8 @@ def check_mk_local_automation_serialized( encoding="utf-8", input=stdin_data, check=False, + # Set the environment for the trace context (TRACEPARENT + optional TRACESTATE) + env=dict(os.environ) | trace.context_for_environment(), ) except Exception as e: raise local_automation_failure(command=command, cmdline=cmd, exc=e) diff --git a/cmk/gui/watolib/broker_certificates.py b/cmk/gui/watolib/broker_certificates.py index aaee0cb2eff..01fdb8a84d6 100644 --- a/cmk/gui/watolib/broker_certificates.py +++ b/cmk/gui/watolib/broker_certificates.py @@ -2,8 +2,9 @@ # 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. - -import traceback +import abc +from collections import defaultdict +from collections.abc import Mapping, Sequence from pathlib import Path from dateutil.relativedelta import relativedelta @@ -11,14 +12,12 @@ from livestatus import SiteConfiguration, SiteId from cmk.ccc import store -from cmk.ccc.exceptions import MKGeneralException from cmk.ccc.site import omd_site from cmk.utils import paths from cmk.utils.certs import save_single_cert from cmk.gui.http import request as _request -from cmk.gui.i18n import _ from cmk.gui.watolib.automation_commands import AutomationCommand from cmk.gui.watolib.automations import do_remote_automation @@ -32,76 +31,106 @@ BrokerCertificates, ca_key_file, cacert_file, - multisite_ca_key_file, - multisite_cacert_file, multisite_cert_file, - multisite_key_file, site_cert_file, site_key_file, + trusted_cas_file, ) +class BrokerCertificateSync(abc.ABC): + def load_central_ca(self) -> PersistedCertificateWithPrivateKey: + return load_broker_ca(paths.omd_root) + + @abc.abstractmethod + def broker_certs_created(self, site_id: SiteId, settings: SiteConfiguration) -> bool: + raise NotImplementedError + + @abc.abstractmethod + def get_site_to_sync( + self, myself: SiteId, dirty_sites: list[tuple[SiteId, SiteConfiguration]] + ) -> Mapping[str, Sequence[tuple[SiteId, SiteConfiguration]]]: + raise NotImplementedError + + @abc.abstractmethod + def load_or_create_customer_ca( + self, customer: str + ) -> PersistedCertificateWithPrivateKey | None: + raise NotImplementedError + + @abc.abstractmethod + def create_broker_certificates( + self, + site_id: SiteId, + settings: SiteConfiguration, + central_ca: CertificateWithPrivateKey, + customer_ca: CertificateWithPrivateKey | None, + ) -> None: + raise NotImplementedError + + @abc.abstractmethod + def update_trusted_cas(self) -> None: + raise NotImplementedError + + +class CREBrokerCertificateSync(BrokerCertificateSync): + def broker_certs_created(self, site_id: SiteId, settings: SiteConfiguration) -> bool: + return broker_certs_created(site_id) + + def get_site_to_sync( + self, myself: SiteId, dirty_sites: list[tuple[SiteId, SiteConfiguration]] + ) -> Mapping[str, Sequence[tuple[SiteId, SiteConfiguration]]]: + required_certificates: dict[str, list[tuple[SiteId, SiteConfiguration]]] = defaultdict(list) + for site_id, settings in dirty_sites: + if site_id != myself and not self.broker_certs_created(site_id, settings): + required_certificates["provider"].append((site_id, settings)) + return required_certificates + + def load_or_create_customer_ca( + self, customer: str + ) -> PersistedCertificateWithPrivateKey | None: + # Only relevant for editions with different customers + return None + + def create_broker_certificates( + self, + site_id: SiteId, + settings: SiteConfiguration, + central_ca: CertificateWithPrivateKey, + customer_ca: CertificateWithPrivateKey | None, + ) -> None: + remote_broker_certs = create_remote_broker_certs(central_ca, site_id, settings) + sync_remote_broker_certs(settings, remote_broker_certs) + # the presence of the following cert is used to determine if the broker certificates need + # to be created/synced, so only save it if the sync was successful + save_single_cert( + multisite_cert_file(paths.omd_root, site_id), + Certificate.load_pem(CertificatePEM(remote_broker_certs.cert)), + ) + + def update_trusted_cas(self) -> None: + # Only relevant for editions with different customers + pass + + def create_broker_certs( - cert_path: Path, key_path: Path, site_id: SiteId, ca: CertificateWithPrivateKey + site_id: SiteId, ca: CertificateWithPrivateKey ) -> CertificateWithPrivateKey: """ Create a new certificate for the broker of a site. - Just store the certificate and not the private key. """ - bundle = ca.issue_new_certificate( + return ca.issue_new_certificate( common_name=site_id, organization=f"Checkmk Site {omd_site()}", expiry=relativedelta(years=2), key_size=4096, ) - save_single_cert(cert_path, bundle.certificate) - - return bundle - - -def load_or_create_broker_central_certs() -> PersistedCertificateWithPrivateKey: - """ - Load, if present, or create a new certificate authority and certificate - with private key for the central-site broker. - """ - - key_path = multisite_ca_key_file(paths.omd_root) - cert_path = multisite_cacert_file(paths.omd_root) - - if key_path.exists() and cert_path.exists(): - return PersistedCertificateWithPrivateKey.read_files(cert_path, key_path) - - ca = CertificateWithPrivateKey.generate_self_signed( - common_name="Message broker CA", - organization=f"Checkmk Site {omd_site()}", - expiry=relativedelta(years=5), - key_size=4096, - is_ca=True, - ) - - # be sure the folder are created - cert_path.parent.mkdir(parents=True, exist_ok=True) - # saves ca to etc/rabbitmq/ssl/multisite - PersistedCertificateWithPrivateKey.persist(ca, cert_path, key_path) - - # saves certs to etc/rabbitmq/ssl/multisite - bundle = create_broker_certs( - multisite_cert_file(paths.omd_root, omd_site()), - multisite_key_file(paths.omd_root, omd_site()), - omd_site(), - ca, - ) - - # saves certs to etc/rabbitmq/ssl/ - PersistedCertificateWithPrivateKey.persist( - bundle, site_cert_file(paths.omd_root), site_key_file(paths.omd_root) - ) - # saves ca to etc/rabbitmq/ssl - return PersistedCertificateWithPrivateKey.persist( - ca, cacert_file(paths.omd_root), ca_key_file(paths.omd_root) +def load_broker_ca(omd_root: Path) -> PersistedCertificateWithPrivateKey: + return PersistedCertificateWithPrivateKey.read_files( + cacert_file(omd_root), ca_key_file(omd_root) ) @@ -110,22 +139,17 @@ def broker_certs_created(site_id: SiteId) -> bool: def create_remote_broker_certs( - central_site_ca: CertificateWithPrivateKey, site_id: SiteId, site: SiteConfiguration + signing_ca: CertificateWithPrivateKey, site_id: SiteId, site: SiteConfiguration ) -> BrokerCertificates: """ Create a new certificate with private key for the broker of a remote site. """ - cert_key = create_broker_certs( - multisite_cert_file(paths.omd_root, site_id), - multisite_key_file(paths.omd_root, site_id), - site_id, - central_site_ca, - ) + cert_key = create_broker_certs(site_id, signing_ca) return BrokerCertificates( - key=cert_key[1].dump_pem(None).bytes, - cert=cert_key[0].dump_pem().bytes, - central_ca=central_site_ca.certificate.dump_pem().bytes, + key=cert_key.private_key.dump_pem(None).bytes, + cert=cert_key.certificate.dump_pem().bytes, + signing_ca=signing_ca.certificate.dump_pem().bytes, ) @@ -153,21 +177,16 @@ def get_request(self) -> BrokerCertificates: return BrokerCertificates.model_validate_json(req) def execute(self, api_request: BrokerCertificates) -> bool: - try: - ca_bytes = api_request.central_ca - if api_request.customer_ca: - ca_bytes += api_request.customer_ca - ca = Certificate.load_pem(CertificatePEM(api_request.customer_ca)) - else: - ca = Certificate.load_pem(CertificatePEM(api_request.central_ca)) - Certificate.load_pem(CertificatePEM(api_request.cert)).verify_is_signed_by(ca) - - store.save_bytes_to_file(cacert_file(paths.omd_root), ca_bytes) - store.save_bytes_to_file(site_cert_file(paths.omd_root), api_request.cert) - store.save_bytes_to_file(site_key_file(paths.omd_root), api_request.key) - except Exception: - raise MKGeneralException( - _("Failed to save broker certificates: %s") % traceback.format_exc() - ) + ca = Certificate.load_pem(CertificatePEM(api_request.signing_ca)) + Certificate.load_pem(CertificatePEM(api_request.cert)).verify_is_signed_by(ca) + + store.save_bytes_to_file( + trusted_cas_file(paths.omd_root), + api_request.signing_ca + api_request.additionally_trusted_ca, + ) + store.save_bytes_to_file(site_cert_file(paths.omd_root), api_request.cert) + store.save_bytes_to_file(site_key_file(paths.omd_root), api_request.key) + cacert_file(paths.omd_root).unlink(missing_ok=True) + ca_key_file(paths.omd_root).unlink(missing_ok=True) return True diff --git a/cmk/gui/watolib/builtin_attributes.py b/cmk/gui/watolib/builtin_attributes.py index bbc2c80f53d..374f1046f54 100644 --- a/cmk/gui/watolib/builtin_attributes.py +++ b/cmk/gui/watolib/builtin_attributes.py @@ -18,11 +18,16 @@ from cmk.gui.form_specs.generators.host_address import create_host_address from cmk.gui.form_specs.generators.setup_site_choice import create_setup_site_choice from cmk.gui.form_specs.generators.snmp_credentials import create_snmp_credentials +from cmk.gui.form_specs.private import ( + ListOfStrings as FSListOfStrings, +) from cmk.gui.form_specs.private import ( OptionalChoice, SingleChoiceElementExtended, SingleChoiceExtended, + StringAutocompleter, ) +from cmk.gui.form_specs.vue.shared_type_defs import Autocompleter from cmk.gui.htmllib.generator import HTMLWriter from cmk.gui.i18n import _ from cmk.gui.logged_in import user @@ -485,6 +490,30 @@ def valuespec(self) -> ValueSpec: orientation="horizontal", ) + def form_spec(self) -> FSListOfStrings: + return FSListOfStrings( + title=Title("Parents"), + help_text=Help( + "Parents are used to configure the reachability of hosts to the " + "monitoring server. A host is considered unreachable if all of " + "its parents are unreachable or down. Unreachable hosts are not " + "actively monitored.

Clusters automatically " + "configure all their nodes as Parents, but only if you do not " + "manually configure Parents.

Distributed " + "setup:
Make sure that the host and all its parents are " + "monitored by the same site." + ), + string_spec=StringAutocompleter( + autocompleter=Autocompleter( + fetch_method="ajax_vs_autocomplete", + data={ + "ident": "config_hostname", + "params": {"strict": False, "escape_regex": False}, + }, + ), + ), + ) + def openapi_field(self) -> gui_fields.Field: return fields.List( gui_fields.HostField(should_exist=True, skip_validation_on_view=True), @@ -1420,7 +1449,7 @@ class HostAttributeDiscoveryFailed(ABCHostAttributeValueSpec): def name(self) -> str: return "inventory_failed" - def topic(self) -> type[HostAttributeTopic]: + def topic(self) -> type[HostAttributeTopicMetaData]: return HostAttributeTopicMetaData @classmethod @@ -1475,6 +1504,65 @@ def get_tag_groups(self, value): return {} +class HostAttributeWaitingForDiscovery(ABCHostAttributeValueSpec): + def name(self) -> str: + return "waiting_for_discovery" + + def topic(self) -> type[HostAttributeTopic]: + return HostAttributeTopicCustomAttributes + + @classmethod + def sort_index(cls) -> int: + return 210 + + def show_in_table(self): + return False + + def show_in_form(self): + return False + + def show_on_create(self): + return False + + def show_in_folder(self): + return False + + def show_in_host_search(self): + return False + + def show_inherited_value(self): + return False + + def editable(self): + return False + + def openapi_editable(self) -> bool: + return True + + def valuespec(self) -> ValueSpec: + return Checkbox( + title=_("Waiting for discovery"), + help=self._help_text(), + default_value=False, + ) + + def openapi_field(self) -> gui_fields.Field: + return fields.Boolean( + example=False, + required=False, + description=self._help_text(), + ) + + def _help_text(self) -> str: + return _( + "Indicates that host is waiting for bulk discovery. It is set to True once it in queue." + "Removed after discovery is ended." + ) + + def get_tag_groups(self, value): + return {} + + class HostAttributeLabels(ABCHostAttributeValueSpec): def name(self) -> str: return "labels" diff --git a/cmk/gui/watolib/config_domains.py b/cmk/gui/watolib/config_domains.py index cb08a6bee0e..5cb7597cf91 100644 --- a/cmk/gui/watolib/config_domains.py +++ b/cmk/gui/watolib/config_domains.py @@ -309,15 +309,18 @@ def config_dir(self): @staticmethod def log_changes( - config_before: TrustedCertificateAuthorities, + config_before: TrustedCertificateAuthorities | None, config_after: TrustedCertificateAuthorities, ) -> None: - current_certs = { - (cert := ConfigDomainCACertificates._load_cert(value)).fingerprint( - HashAlgorithm.Sha256 - ): cert - for value in config_before["trusted_cas"] - } + if config_before is None: + current_certs = {} + else: + current_certs = { + (cert := ConfigDomainCACertificates._load_cert(value)).fingerprint( + HashAlgorithm.Sha256 + ): cert + for value in config_before["trusted_cas"] or [] + } new_certs = { (cert := ConfigDomainCACertificates._load_cert(value)).fingerprint( diff --git a/cmk/gui/watolib/config_sync.py b/cmk/gui/watolib/config_sync.py index f82699767c0..356006bf9d1 100644 --- a/cmk/gui/watolib/config_sync.py +++ b/cmk/gui/watolib/config_sync.py @@ -21,6 +21,7 @@ import cmk.ccc.version as cmk_version from cmk.ccc import store from cmk.ccc.exceptions import MKGeneralException +from cmk.ccc.plugin_registry import Registry import cmk.utils.paths @@ -64,6 +65,14 @@ def __new__(cls, ty: str, ident: str, site_path: str, excludes: list[str]) -> "R ) +class ReplicationPathRegistry(Registry[ReplicationPath]): + def plugin_name(self, instance: ReplicationPath) -> str: + return instance.ident + + +replication_path_registry = ReplicationPathRegistry() + + class SnapshotSettings(NamedTuple): # TODO: Refactor to Path snapshot_path: str diff --git a/cmk/gui/watolib/configuration_bundles.py b/cmk/gui/watolib/configuration_bundles.py index 34beb10d223..f0b774629f1 100644 --- a/cmk/gui/watolib/configuration_bundles.py +++ b/cmk/gui/watolib/configuration_bundles.py @@ -56,19 +56,24 @@ class DomainDefinition: ALL_ENTITIES: set[Entity] = set(get_args(Entity)) -BUNDLE_DOMAINS: Mapping[RuleGroupType, set[DomainDefinition]] = { - RuleGroupType.SPECIAL_AGENTS: { + + +def bundle_domains() -> Mapping[RuleGroupType, set[DomainDefinition]]: + domains: set[DomainDefinition] = { DomainDefinition(entity="host", permission="hosts"), DomainDefinition(entity="rule", permission="rulesets"), DomainDefinition(entity="password", permission="passwords"), - DomainDefinition(entity="dcd", permission="dcd_connections"), } -} + + if DCDConnectionHook.domain_definition is not None: + domains.update({DCDConnectionHook.domain_definition}) + + return {RuleGroupType.SPECIAL_AGENTS: domains} def _get_affected_entities(bundle_group: str) -> set[Entity]: rule_group_type = RuleGroupType(bundle_group.split(":", maxsplit=1)[0]) - bundle_domain = BUNDLE_DOMAINS.get(rule_group_type, None) + bundle_domain = bundle_domains().get(rule_group_type, None) return set(domain.entity for domain in bundle_domain) if bundle_domain else ALL_ENTITIES @@ -97,6 +102,14 @@ class CreateDCDConnection(TypedDict): @dataclass class CreateBundleEntities: + """ + + Remarks for Special agents: + * when creating a special agent rule, the user may select an existing password. In such, + cases the password shouldn't be part of the bundle, as deletion of the bundle should leave + the password untouched. + """ + hosts: Iterable[CreateHost] | None = None passwords: Iterable[CreatePassword] | None = None rules: Iterable[CreateRule] | None = None @@ -111,6 +124,7 @@ class DCDConnectionHook: load_dcd_connections: Callable[[], DCDConnectionDict] = lambda: {} create_dcd_connection: Callable[[str, DCDConnectionSpec], None] = _dcd_unsupported delete_dcd_connection: Callable[[str], None] = _dcd_unsupported + domain_definition: DomainDefinition | None = None @dataclass @@ -124,7 +138,7 @@ class BundleReferences: def valid_special_agent_bundle(bundle: BundleReferences) -> bool: host_conditions = bundle.hosts is not None and len(bundle.hosts) == 1 rule_conditions = bundle.rules is not None and len(bundle.rules) == 1 - password_conditions = bundle.passwords is not None and len(bundle.passwords) == 1 + password_conditions = bundle.passwords is None or len(bundle.passwords) == 1 if not host_conditions or not rule_conditions or not password_conditions: return False return True @@ -431,7 +445,8 @@ class ConfigBundle(TypedDict): """ A configuration bundle is a collection of configs which are managed together by this bundle. Each underlying config must have the locked_by attribute set to the id of the bundle. We - explicitly avoid double references here to keep the data model simple. The group and program + explicitly avoid double references (for now: but might have to be considered in the context + of performance restrictions) here to keep the data model simple. The group and program combination should determine which configuration objects are potentially part of the bundle. """ diff --git a/cmk/gui/watolib/custom_attributes.py b/cmk/gui/watolib/custom_attributes.py index 08ccf3561bb..b20ef77f02b 100644 --- a/cmk/gui/watolib/custom_attributes.py +++ b/cmk/gui/watolib/custom_attributes.py @@ -51,7 +51,7 @@ def update_host_custom_attrs(): load_config() tree = folder_tree() tree.invalidate_caches() - tree.root_folder().rewrite_hosts_files() + tree.root_folder().recursively_save_hosts() def load_custom_attrs_from_mk_file(lock: bool) -> CustomAttrSpecs: diff --git a/cmk/gui/watolib/host_attributes.py b/cmk/gui/watolib/host_attributes.py index 0564264d433..e3fe78d3230 100644 --- a/cmk/gui/watolib/host_attributes.py +++ b/cmk/gui/watolib/host_attributes.py @@ -36,6 +36,7 @@ from cmk.gui.config import active_config from cmk.gui.exceptions import MKUserError +from cmk.gui.form_specs.converter import TransformForLegacyData from cmk.gui.form_specs.private import SingleChoiceElementExtended, SingleChoiceExtended from cmk.gui.htmllib.html import html from cmk.gui.http import request @@ -46,8 +47,8 @@ from cmk.gui.watolib.utils import host_attribute_matches from cmk.fields import String -from cmk.rulesets.v1 import Title -from cmk.rulesets.v1.form_specs import DefaultValue, FormSpec +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import BooleanChoice, DefaultValue, FormSpec _ContactgroupName = str @@ -140,6 +141,7 @@ class HostAttributes(TypedDict, total=False): locked_attributes: Sequence[str] meta_data: MetaData inventory_failed: bool + waiting_for_discovery: bool labels: Labels contactgroups: HostContactGroupSpec # Enterprise editions only @@ -156,6 +158,24 @@ class HostAttributes(TypedDict, total=False): tag_criticality: str +def mask_attributes(attributes: Mapping[str, object]) -> dict[str, object]: + """Create a copy of the given attributes and mask credential data""" + + MASK_STRING = "******" + + masked = dict(attributes) + if "snmp_community" in masked: + masked["snmp_community"] = MASK_STRING + if "management_snmp_community" in masked: + masked["management_snmp_community"] = MASK_STRING + if ipmi := masked.get("management_ipmi_credentials"): + username = ipmi.get("username", None) if isinstance(ipmi, dict) else None + masked["management_ipmi_credentials"] = IPMICredentials( + username=username or "(Unknown)", password=MASK_STRING + ) + return masked + + class HostAttributeTopic(abc.ABC): @property @abc.abstractmethod @@ -1107,21 +1127,18 @@ def valuespec(self) -> Transform: from_valuespec=lambda s: self._tag_value() if s is True else None, ) - def form_spec(self) -> SingleChoiceExtended: - return SingleChoiceExtended( - title=Title( # pylint: disable=localization-of-non-literal-string - self._tag_group.title + def form_spec(self) -> TransformForLegacyData: + return TransformForLegacyData( + wrapped_form_spec=BooleanChoice( + title=Title( # pylint: disable=localization-of-non-literal-string + self._tag_group.title + ), + label=Label( # pylint: disable=localization-of-non-literal-string + self._tag_group.get_tag_choices()[0][1] + ), ), - elements=[ - SingleChoiceElementExtended( - name=self._tag_value(), - title=Title( # pylint: disable=localization-of-non-literal-string - self._tag_group.title - ), - ) - ], - prefill=DefaultValue(self._tag_value()), - type=str, + from_disk=lambda s: s == self._tag_value(), + to_disk=lambda s: self._tag_value() if s is True else None, ) @property diff --git a/cmk/gui/watolib/host_rename.py b/cmk/gui/watolib/host_rename.py index ba734264f04..2b72f6070e1 100644 --- a/cmk/gui/watolib/host_rename.py +++ b/cmk/gui/watolib/host_rename.py @@ -78,23 +78,35 @@ def update_interface(message: str) -> None: job_interface.send_progress_update(message) actions: list[str] = [] - all_hosts = list(Host.all().values()) # 1. Fix Setup configuration itself ---------------- auth_problems = [] successful_renamings = [] update_interface(_("Renaming Setup configuration...")) - for folder, oldname, newname in renamings: + + setup_actions: dict[tuple[Folder, HostName, HostName], list[str]] = {} + for renaming in renamings: + folder, oldname, newname = renaming try: - this_host_actions = [] update_interface(_("Renaming host(s) in folders...")) - this_host_actions += _rename_host_in_folder(folder, oldname, newname) + setup_actions[renaming] = _rename_host_in_folder(folder, oldname, newname) + except MKAuthException as e: + auth_problems.append((oldname, e)) + + # Precompute cluster host list for node renaming due to expensive Host.all() + # call. This currently also needs to be done after the host renaming as the + # folder_tree cache_invalidation still misses some caches. + cluster_hosts = [host for host in Host.all().values() if host.is_cluster()] + + for renaming, this_host_actions in setup_actions.items(): + folder, oldname, newname = renaming + try: update_interface(_("Renaming host(s) in cluster nodes...")) - this_host_actions += _rename_host_as_cluster_node(all_hosts, oldname, newname) + this_host_actions.extend(_rename_host_as_cluster_node(cluster_hosts, oldname, newname)) update_interface(_("Renaming host(s) in parents...")) - this_host_actions += _rename_parents(oldname, newname) + this_host_actions.extend(_rename_parents(oldname, newname)) update_interface(_("Renaming host(s) in rulesets...")) - this_host_actions += _rename_host_in_rulesets(oldname, newname) + this_host_actions.extend(_rename_host_in_rulesets(oldname, newname)) for hook in rename_host_hook_registry.hooks_by_phase(RenamePhase.SETUP): update_interface(_("Renaming host(s) in %s...") % hook.title) @@ -144,16 +156,13 @@ def _rename_host_in_folder(folder: Folder, oldname: HostName, newname: HostName) def _rename_host_as_cluster_node( - all_hosts: Iterable[Host], oldname: HostName, newname: HostName + cluster_hosts: list[Host], oldname: HostName, newname: HostName ) -> list[str]: - clusters = [] - for somehost in all_hosts: - if somehost.is_cluster(): - if somehost.rename_cluster_node(oldname, newname): - clusters.append(somehost.name()) - if clusters: - return ["cluster_nodes"] * len(clusters) - return [] + renamed_cluster_nodes = 0 + for cluster_host in cluster_hosts: + if cluster_host.rename_cluster_node(oldname, newname): + renamed_cluster_nodes += 1 + return ["cluster_nodes"] * renamed_cluster_nodes def _rename_parents( @@ -166,7 +175,7 @@ def _rename_parents( # Needed because hosts.mk in folders with parent as effective attribute # would not be updated for folder in folder_parent_renamed: - folder.rewrite_hosts_files() + folder.recursively_save_hosts() return parent_renamed diff --git a/cmk/gui/watolib/hosts_and_folders.py b/cmk/gui/watolib/hosts_and_folders.py index 2bcdfc3009c..16dfcd1dfb8 100644 --- a/cmk/gui/watolib/hosts_and_folders.py +++ b/cmk/gui/watolib/hosts_and_folders.py @@ -49,7 +49,7 @@ ) from cmk.utils.hostaddress import HostName from cmk.utils.labels import Labels -from cmk.utils.object_diff import make_diff_text +from cmk.utils.object_diff import make_diff, make_diff_text from cmk.utils.redis import get_redis_client, redis_enabled, redis_server_reachable from cmk.utils.regex import regex, WATO_FOLDER_PATH_NAME_CHARS, WATO_FOLDER_PATH_NAME_REGEX from cmk.utils.tags import TagGroupID, TagID @@ -89,13 +89,13 @@ host_attribute_registry, HostAttributes, HostContactGroupSpec, + mask_attributes, MetaData, ) from cmk.gui.watolib.objref import ObjectRef, ObjectRefType from cmk.gui.watolib.predefined_conditions import PredefinedConditionStore from cmk.gui.watolib.search import ( ABCMatchItemGenerator, - match_item_generator_registry, MatchItem, MatchItems, ) @@ -984,6 +984,12 @@ def root_folder(self) -> Folder: return self.folder("") def invalidate_caches(self) -> None: + # Attention: This will not invalidate all folder caches. (CMK-19211) + # You might have some references in your code which are not part of the + # root_folder() hierarchy since the root folder python object is + # regenerated after calling this method (since we are dropping + # "wato_folders"), losing all references to its subfolders. This leads + # to the recursive .drop_caches missing them them. self.root_folder().drop_caches() if may_use_redis(): get_wato_redis_client(self).clear_cached_folders() @@ -1462,13 +1468,10 @@ def _folder_attributes_for_base_config(self) -> dict[str, FolderAttributesForBas } return {} - def save(self, is_custom_folder: bool = False) -> None: - self.persist_instance() - if is_custom_folder: - # save a folder that is used only temporarily for a specific purpose (e.g. syncing to - # remote sites) -> skip further saving functionality (e.g. communicating with redis) - return - folder_tree().invalidate_caches() + def save(self) -> None: + self.save_folder_attributes() + self.tree.invalidate_caches() + self.save_hosts() def serialize(self) -> WATOFolderInfo: return { @@ -1547,7 +1550,7 @@ def wato_info_storage_manager(cls) -> _WATOInfoStorageManager: g.wato_info_storage_manager = _WATOInfoStorageManager() return g.wato_info_storage_manager - def persist_instance(self) -> None: + def save_folder_attributes(self) -> None: """Save the current state of the instance to a file.""" self.attributes = update_metadata(self.attributes) store.makedirs(os.path.dirname(self.wato_info_path())) @@ -1627,7 +1630,7 @@ def has_hosts(self) -> bool: return len(self.hosts()) != 0 def host_validation_errors(self) -> dict[HostName, list[str]]: - return validate_all_hosts(self.host_names()) + return validate_all_hosts(self.tree, self.host_names()) def has_parent(self) -> bool: return self.parent() is not None @@ -1806,7 +1809,7 @@ def _choices_for_moving(self, what: str) -> Choices: get_wato_redis_client(self.tree).choices_for_moving(self.path(), _MoveType(what)) ) - for folder in folder_tree().all_folders().values(): + for folder in self.tree.all_folders().values(): if not folder.permissions.may("write"): continue if folder.is_same_as(self): @@ -2168,16 +2171,12 @@ def create_subfolder(self, name: str, title: str, attributes: HostAttributes) -> ) self._subfolders[name] = new_subfolder new_subfolder.save() - new_subfolder.save_hosts() add_change( "new-folder", _l("Created new folder %s") % new_subfolder.alias_path(), object_ref=new_subfolder.object_ref(), sites=[new_subfolder.site_id()], - diff_text=make_diff_text( - make_folder_audit_log_object({}), - make_folder_audit_log_object(new_subfolder.attributes), - ), + diff_text=diff_attributes({}, None, new_subfolder.attributes, None), ) hooks.call("folder-created", new_subfolder) need_sidebar_reload() @@ -2206,7 +2205,7 @@ def delete_subfolder(self, name: str) -> None: ) del self._subfolders[name] shutil.rmtree(subfolder.filesystem_path()) - folder_tree().invalidate_caches() + self.tree.invalidate_caches() need_sidebar_reload() folder_lookup_cache().delete() @@ -2251,7 +2250,7 @@ def move_subfolder_to(self, subfolder: Folder, target_folder: Folder) -> None: old_filesystem_path = subfolder.filesystem_path() shutil.move(old_filesystem_path, target_folder.filesystem_path()) - folder_tree().invalidate_caches() + self.tree.invalidate_caches() # Since redis only updates on the next request, we can no longer use it here # We COULD enforce a redis update here, but this would take too much time @@ -2260,13 +2259,13 @@ def move_subfolder_to(self, subfolder: Folder, target_folder: Folder) -> None: # Reload folder at new location and rewrite host files # Again, some special handling because of the missing slash in the main folder if not target_folder.is_root(): - moved_subfolder = folder_tree().folder(f"{target_folder.path()}/{subfolder.name()}") + moved_subfolder = self.tree.folder(f"{target_folder.path()}/{subfolder.name()}") else: - moved_subfolder = folder_tree().folder(subfolder.name()) + moved_subfolder = self.tree.folder(subfolder.name()) # Do not update redis while rewriting a plethora of host files # Redis automatically updates on the next request - moved_subfolder.rewrite_hosts_files() # fixes changed inheritance + moved_subfolder.recursively_save_hosts() # fixes changed inheritance affected_sites = list(set(affected_sites + moved_subfolder.all_site_ids())) add_change( @@ -2310,7 +2309,7 @@ def edit(self, new_title: str, new_attributes: HostAttributes) -> None: # to the new mapping. affected_sites = self.all_site_ids() - old_object = make_folder_audit_log_object(self.attributes) + diff = diff_attributes(self.attributes, None, new_attributes, None) self._title = new_title self.attributes = new_attributes @@ -2318,8 +2317,9 @@ def edit(self, new_title: str, new_attributes: HostAttributes) -> None: # Due to changes in folder/file attributes, host files # might need to be rewritten in order to reflect Changes # in Nagios-relevant attributes. - self.save() - self.rewrite_hosts_files() + self.save_folder_attributes() + self.tree.invalidate_caches() + self.recursively_save_hosts() affected_sites = list(set(affected_sites + self.all_site_ids())) add_change( @@ -2327,7 +2327,7 @@ def edit(self, new_title: str, new_attributes: HostAttributes) -> None: _l("Edited properties of folder %s") % self.title(), object_ref=self.object_ref(), sites=affected_sites, - diff_text=make_diff_text(old_object, make_folder_audit_log_object(self.attributes)), + diff_text=diff, ) def prepare_create_hosts(self) -> None: @@ -2378,7 +2378,6 @@ def create_validated_hosts( self.propagate_hosts_changes(host_name, attributes, cluster_nodes) self.save() # num_hosts has changed - self.save_hosts() folder_path = self.path() folder_lookup_cache().add_hosts([(x[0], folder_path) for x in entries]) @@ -2402,14 +2401,13 @@ def propagate_hosts_changes( assert self._hosts is not None self._hosts[host_name] = host self._num_hosts = len(self._hosts) + add_change( "create-host", _l("Created new host %s.") % host_name, object_ref=host.object_ref(), sites=[host.site_id()], - diff_text=make_diff_text( - {}, make_host_audit_log_object(host.attributes, host.cluster_nodes()) - ), + diff_text=diff_attributes({}, None, host.attributes, host.cluster_nodes()), domain_settings=_generate_domain_settings("check_mk", [host_name]), ) @@ -2444,7 +2442,7 @@ def delete_hosts( sites=[host.site_id()], ) - self.persist_instance() # num_hosts has changed + self.save_folder_attributes() # num_hosts has changed self.save_hosts() folder_lookup_cache().delete_hosts(host_names) @@ -2459,7 +2457,7 @@ def _validate_delete_hosts( errors.extend(_("%s is locked by Quick setup.") % host_name for host_name in hosts) # 2. check if hosts have parents - if hosts_with_children := self._get_parents_of_hosts(host_names): + if hosts_with_children := self._get_parents_of_hosts(self.tree, host_names): errors.extend( _("%s is parent of %s.") % (parent, ", ".join(children)) for parent, children in sorted(hosts_with_children.items()) @@ -2480,11 +2478,13 @@ def _get_hosts_locked_by_quick_setup(host_names: Collection[HostName]) -> list[H ] @staticmethod - def _get_parents_of_hosts(host_names: Collection[HostName]) -> dict[HostName, list[HostName]]: + def _get_parents_of_hosts( + tree: FolderTree, host_names: Collection[HostName] + ) -> dict[HostName, list[HostName]]: # Note: Deletion of chosen hosts which are parents # is possible if and only if all children are chosen, too. hosts_with_children: dict[HostName, list[HostName]] = {} - for child_key, child in folder_tree().root_folder().all_hosts_recursively().items(): + for child_key, child in tree.root_folder().all_hosts_recursively().items(): for host_name in host_names: if host_name in child.parents(): hosts_with_children.setdefault(host_name, []) @@ -2539,8 +2539,8 @@ def move_hosts(self, host_names: Collection[HostName], target_folder: Folder) -> target_folder._add_host(host) affected_sites = list(set(affected_sites + [host.site_id()])) - old_folder_text = self.path() or folder_tree().root_folder().title() - new_folder_text = target_folder.path() or folder_tree().root_folder().title() + old_folder_text = self.path() or self.tree.root_folder().title() + new_folder_text = target_folder.path() or self.tree.root_folder().title() add_change( "move-host", _l('Moved host from "%s" (ID: %s) to "%s" (ID: %s)') @@ -2554,10 +2554,10 @@ def move_hosts(self, host_names: Collection[HostName], target_folder: Folder) -> sites=affected_sites, ) - self.persist_instance() # num_hosts has changed + self.save_folder_attributes() # num_hosts has changed self.save_hosts() - target_folder.persist_instance() + target_folder.save_folder_attributes() target_folder.save_hosts() folder_path = target_folder.path() @@ -2603,19 +2603,14 @@ def rename_parent(self, oldname, newname): object_ref=self.object_ref(), sites=self.all_site_ids(), ) - self.save_hosts() self.save() return True - def rewrite_hosts_files(self): - self._rewrite_hosts_file() - for subfolder in self.subfolders(): - subfolder.rewrite_hosts_files() - - def rewrite_folders(self): - self.persist_instance() + def recursively_save_hosts(self): + self._load_hosts_on_demand() + self.save_hosts() for subfolder in self.subfolders(): - subfolder.rewrite_folders() + subfolder.recursively_save_hosts() def _add_host(self, host): self._load_hosts_on_demand() @@ -2638,10 +2633,6 @@ def _add_all_sites_to_set(self, site_ids): for subfolder in self.subfolders(): subfolder._add_all_sites_to_set(site_ids) - def _rewrite_hosts_file(self): - self._load_hosts_on_demand() - self.save_hosts() - # .-----------------------------------------------------------------------. # | HTML Generation | # '-----------------------------------------------------------------------' @@ -2898,7 +2889,7 @@ def hosts(self) -> Mapping[HostName, Host]: return self._found_hosts def host_validation_errors(self) -> dict[HostName, list[str]]: - return validate_all_hosts(list(self.hosts().keys())) + return validate_all_hosts(self.tree, list(self.hosts().keys())) def load_host(self, host_name: HostName) -> Host: try: @@ -3223,6 +3214,9 @@ def tag(self, taggroup_name: TagGroupID) -> TagID | None: def discovery_failed(self) -> bool: return self.attributes.get("inventory_failed", False) + def is_waiting_for_discovery(self) -> bool: + return self.attributes.get("waiting_for_discovery", False) + def validation_errors(self) -> list[str]: if hooks.registered("validate-host"): errors = [] @@ -3347,8 +3341,7 @@ def edit(self, attributes: HostAttributes, cluster_nodes: Sequence[HostName] | N _get_cgconf_from_attributes(attributes)["groups"], ) - old_object = make_host_audit_log_object(self.attributes, self._cluster_nodes) - new_object = make_host_audit_log_object(attributes, cluster_nodes) + diff = diff_attributes(self.attributes, self._cluster_nodes, attributes, cluster_nodes) # 2. Actual modification affected_sites = [self.site_id()] @@ -3356,12 +3349,13 @@ def edit(self, attributes: HostAttributes, cluster_nodes: Sequence[HostName] | N self._cluster_nodes = cluster_nodes affected_sites = list(set(affected_sites + [self.site_id()])) self.folder().save_hosts() + add_change( "edit-host", _l("Modified host %s.") % self.name(), object_ref=self.object_ref(), sites=affected_sites, - diff_text=make_diff_text(old_object, new_object), + diff_text=diff, domain_settings=_generate_domain_settings("check_mk", [self.name()]), ) @@ -3376,7 +3370,8 @@ def clean_attributes(self, attrnames_to_clean: Sequence[str]) -> None: self._need_folder_write_permissions() self.need_unlocked() - old = make_host_audit_log_object(self.attributes.copy(), self._cluster_nodes) + old_attrs = self.attributes.copy() + old_nodes = self._cluster_nodes # 2. Actual modification affected_sites = [self.site_id()] @@ -3386,14 +3381,13 @@ def clean_attributes(self, attrnames_to_clean: Sequence[str]) -> None: del self.attributes[attrname] # type: ignore[misc] affected_sites = list(set(affected_sites + [self.site_id()])) self.folder().save_hosts() + add_change( "edit-host", _l("Removed explicit attributes of host %s.") % self.name(), object_ref=self.object_ref(), sites=affected_sites, - diff_text=make_diff_text( - old, make_host_audit_log_object(self.attributes, self._cluster_nodes) - ), + diff_text=diff_attributes(old_attrs, old_nodes, self.attributes, self._cluster_nodes), ) def _need_folder_write_permissions(self) -> None: @@ -3477,22 +3471,35 @@ def rename(self, new_name: HostName) -> None: self._name = new_name -def make_host_audit_log_object( - attributes: Mapping[str, object], cluster_nodes: Sequence[HostName] | None -) -> dict[str, object]: - """The resulting object is used for building object diffs""" - obj = {**attributes} - if cluster_nodes: - obj["nodes"] = cluster_nodes - obj.pop("meta_data", None) - return obj +def diff_attributes( + left_attributes: Mapping[str, object], + left_cluster_nodes: Sequence[HostName] | None, + right_attributes: Mapping[str, object], + right_cluster_nodes: Sequence[HostName] | None, +) -> str: + """Diff two sets of host attributes, masking secrets""" + # The diff has no type infomation, so in order to detect secrets, we have to mask them before + # diffing. However, all masked secrets look the same in the diff, so then we couldn't detect + # the changes anymore. + # To add them manually, see if masking changes the diff. If so, secrets must have changed. + (left_attributes := dict(left_attributes)).pop("meta_data", None) + if left_cluster_nodes: + left_attributes["nodes"] = left_cluster_nodes + (right_attributes := dict(right_attributes)).pop("meta_data", None) + if right_cluster_nodes: + right_attributes["nodes"] = right_cluster_nodes + + unmasked_diff = make_diff(left_attributes, right_attributes) + masked_diff = make_diff( + left_masked := mask_attributes(left_attributes), + right_masked := mask_attributes(right_attributes), + ) + if unmasked_diff == masked_diff: + # no special treatment needed + return make_diff_text(left_masked, right_masked) -def make_folder_audit_log_object(attributes: Mapping[str, object]) -> dict[str, object]: - """The resulting object is used for building object diffs""" - obj = {**attributes} - obj.pop("meta_data", None) - return obj + return (masked_diff + "\n" if masked_diff else "") + _("Redacted secrets changed.") def _validate_contact_group_modification( @@ -3545,7 +3552,7 @@ def call_hook_hosts_changed(folder: Folder) -> None: # The same with all hosts! if hooks.registered("all-hosts-changed"): - hosts = _collect_hosts(folder_tree().root_folder()) + hosts = _collect_hosts(folder.tree.root_folder()) hooks.call("all-hosts-changed", hosts) @@ -3554,11 +3561,11 @@ def call_hook_hosts_changed(folder: Folder) -> None: # symbols in the host list and the host detail view # Returns dictionary { hostname: [errors] } def validate_all_hosts( - hostnames: Sequence[HostName], force_all: bool = False + tree: FolderTree, hostnames: Sequence[HostName], force_all: bool = False ) -> dict[HostName, list[str]]: if hooks.registered("validate-all-hosts") and (len(hostnames) > 0 or force_all): hosts_errors: dict[HostName, list[str]] = {} - all_hosts = _collect_hosts(folder_tree().root_folder()) + all_hosts = _collect_hosts(tree.root_folder()) if force_all: hostnames = list(all_hosts.keys()) @@ -3712,14 +3719,6 @@ def is_localization_dependent(self) -> bool: return False -match_item_generator_registry.register( - MatchItemGeneratorHosts( - "hosts", - collect_all_hosts, - ) -) - - def rebuild_folder_lookup_cache() -> None: """Rebuild folder lookup cache around ~5AM This needs to be done, since the cachefile might include outdated/vanished hosts""" diff --git a/cmk/gui/watolib/network_scan.py b/cmk/gui/watolib/network_scan.py index d3f2729fb3e..c98663d70f2 100644 --- a/cmk/gui/watolib/network_scan.py +++ b/cmk/gui/watolib/network_scan.py @@ -159,7 +159,8 @@ def _add_scanned_hosts_to_folder( with store.lock_checkmk_configuration(configuration_lockfile): folder.create_hosts(entries) - folder.save() + folder.save_folder_attributes() + folder_tree().invalidate_caches() bakery.try_bake_agents_for_hosts(tuple(e[0] for e in entries)) @@ -171,7 +172,8 @@ def _save_network_scan_result(folder: Folder, result: NetworkScanResult) -> None # folder again to get the current state. write_folder = folder_tree().folder(folder.path()) write_folder.attributes["network_scan_result"] = result - write_folder.save() + write_folder.save_folder_attributes() + folder_tree().invalidate_caches() class AutomationNetworkScan(AutomationCommand[NetworkScanRequest]): diff --git a/cmk/gui/watolib/notification_parameter.py b/cmk/gui/watolib/notification_parameter.py new file mode 100644 index 00000000000..f2d8b8f3428 --- /dev/null +++ b/cmk/gui/watolib/notification_parameter.py @@ -0,0 +1,120 @@ +#!/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 dataclasses import dataclass +from typing import NamedTuple, Sequence + +from cmk.ccc.i18n import _ + +from cmk.utils.notify_types import ( + NotificationParameterGeneralInfos, + NotificationParameterID, + NotificationParameterItem, + NotificationParameterMethod, +) + +from cmk.gui.form_specs.vue import shared_type_defs +from cmk.gui.form_specs.vue.visitors import ( + DataOrigin, + DEFAULT_VALUE, + get_visitor, + VisitorOptions, +) +from cmk.gui.wato._notification_parameter._registry import NotificationParameterRegistry +from cmk.gui.watolib.notifications import NotificationParameterConfigFile +from cmk.gui.watolib.sample_config import new_notification_parameter_id + +INTERNAL_TRANSFORM_ERROR = _("FormSpec and internal data structure mismatch") + + +def _to_param_item(data: object) -> NotificationParameterItem: + if not isinstance(data, dict): + raise ValueError(INTERNAL_TRANSFORM_ERROR) + + try: + general = data["general"] + if not isinstance(general, dict): + raise ValueError(INTERNAL_TRANSFORM_ERROR) + + return NotificationParameterItem( + general=NotificationParameterGeneralInfos( + description=general["description"], + comment=general.get("comment", ""), + docu_url=general.get("docu_url", ""), + ), + parameter_properties=data["parameter_properties"], + ) + except KeyError as exc: + raise ValueError from exc + + +def save_notification_parameter( + registry: NotificationParameterRegistry, + parameter_method: NotificationParameterMethod, + data: object, + object_id: NotificationParameterID | None = None, +) -> NotificationParameterID | Sequence[shared_type_defs.ValidationMessage]: + form_spec = registry.form_spec(parameter_method) + visitor = get_visitor(form_spec, VisitorOptions(DataOrigin.FRONTEND)) + + validation_errors = visitor.validate(data) + if validation_errors: + return validation_errors + + disk_data = visitor.to_disk(data) + + try: + item = _to_param_item(disk_data) + except ValueError as exc: + return [ + shared_type_defs.ValidationMessage(location=[], message=str(exc), invalid_value=None) + ] + + parameter_id = ( + NotificationParameterID(object_id) if object_id else new_notification_parameter_id() + ) + config_file = NotificationParameterConfigFile() + notification_parameter = config_file.load_for_modification() + notification_parameter.setdefault(parameter_method, {})[parameter_id] = item + config_file.save(notification_parameter) + + return parameter_id + + +class NotificationParameterSchema(NamedTuple): + schema: shared_type_defs.FormSpec + default_values: object + + +def get_notification_parameter_schema( + registry: NotificationParameterRegistry, parameter_method: NotificationParameterMethod +) -> NotificationParameterSchema: + form_spec = registry.form_spec(parameter_method) + visitor = get_visitor(form_spec, VisitorOptions(DataOrigin.FRONTEND)) + schema, default_values = visitor.to_vue(DEFAULT_VALUE) + return NotificationParameterSchema(schema=schema, default_values=default_values) + + +@dataclass(frozen=True, kw_only=True) +class NotificationParameterDescription: + ident: NotificationParameterID + description: str + + +def get_list_of_notification_parameter( + parameter_method: NotificationParameterMethod, +) -> Sequence[NotificationParameterDescription]: + notification_parameter = NotificationParameterConfigFile().load_for_reading() + return [ + NotificationParameterDescription(ident=k, description=v["general"]["description"]) + for k, v in notification_parameter.get(parameter_method, {}).items() + ] + + +def get_notification_parameter( + parameter_method: NotificationParameterMethod, + parameter_id: NotificationParameterID, +) -> NotificationParameterItem: + notification_parameter = NotificationParameterConfigFile().load_for_reading() + return notification_parameter[parameter_method][parameter_id] diff --git a/cmk/gui/watolib/notification_types.py b/cmk/gui/watolib/notification_types.py new file mode 100644 index 00000000000..5307f862e15 --- /dev/null +++ b/cmk/gui/watolib/notification_types.py @@ -0,0 +1,100 @@ +#!/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. +# +# This file is auto-generated via the cmk-shared-typing package. +# Do not edit manually. + + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Optional + + +@dataclass(kw_only=True) +class FallbackWarningI18n: + title: str + message: str + setup_link_title: str + do_not_show_again_title: str + + +@dataclass(kw_only=True) +class NotificationStatsI18n: + sent_notifications: str + failed_notifications: str + sent_notifications_link_title: str + failed_notifications_link_title: str + + +@dataclass(kw_only=True) +class CoreStatsI18n: + title: str + sites_column_title: str + status_column_title: str + ok_msg: str + warning_msg: str + disabled_msg: str + + +@dataclass(kw_only=True) +class Rule: + i18n: str + count: str + link: str + + +@dataclass(kw_only=True) +class FallbackWarning: + i18n: FallbackWarningI18n + user_id: str + setup_link: str + do_not_show_again_link: str + + +@dataclass(kw_only=True) +class NotificationStats: + num_sent_notifications: int + num_failed_notifications: int + sent_notification_link: str + failed_notification_link: str + i18n: NotificationStatsI18n + + +@dataclass(kw_only=True) +class CoreStats: + sites: list[str] + i18n: CoreStatsI18n + + +@dataclass(kw_only=True) +class RuleTopic: + rules: list[Rule] + i18n: Optional[str] = None + + +@dataclass(kw_only=True) +class RuleSection: + i18n: str + topics: list[RuleTopic] + + +@dataclass(kw_only=True) +class Notifications: + notification_stats: NotificationStats + core_stats: CoreStats + rule_sections: list[RuleSection] + fallback_warning: Optional[FallbackWarning] = None + + +@dataclass(kw_only=True) +class NotificationParametersOverview: + parameters: list[RuleSection] + + +@dataclass(kw_only=True) +class NotificationTypeDefs: + notifications: Optional[Notifications] = None + notification_parameters_overview: Optional[NotificationParametersOverview] = None diff --git a/cmk/gui/watolib/notifications.py b/cmk/gui/watolib/notifications.py index 0ddb8286999..18cfa462705 100644 --- a/cmk/gui/watolib/notifications.py +++ b/cmk/gui/watolib/notifications.py @@ -32,7 +32,13 @@ from cmk.ccc import store -from cmk.utils.notify_types import EventRule, NotificationRuleID, NotifyBulkType, NotifyPlugin +from cmk.utils.notify_types import ( + EventRule, + NotificationParameterSpec, + NotificationRuleID, + NotifyBulkType, + NotifyPlugin, +) from cmk.utils.user import UserId from cmk.gui import userdb @@ -65,7 +71,11 @@ PluginAdapter, ) from cmk.gui.type_defs import GlobalSettings -from cmk.gui.watolib.simple_config_file import ConfigFileRegistry, WatoListConfigFile +from cmk.gui.watolib.simple_config_file import ( + ConfigFileRegistry, + WatoListConfigFile, + WatoSimpleConfigFile, +) from cmk.gui.watolib.user_scripts import load_notification_scripts from cmk.gui.watolib.utils import wato_root_dir @@ -671,3 +681,12 @@ def find_timeperiod_usage_in_notification_rules(time_period_name: str) -> list[t for index, rule in enumerate(NotificationRuleConfigFile().load_for_reading()): used_in += userdb.find_timeperiod_usage_in_notification_rule(time_period_name, index, rule) return used_in + + +class NotificationParameterConfigFile(WatoSimpleConfigFile[NotificationParameterSpec]): + def __init__(self) -> None: + super().__init__( + config_file_path=Path(wato_root_dir() + "notification_parameter.mk"), + config_variable="notification_parameter", + spec_class=NotificationParameterSpec, + ) diff --git a/cmk/gui/watolib/piggyback_hub.py b/cmk/gui/watolib/piggyback_hub.py index 7049252a8d1..0aeccd1b1ab 100644 --- a/cmk/gui/watolib/piggyback_hub.py +++ b/cmk/gui/watolib/piggyback_hub.py @@ -3,19 +3,56 @@ # 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 +from collections.abc import Container, Iterable, Mapping from livestatus import SiteConfiguration, SiteId +from cmk.utils.hostaddress import HostName from cmk.utils.paths import omd_root -from cmk.gui.site_config import configured_sites from cmk.gui.type_defs import GlobalSettings -from cmk.gui.watolib.global_settings import load_configuration_settings -from cmk.gui.watolib.hosts_and_folders import folder_tree +from cmk.gui.watolib.site_changes import ChangeSpec -from cmk.piggyback_hub.config import load_config, PiggybackHubConfig, save_config, Target -from cmk.piggyback_hub.utils import distribute +from cmk.piggyback_hub.config import distribute_config, PiggybackHubConfig + +_HOST_CHANGES = ( + "edit-host", + "create-host", + "delete-host", + "rename-host", + "move-host", + "edit-folder", +) + + +def has_piggyback_hub_relevant_changes(pending_changes: Iterable[ChangeSpec]) -> bool: + def _is_relevant_config_change(change: ChangeSpec) -> bool: + return ( + change["action_name"] == "edit-configvar" + and "piggyback_hub" in change["domains"] + or change["action_name"] in _HOST_CHANGES + ) + + return any(_is_relevant_config_change(change) for change in pending_changes) + + +def distribute_piggyback_hub_configs( + global_settings: GlobalSettings, + configured_sites: Mapping[SiteId, SiteConfiguration], + dirty_sites: Container[SiteId], # only needed in CME case. + hosts_sites: Mapping[HostName, SiteId], +) -> None: + site_configs = filter_for_enabled_piggyback_hub(global_settings, configured_sites) + + new_config = PiggybackHubConfig( + targets={ + host_name: site_id + for host_name, site_id in hosts_sites.items() + if site_id in site_configs + } + ) + + distribute_config({site: new_config for site in site_configs}, omd_root) def _piggyback_hub_enabled(site_config: SiteConfiguration, global_settings: GlobalSettings) -> bool: @@ -24,34 +61,11 @@ def _piggyback_hub_enabled(site_config: SiteConfiguration, global_settings: Glob return global_settings.get("piggyback_hub_enabled", True) -def get_enabled_piggyback_hub_site_configs() -> Mapping[SiteId, SiteConfiguration]: - global_settings = load_configuration_settings() +def filter_for_enabled_piggyback_hub( + global_settings: GlobalSettings, configured_sites: Mapping[SiteId, SiteConfiguration] +) -> Mapping[SiteId, SiteConfiguration]: return { site_id: site_config - for site_id, site_config in configured_sites().items() + for site_id, site_config in configured_sites.items() if _piggyback_hub_enabled(site_config, global_settings) is True } - - -def _get_piggyback_hub_config( - site_configs: Mapping[SiteId, SiteConfiguration], -) -> PiggybackHubConfig: - root_folder = folder_tree().root_folder() - return PiggybackHubConfig( - targets=[ - Target(host_name=host_name, site_id=host.site_id()) - for host_name, host in root_folder.all_hosts_recursively().items() - if host.site_id() in site_configs.keys() - ] - ) - - -def distribute_config() -> None: - site_configs = get_enabled_piggyback_hub_site_configs() - - old_config = load_config(omd_root) - new_config = _get_piggyback_hub_config(site_configs) - - if set(old_config.targets) != set(new_config.targets): - distribute({site: new_config for site in site_configs.keys()}, omd_root) - save_config(omd_root, new_config) diff --git a/cmk/gui/watolib/registration.py b/cmk/gui/watolib/registration.py index 59988672b8b..509a1b8af4e 100644 --- a/cmk/gui/watolib/registration.py +++ b/cmk/gui/watolib/registration.py @@ -16,10 +16,12 @@ from cmk.gui.background_job import BackgroundJobRegistry from cmk.gui.cron import register_job from cmk.gui.valuespec import AutocompleterRegistry +from cmk.gui.watolib.search import MatchItemGeneratorRegistry from . import ( _host_attributes, _sync_remote_sites, + activate_changes, auth_php, autodiscovery, automatic_host_removal, @@ -55,6 +57,7 @@ SampleConfigGeneratorRegistry, ) from .config_hostname import config_hostname_autocompleter +from .config_sync import ReplicationPathRegistry from .groups import ContactGroupUsageFinderRegistry as ContactGroupUsageFinderRegistry from .host_attributes import ABCHostAttribute, HostAttributeRegistry, HostAttributeTopicRegistry from .host_label_sync import AutomationDiscoveredHostLabelSync, DiscoveredHostLabelSyncJob @@ -64,8 +67,10 @@ RenameHostsBackgroundJob, ) from .hosts_and_folders import ( + collect_all_hosts, find_usages_of_contact_group_in_hosts_and_folders, Folder, + MatchItemGeneratorHosts, rebuild_folder_lookup_cache, ) from .network_scan import AutomationNetworkScan, execute_network_scan_job @@ -78,7 +83,12 @@ find_timeperiod_usage_in_host_and_service_rules, find_timeperiod_usage_in_time_specific_parameters, ) -from .rulespecs import RulespecGroupEnforcedServices, RulespecGroupRegistry +from .rulespecs import ( + MatchItemGeneratorRules, + rulespec_registry, + RulespecGroupEnforcedServices, + RulespecGroupRegistry, +) from .sample_config import ( ConfigGeneratorAcknowledgeInitialWerks, ConfigGeneratorAutomationUser, @@ -102,6 +112,8 @@ def register( timeperiod_usage_finder_registry: TimeperiodUsageFinderRegistry, config_variable_group_registry: ConfigVariableGroupRegistry, autocompleter_registry: AutocompleterRegistry, + match_item_generator_registry: MatchItemGeneratorRegistry, + replication_path_registry: ReplicationPathRegistry, ) -> None: _register_automation_commands(automation_command_registry) _register_gui_background_jobs(job_registry) @@ -109,6 +121,7 @@ def register( _register_nagvis_hooks() _register_config_domains(config_domain_registry) host_attributes.register(host_attribute_topic_registry) + activate_changes.register(replication_path_registry) _host_attributes.register() _register_host_attribute(host_attribute_registry) _register_cronjobs() @@ -142,6 +155,19 @@ def register( hooks.register_builtin("request-start", launch_requests_processing_background) hooks.register_builtin("validate-host", builtin_attributes.validate_host_parents) hooks.register_builtin("ldap-sync-finished", handle_ldap_sync_finished) + match_item_generator_registry.register( + MatchItemGeneratorRules( + "rules", + rulespec_group_registry, + rulespec_registry, + ) + ) + match_item_generator_registry.register( + MatchItemGeneratorHosts( + "hosts", + collect_all_hosts, + ) + ) def _register_automation_commands(automation_command_registry: AutomationCommandRegistry) -> None: @@ -201,6 +227,7 @@ def _register_host_attribute(host_attribute_registry: HostAttributeRegistry) -> builtin_attributes.HostAttributeLockedAttributes, builtin_attributes.HostAttributeMetaData, builtin_attributes.HostAttributeDiscoveryFailed, + builtin_attributes.HostAttributeWaitingForDiscovery, builtin_attributes.HostAttributeLabels, groups.HostAttributeContactGroups, ] diff --git a/cmk/gui/watolib/rulespecs.py b/cmk/gui/watolib/rulespecs.py index 94708794856..77b895e4716 100644 --- a/cmk/gui/watolib/rulespecs.py +++ b/cmk/gui/watolib/rulespecs.py @@ -10,7 +10,7 @@ import re from collections.abc import Callable from dataclasses import dataclass, field -from typing import Any, Literal +from typing import Any, Literal, NamedTuple import cmk.ccc.plugin_registry from cmk.ccc.exceptions import MKGeneralException @@ -19,6 +19,8 @@ from cmk.utils import paths from cmk.utils.rulesets.definition import is_from_ruleset_group, RuleGroup, RuleGroupType +from cmk.gui.form_specs.converter import Tuple as FSTuple +from cmk.gui.form_specs.private import SingleChoiceElementExtended, SingleChoiceExtended from cmk.gui.global_config import get_global_config from cmk.gui.htmllib.generator import HTMLWriter from cmk.gui.htmllib.html import html @@ -51,9 +53,13 @@ ValueSpecValidateFunc, ) +from cmk.rulesets.v1 import Help, Label, Title +from cmk.rulesets.v1.form_specs import DefaultValue, FormSpec, SingleChoice, SingleChoiceElement +from cmk.rulesets.v1.form_specs import FixedValue as FSFixedValue + from .check_mk_automations import get_check_information_cached from .main_menu import ABCMainModule, MainModuleRegistry -from .search import ABCMatchItemGenerator, match_item_generator_registry, MatchItem, MatchItems +from .search import ABCMatchItemGenerator, MatchItem, MatchItems from .timeperiods import TimeperiodSelection MatchType = Literal["first", "all", "list", "dict", "varies"] @@ -303,6 +309,15 @@ def _validate_function_args(arg_infos: list[tuple[Any, bool, bool]], hint: str) ) +class FormSpecDefinition(NamedTuple): + value: Callable[[], FormSpec] + item: Callable[[], FormSpec] | None + + +class FormSpecNotImplementedError(Exception): + pass + + class Rulespec(abc.ABC): NO_FACTORY_DEFAULT: list = [] # This option has the same effect as `NO_FACTORY_DEFAULT`. It's often used in MKPs. @@ -330,6 +345,7 @@ def __init__( factory_default: Any, help_func: Callable[[], str] | None, doc_references: dict[DocReference, str] | None, + form_spec_definition: FormSpecDefinition | None = None, ) -> None: super().__init__() @@ -350,6 +366,7 @@ def __init__( (is_binary_ruleset, False, False), (factory_default, False, True), (help_func, True, True), + (form_spec_definition, False, True), ] _validate_function_args(arg_infos, name) @@ -370,6 +387,7 @@ def __init__( self._factory_default = factory_default self._help = help_func self._doc_references = doc_references + self._form_spec_definition = form_spec_definition @property def name(self) -> str: @@ -383,6 +401,20 @@ def group(self) -> type[RulespecBaseGroup]: def valuespec(self) -> ValueSpec: return self._valuespec() + @property + def form_spec(self) -> FormSpec: + if self._form_spec_definition is None: + raise FormSpecNotImplementedError() + return self._form_spec_definition.value() + + @property + def item_form_spec(self) -> FormSpec | None: + if self._form_spec_definition is None: + raise FormSpecNotImplementedError() + if self._form_spec_definition.item is None: + return None + return self._form_spec_definition.item() + @property def title(self) -> str | None: plain_title = self._title() if self._title else self.valuespec.title() @@ -510,6 +542,7 @@ def __init__( # pylint: disable=dangerous-default-value factory_default: Any = Rulespec.NO_FACTORY_DEFAULT, help_func: Callable[[], str] | None = None, doc_references: dict[DocReference, str] | None = None, + form_spec_definition: FormSpecDefinition | None = None, ) -> None: super().__init__( name=name, @@ -524,6 +557,7 @@ def __init__( # pylint: disable=dangerous-default-value factory_default=factory_default, help_func=help_func, doc_references=doc_references, + form_spec_definition=None if form_spec_definition is None else form_spec_definition, # Excplicit set is_for_services=False, item_type=None, @@ -556,6 +590,7 @@ def __init__( # pylint: disable=dangerous-default-value factory_default: Any = Rulespec.NO_FACTORY_DEFAULT, help_func: Callable[[], str] | None = None, doc_references: dict[DocReference, str] | None = None, + form_spec_definition: FormSpecDefinition | None = None, ) -> None: super().__init__( name=name, @@ -574,6 +609,7 @@ def __init__( # pylint: disable=dangerous-default-value factory_default=factory_default, help_func=help_func, doc_references=doc_references, + form_spec_definition=form_spec_definition, # Excplicit set is_for_services=True, ) @@ -606,6 +642,7 @@ def __init__( # pylint: disable=dangerous-default-value # Explicit set is_binary_ruleset=True, valuespec=self._binary_host_valuespec, + form_spec_definition=FormSpecDefinition(self._binary_host_form_spec, None), ) def _binary_host_valuespec(self) -> ValueSpec: @@ -617,6 +654,20 @@ def _binary_host_valuespec(self) -> ValueSpec: default_value=True, ) + def _binary_host_form_spec(self) -> SingleChoiceExtended: + return SingleChoiceExtended[bool]( + elements=[ + SingleChoiceElementExtended[bool]( + name=True, title=Title("Positive match (Add matching hosts to the set)") + ), + SingleChoiceElementExtended[bool]( + name=False, title=Title("Negative match (Exclude matching hosts from the set)") + ), + ], + type=bool, + prefill=DefaultValue(True), + ) + class BinaryServiceRulespec(ServiceRulespec): # Required because of Rulespec.NO_FACTORY_DEFAULT @@ -653,6 +704,7 @@ def __init__( # pylint: disable=dangerous-default-value # Explicit set is_binary_ruleset=True, valuespec=self._binary_service_valuespec, + form_spec_definition=FormSpecDefinition(self._binary_service_form_spec, None), ) def _binary_service_valuespec(self) -> ValueSpec: @@ -664,6 +716,21 @@ def _binary_service_valuespec(self) -> ValueSpec: default_value=True, ) + def _binary_service_form_spec(self) -> SingleChoiceExtended: + return SingleChoiceExtended[bool]( + elements=[ + SingleChoiceElementExtended[bool]( + name=True, title=Title("Positive match (Add services hosts to the set)") + ), + SingleChoiceElementExtended[bool]( + name=False, + title=Title("Negative match (Exclude matching services from the set)"), + ), + ], + type=bool, + prefill=DefaultValue(True), + ) + def _get_manual_check_parameter_rulespec_instance( group: type[Any], @@ -674,6 +741,7 @@ def _get_manual_check_parameter_rulespec_instance( is_optional: bool = False, is_deprecated: bool = False, is_cloud_and_managed_edition_only: bool = False, + form_spec_definition: FormSpecDefinition | None = None, ) -> "ManualCheckParameterRulespec": # There may be no RulespecGroup declaration for the static checks. # Create some based on the regular check groups (which should have a definition) @@ -699,6 +767,7 @@ def _get_manual_check_parameter_rulespec_instance( is_optional=is_optional, is_deprecated=is_deprecated, is_cloud_and_managed_edition_only=is_cloud_and_managed_edition_only, + form_spec_definition=form_spec_definition, ) @@ -744,6 +813,7 @@ def __init__( # pylint: disable=dangerous-default-value is_cloud_and_managed_edition_only: bool = False, factory_default: Any = Rulespec.NO_FACTORY_DEFAULT, create_manual_check: bool = True, + form_spec_definition: FormSpecDefinition | None = None, ) -> None: # Mandatory keys self._check_group_name = check_group_name @@ -754,6 +824,7 @@ def __init__( # pylint: disable=dangerous-default-value # (arg, is_callable, none_allowed) (check_group_name, False, False), (parameter_valuespec, True, False), + (form_spec_definition, False, True), ] _validate_function_args(arg_infos, name) @@ -770,6 +841,12 @@ def __init__( # pylint: disable=dangerous-default-value is_binary_ruleset=False, match_type=match_type or "first", valuespec=self._rulespec_valuespec, + form_spec_definition=None + if form_spec_definition is None + else FormSpecDefinition( + lambda: _wrap_form_spec_in_timeperiod_form_spec(form_spec_definition.value()), + form_spec_definition.item, + ), ) self.manual_check_parameter_rulespec_instance = None @@ -783,6 +860,7 @@ def __init__( # pylint: disable=dangerous-default-value item_spec=item_spec, is_optional=is_optional, is_deprecated=is_deprecated, + form_spec_definition=form_spec_definition, ) ) @@ -815,6 +893,7 @@ def __init__( # pylint: disable=dangerous-default-value is_cloud_and_managed_edition_only: bool = False, factory_default: Any = Rulespec.NO_FACTORY_DEFAULT, create_manual_check: bool = True, + form_spec_definition: FormSpecDefinition | None = None, ): self._check_group_name = check_group_name name = "checkgroup_parameters:%s" % self._check_group_name @@ -838,6 +917,11 @@ def __init__( # pylint: disable=dangerous-default-value is_binary_ruleset=False, match_type=match_type or "first", valuespec=self._rulespec_valuespec, + form_spec_definition=None + if form_spec_definition is None + else FormSpecDefinition( + lambda: _wrap_form_spec_in_timeperiod_form_spec(form_spec_definition.value()), None + ), ) self.manual_check_parameter_rulespec_instance = None @@ -850,6 +934,7 @@ def __init__( # pylint: disable=dangerous-default-value parameter_valuespec=parameter_valuespec, is_optional=is_optional, is_deprecated=is_deprecated, + form_spec_definition=form_spec_definition, ) ) @@ -873,6 +958,11 @@ def _wrap_valuespec_in_timeperiod_valuespec(valuespec: ValueSpec) -> ValueSpec: return TimeperiodValuespec(valuespec) +def _wrap_form_spec_in_timeperiod_form_spec(form_spec: FormSpec) -> FormSpec: + # TODO: implement, don't forget to use Title and Help from embedded form_spec + return form_spec + + class ManualCheckParameterRulespec(HostRulespec): """Base class for all rulespecs managing manually configured checks @@ -892,6 +982,7 @@ def __init__( # pylint: disable=dangerous-default-value name: str | None = None, match_type: MatchType = "all", factory_default: Any = Rulespec.NO_FACTORY_DEFAULT, + form_spec_definition: FormSpecDefinition | None = None, ): # Mandatory keys self._check_group_name = check_group_name @@ -903,6 +994,7 @@ def __init__( # pylint: disable=dangerous-default-value (check_group_name, False, False), (parameter_valuespec, True, True), (item_spec, True, True), + (form_spec_definition, False, True), ] _validate_function_args(arg_infos, name) super().__init__( @@ -916,11 +1008,14 @@ def __init__( # pylint: disable=dangerous-default-value is_cloud_and_managed_edition_only=is_cloud_and_managed_edition_only, # Explicit set valuespec=self._rulespec_valuespec, + form_spec_definition=None + if form_spec_definition is None + else FormSpecDefinition(lambda: self._rulespec_form_spec(form_spec_definition), None), ) # Optional keys self._parameter_valuespec = parameter_valuespec - self._rule_value_item_spec = item_spec + self._rule_value_item_valuespec = item_spec @property def check_group_name(self) -> str: @@ -953,21 +1048,83 @@ def _rulespec_valuespec(self) -> ValueSpec: title=_("Check type"), help=_("Please choose the check plug-in"), ), - self._get_item_spec(), + self._get_item_valuespec(), parameter_vs, ], ) - def _get_item_spec(self) -> ValueSpec: + def _get_item_valuespec(self) -> ValueSpec: """Not used as condition, only for the rule value valuespec""" - if self._rule_value_item_spec: - return self._rule_value_item_spec() + if self._rule_value_item_valuespec: + return self._rule_value_item_valuespec() return FixedValue( value=None, totext="", ) + def _rulespec_form_spec(self, form_spec_definition: FormSpecDefinition) -> FormSpec: + """Wraps the parameter together with the other needed form specs + + This should not be overridden by specific manual checks. Normally the parameter_form_spec + is the one that should be overridden. + """ + + value_form_spec, item_form_spec = form_spec_definition + + parameter_fs: FormSpec[Any] + if value_form_spec is None: + parameter_fs = FSFixedValue( + title=Title("Parameters"), + value=None, + help_text=Help("This check has no parameters."), + label=Label(""), + ) + else: + parameter_fs = _wrap_form_spec_in_timeperiod_form_spec(value_form_spec()) + + return FSTuple( + title=parameter_fs.title, + elements=[ + _get_check_type_group_choice( + title=Title("Check type"), + help_text=Help("Please choose the check plug-in"), + check_group_name=self.check_group_name, + ), + self._compute_item_form_spec(item_form_spec), + parameter_fs, + ], + ) + + def _compute_item_form_spec(self, form_spec: Callable[[], FormSpec] | None) -> FormSpec: + """Not used as condition, only for the rule value valuespec""" + if form_spec is None: + return FSFixedValue( + value=None, + label=Label(""), + ) + return form_spec() + + +def _get_check_type_group_choice( + title: Title, help_text: Help, check_group_name: str +) -> SingleChoice: + checks = get_check_information_cached() + elements: list[SingleChoiceElement] = [] + for checkname, check in checks.items(): + if check.get("group") == check_group_name: + elements.append( + SingleChoiceElement( + name=str(checkname), + title=Title(f"{checkname} - {check['title']}"), # pylint: disable=localization-of-non-literal-string + ) + ) + return SingleChoice( + title=title, + help_text=help_text, + elements=elements, + ) + # Pre 1.6 rule registering logic. Need to be kept for some time def register_rule( @@ -1394,11 +1551,3 @@ def is_localization_dependent(self) -> bool: rulespec_registry = RulespecRegistry(rulespec_group_registry) - -match_item_generator_registry.register( - MatchItemGeneratorRules( - "rules", - rulespec_group_registry, - rulespec_registry, - ) -) diff --git a/cmk/gui/watolib/sample_config.py b/cmk/gui/watolib/sample_config.py index dc1f6286b37..1ba54f8b5ff 100644 --- a/cmk/gui/watolib/sample_config.py +++ b/cmk/gui/watolib/sample_config.py @@ -13,7 +13,12 @@ from cmk.utils.encryption import raw_certificates_from_file from cmk.utils.log import VERBOSE -from cmk.utils.notify_types import EventRule, MailPluginModel, NotificationRuleID +from cmk.utils.notify_types import ( + EventRule, + MailPluginModel, + NotificationParameterID, + NotificationRuleID, +) from cmk.utils.paths import configuration_lockfile, site_cert_file from cmk.utils.tags import sample_tag_config, TagConfig @@ -95,6 +100,10 @@ def new_notification_rule_id() -> NotificationRuleID: return NotificationRuleID(str(uuid4())) +def new_notification_parameter_id() -> NotificationParameterID: + return NotificationParameterID(str(uuid4())) + + def get_default_notification_rule() -> EventRule: return EventRule( rule_id=new_notification_rule_id(), diff --git a/cmk/gui/watolib/tags.py b/cmk/gui/watolib/tags.py index efd2eb4460a..3487b87adbc 100644 --- a/cmk/gui/watolib/tags.py +++ b/cmk/gui/watolib/tags.py @@ -147,7 +147,7 @@ def _update_tag_dependencies() -> None: load_config() tree = folder_tree() tree.invalidate_caches() - tree.root_folder().rewrite_hosts_files() + tree.root_folder().recursively_save_hosts() class RepairError(MKGeneralException): diff --git a/cmk/gui/wsgi/app.py b/cmk/gui/wsgi/app.py index 6de7432b11a..db62b8a86ec 100644 --- a/cmk/gui/wsgi/app.py +++ b/cmk/gui/wsgi/app.py @@ -14,7 +14,10 @@ from werkzeug.middleware.proxy_fix import ProxyFix from werkzeug.security import safe_join -from cmk.gui import http +from cmk.ccc.version import Edition + +from cmk.gui.features import features_registry +from cmk.gui.flask_app import CheckmkFlaskApp from cmk.gui.session import FileBasedSession from cmk.gui.wsgi.blueprints.checkmk import checkmk from cmk.gui.wsgi.blueprints.rest_api import rest_api @@ -24,13 +27,7 @@ logger = logging.getLogger(__name__) -class CheckmkFlaskApp(Flask): - request_class = http.Request - response_class = http.Response - session_interface = FileBasedSession() - - -def make_wsgi_app(debug: bool = False, testing: bool = False) -> Flask: +def make_wsgi_app(edition: Edition, debug: bool = False, testing: bool = False) -> Flask: """Create the Checkmk WSGI application. Args: @@ -44,8 +41,12 @@ def make_wsgi_app(debug: bool = False, testing: bool = False) -> Flask: Returns: The WSGI application """ + try: + features = features_registry[str(edition)] + except KeyError: + raise ValueError(f"Invalid edition: {edition}") - app = CheckmkFlaskApp(__name__) + app = CheckmkFlaskApp(__name__, FileBasedSession(), features) app.debug = debug app.testing = testing # Config needs a request context to work. :( @@ -95,4 +96,4 @@ def redirect_doc(site: str) -> werkzeug.Response: return app -__all__ = ["make_wsgi_app", "CheckmkFlaskApp"] +__all__ = ["make_wsgi_app"] diff --git a/cmk/gui/wsgi/applications/index.wsgi b/cmk/gui/wsgi/applications/index.wsgi index 03334993185..3b3ee1c45bc 100644 --- a/cmk/gui/wsgi/applications/index.wsgi +++ b/cmk/gui/wsgi/applications/index.wsgi @@ -8,6 +8,7 @@ from wsgiref.types import WSGIEnvironment from opentelemetry.instrumentation.wsgi import get_default_span_name, OpenTelemetryMiddleware from cmk.ccc.site import get_omd_config, omd_site +from cmk.ccc.version import edition from cmk.utils import paths @@ -70,7 +71,10 @@ Application = OpenTelemetryMiddleware( LazyImportProfilingMiddleware( app_factory_module="cmk.gui.wsgi.app", app_factory_name="make_wsgi_app", - app_factory_args=(DEBUG,), + app_factory_args=( + edition(paths.omd_root), + DEBUG, + ), app_factory_kwargs={}, config_loader=ProfileConfigLoader( fetch_actual_config=load_actual_config, diff --git a/cmk/notification_plugins/ilert.py b/cmk/notification_plugins/ilert.py index 765b367dc49..5dda71533c7 100644 --- a/cmk/notification_plugins/ilert.py +++ b/cmk/notification_plugins/ilert.py @@ -5,9 +5,8 @@ # iLert # License: GNU Public License v2 -from os import environ - from cmk.notification_plugins.utils import ( + _get_password_from_env_or_context, JsonFieldMatcher, post_request, process_by_matchers, @@ -16,7 +15,6 @@ StatusCodeMatcher, StatusCodeRange, ) -from cmk.notification_plugins.utils import retrieve_from_passwordstore as passwords PLUGIN_VERSION = "1.0" @@ -43,7 +41,7 @@ def _ilert_url() -> str: - password = passwords(environ["NOTIFY_PARAMETER_ILERT_API_KEY"]) + password = _get_password_from_env_or_context(key="NOTIFY_PARAMETER_ILERT_API_KEY") return f"https://api.ilert.com/api/v1/events/checkmk-ext/{password}" diff --git a/cmk/notification_plugins/mail.py b/cmk/notification_plugins/mail.py index f17ed1b26cf..5b9e4e54e4b 100644 --- a/cmk/notification_plugins/mail.py +++ b/cmk/notification_plugins/mail.py @@ -12,7 +12,7 @@ import socket import sys -from collections.abc import Callable +from collections.abc import Callable, Sequence from email.message import Message from email.mime.application import MIMEApplication from email.mime.image import MIMEImage @@ -20,237 +20,16 @@ from email.mime.text import MIMEText from typing import Literal, NamedTuple, NoReturn +from jinja2 import Environment, FileSystemLoader + from cmk.ccc.exceptions import MKException +from cmk.utils.escaping import escape_permissive from cmk.utils.mail import default_from_address, MailString, send_mail_sendmail, set_mail_headers +from cmk.utils.paths import omd_root, web_dir from cmk.notification_plugins import utils -from cmk.notification_plugins.utils import render_cmk_graphs - - -def tmpl_head_html(html_section: str) -> str: - return ( - """ - - -$SUBJECT$ - - -""" - + html_section - + "" - ) - - -TMPL_FOOT_HTML = """
- -""" +from cmk.notification_plugins.utils import _get_password_from_env_or_context, render_cmk_graphs # Elements to be put into the mail body. Columns: # 1. Name @@ -259,7 +38,6 @@ def tmpl_head_html(html_section: str) -> str: # 4. "normal"-> for normal notifications, "alerthandler" -> for alert handler notifications, "all" -> for all types # 5. Title # 6. Text template -# 7. HTML template BODY_ELEMENTS = [ ( @@ -269,9 +47,15 @@ def tmpl_head_html(html_section: str) -> str: "all", "Host", "$HOSTNAME_AND_ALIAS_TXT$", - "$HOSTNAME_AND_ALIAS_HTML$", ), - ("servicedesc", "service", True, "all", "Service", "$SERVICEDESC$", "$LINKEDSERVICEDESC$"), + ( + "servicedesc", + "service", + True, + "all", + "Service", + "$SERVICEDESC$", + ), ( "event", "both", @@ -279,7 +63,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Event", "$EVENT_TXT$", - "$EVENT_HTML$", ), # Elements for both host and service notifications ( @@ -289,7 +72,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Address", "$HOSTADDRESS$", - "$HOSTADDRESS$", ), ( "abstime", @@ -298,10 +80,23 @@ def tmpl_head_html(html_section: str) -> str: "all", "Time", "$LONGDATETIME$", - "$LONGDATETIME$", ), - ("omdsite", "both", False, "all", "Site", "$OMD_SITE$", "$OMD_SITE$"), - ("hosttags", "both", False, "all", "Host tags", "$HOST_TAGS$", "$HOST_TAGS$"), + ( + "omdsite", + "both", + False, + "all", + "Site", + "$OMD_SITE$", + ), + ( + "hosttags", + "both", + False, + "all", + "Host tags", + "$HOST_TAGS$", + ), ( "notification_author", "both", @@ -309,7 +104,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Notification author", "$NOTIFICATIONAUTHOR$", - "$NOTIFICATIONAUTHOR$", ), ( "notification_comment", @@ -318,7 +112,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Notification comment", "$NOTIFICATIONCOMMENT$", - "$NOTIFICATIONCOMMENT$", ), ( "notesurl", @@ -327,7 +120,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Custom host notes URL", "$HOSTNOTESURL$", - "$HOSTNOTESURL$", ), # Elements only for host notifications ( @@ -337,7 +129,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Relative time", "$LASTHOSTSTATECHANGE_REL$", - "$LASTHOSTSTATECHANGE_REL$", ), ( "output", @@ -346,7 +137,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Summary", "$HOSTOUTPUT$", - "$HOSTOUTPUT_HTML$", ), ( "ack_author", @@ -355,7 +145,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Acknowledge author", "$HOSTACKAUTHOR$", - "$HOSTACKAUTHOR$", ), ( "ack_comment", @@ -364,7 +153,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Acknowledge comment", "$HOSTACKCOMMENT$", - "$HOSTACKCOMMENT$", ), ( "perfdata", @@ -373,7 +161,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Metrics", "$HOSTPERFDATA$", - "$HOSTPERFDATA$", ), # Elements only for service notifications ( @@ -383,7 +170,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Relative time", "$LASTSERVICESTATECHANGE_REL$", - "$LASTSERVICESTATECHANGE_REL$", ), ( "output", @@ -392,7 +178,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Summary", "$SERVICEOUTPUT$", - "$SERVICEOUTPUT_HTML$", ), ( "longoutput", @@ -401,7 +186,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Details", "$LONGSERVICEOUTPUT$", - "$LONGSERVICEOUTPUT_HTML$", ), ( "ack_author", @@ -410,7 +194,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Acknowledge author", "$SERVICEACKAUTHOR$", - "$SERVICEACKAUTHOR$", ), ( "ack_comment", @@ -419,7 +202,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Acknowledge comment", "$SERVICEACKCOMMENT$", - "$SERVICEACKCOMMENT$", ), ( "perfdata", @@ -428,7 +210,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Host metrics", "$HOSTPERFDATA$", - "$HOSTPERFDATA$", ), ( "perfdata", @@ -437,7 +218,6 @@ def tmpl_head_html(html_section: str) -> str: "normal", "Service metrics", "$SERVICEPERFDATA$", - "$SERVICEPERFDATA$", ), ( "notesurl", @@ -446,7 +226,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Custom service notes URL", "$SERVICENOTESURL$", - "$SERVICENOTESURL$", ), # Alert handlers ( @@ -456,7 +235,6 @@ def tmpl_head_html(html_section: str) -> str: "alerthandler", "Name of alert handler", "$ALERTHANDLERNAME$", - "$ALERTHANDLERNAME$", ), ( "alerthandler_output", @@ -465,7 +243,6 @@ def tmpl_head_html(html_section: str) -> str: "alerthandler", "Output of alert handler", "$ALERTHANDLEROUTPUT$", - "$ALERTHANDLEROUTPUT$", ), # Debugging ( @@ -475,7 +252,6 @@ def tmpl_head_html(html_section: str) -> str: "all", "Complete variable list", "$CONTEXT_ASCII$", - "$CONTEXT_HTML$", ), ] @@ -490,17 +266,23 @@ class GraphException(MKException): pass -class AttachmentNamedTuple(NamedTuple): +class Attachment(NamedTuple): what: Literal["img"] name: str contents: bytes | str how: str -# Keeping this for compatibility reasons -AttachmentUnNamedTuple = tuple[str, str, bytes | str, str] -AttachmentTuple = AttachmentNamedTuple | AttachmentUnNamedTuple -AttachmentList = list[AttachmentTuple] +class TemplateRenderer: + def __init__(self) -> None: + self.env = Environment( + loader=FileSystemLoader(omd_root / "share/check_mk/notifications/templates/mail"), + autoescape=True, + ) + + def render_template(self, template_file: str, data: dict[str, object]) -> str: + template = self.env.get_template(template_file) + return template.render(data) # TODO: Just use a single EmailContent parameter. @@ -511,7 +293,7 @@ def multipart_mail( reply_to: str, content_txt: str, content_html: str, - attach: AttachmentList | None = None, + attach: Sequence[Attachment] | None = None, ) -> MIMEMultipart: if attach is None: attach = [] @@ -626,18 +408,6 @@ def _ensure_str_error_message(message: bytes | str) -> str: return message.decode("utf-8") if isinstance(message, bytes) else message -# We can not use cmk.utils.html.replace_state_markers here because of a bug in outlook -# that results in missing state markers -# https://github.com/hteumeuleu/email-bugs/issues/75 -def _replace_state_markers(output: str) -> str: - return ( - output.replace("(!)", 'WARN') - .replace("(!!)", 'CRIT') - .replace("(?)", 'UNKN') - .replace("(.)", 'OK') - ) - - def send_mail_smtp_impl( message: Message, target: MailString, @@ -674,7 +444,13 @@ def getreply_wrapper(self: smtplib.SMTP) -> tuple[int, bytes]: conn.starttls() if context.get("PARAMETER_SMTP_AUTH_USER") is not None: - conn.login(context["PARAMETER_SMTP_AUTH_USER"], context["PARAMETER_SMTP_AUTH_PASSWORD"]) + conn.login( + context["PARAMETER_SMTP_AUTH_USER"], + _get_password_from_env_or_context( + key="PARAMETER_SMTP_AUTH_PASSWORD", + context=context, + ), + ) # this call returns a dictionary with the recipients that failed + the reason, but only # if at least one succeeded, otherwise it throws an exception. @@ -699,29 +475,26 @@ def send_mail(message: Message, target: str, from_address: str, context: dict[st return 0 -def render_performance_graphs(context: dict[str, str]) -> tuple[AttachmentList, str]: - attachments: AttachmentList = [] - graph_code = "" +def render_performance_graphs( + context: dict[str, str], +) -> tuple[list[Attachment], list[str]]: + attachments: list[Attachment] = [] + file_names = [] for graph in render_cmk_graphs(context): - attachments.append(AttachmentNamedTuple("img", graph.filename, graph.data, "inline")) - - cls = "" - if context.get("PARAMETER_NO_FLOATING_GRAPHS"): - cls = ' class="nofloat"' - graph_code += f'' + attachments.append(Attachment("img", graph.filename, graph.data, "inline")) - if graph_code: - graph_code = ( - "Graphs" - '%s' % graph_code - ) + file_names.append(graph.filename) - return attachments, graph_code + return attachments, file_names def construct_content( - context: dict[str, str], is_bulk: bool = False, notification_number: int = 1 -) -> tuple[str, str, AttachmentList]: + context: dict[str, str], + is_bulk: bool = False, + bulk_summary: list[dict[str, str]] | None = None, + last_bulk_entry: bool = False, + notification_number: int = 1, +) -> tuple[str, str, list[Attachment]]: # A list of optional information is configurable via the parameter "elements" # (new configuration style) # Note: The value PARAMETER_ELEMENTSS is NO TYPO. @@ -736,36 +509,44 @@ def construct_content( if notification_number > int(notifications_with_graphs): elements.remove("graph") - # Prepare the mail contents - template_txt, template_html = body_templates( + # Prepare the text mail content + template_txt = body_templates( context["WHAT"].lower(), "ALERTHANDLEROUTPUT" in context, elements, BODY_ELEMENTS, ) content_txt = utils.substitute_context(template_txt, context) - content_html = utils.substitute_context(template_html, context) - attachments: AttachmentList = [] + attachments: list[Attachment] = [] + file_names: list[str] = [] if "graph" in elements and "ALERTHANDLEROUTPUT" not in context: # Add Checkmk graphs try: - attachments, graph_code = render_performance_graphs(context) - content_html += graph_code + attachments, file_names = render_performance_graphs(context) except Exception as e: sys.stderr.write("Failed to add graphs to mail. Continue without them. (%s)\n" % e) - extra_html_section = "" - if "PARAMETER_INSERT_HTML_SECTION" in context: - extra_html_section = context["PARAMETER_INSERT_HTML_SECTION"] - - content_html = ( - utils.substitute_context(tmpl_head_html(extra_html_section), context) - + content_html - + utils.substitute_context(TMPL_FOOT_HTML, context) + content_html = utils.substitute_context( + TemplateRenderer().render_template( + "base.html", + { + "data": context, + "graphs": file_names, + "insert": escape_permissive(context.get("PARAMETER_INSERT_HTML_SECTION", "")), + "is_bulk": is_bulk, + "bulk_summary": bulk_summary, + "last_bulk_entry": last_bulk_entry, + }, + ), + context, ) - return content_txt, content_html, attachments + return ( + content_txt, + content_html, + attachments, + ) def extend_context(context: dict[str, str]) -> None: @@ -773,10 +554,12 @@ def extend_context(context: dict[str, str]) -> None: context["PARAMETER_URL_PREFIX"] = context["PARAMETER_2"] context["LINKEDHOSTNAME"] = utils.format_link( - '%s', utils.host_url_from_context(context), context["HOSTNAME"] + '%s', + utils.host_url_from_context(context), + context["HOSTNAME"], ) context["LINKEDSERVICEDESC"] = utils.format_link( - '%s', + '%s', utils.service_url_from_context(context), context.get("SERVICEDESC", ""), ) @@ -788,25 +571,22 @@ def extend_context(context: dict[str, str]) -> None: context["HOSTNAME_AND_ALIAS_TXT"] = "$HOSTNAME$" context["HOSTNAME_AND_ALIAS_HTML"] = "$LINKEDHOSTNAME$" - event_template_txt, event_template_html = event_templates(context["NOTIFICATIONTYPE"]) + event_template_txt = txt_event_template(context["NOTIFICATIONTYPE"]) context["EVENT_TXT"] = utils.substitute_context( event_template_txt.replace("@", context["WHAT"]), context ) - context["EVENT_HTML"] = utils.substitute_context( - event_template_html.replace("@", context["WHAT"]), context - ) if "HOSTOUTPUT" in context: - context["HOSTOUTPUT_HTML"] = _replace_state_markers(context["HOSTOUTPUT"]) + context["HOSTOUTPUT_HTML"] = context["HOSTOUTPUT"] if context["WHAT"] == "SERVICE": - context["SERVICEOUTPUT_HTML"] = _replace_state_markers(context["SERVICEOUTPUT"]) + context["SERVICEOUTPUT_HTML"] = context["SERVICEOUTPUT"] long_serviceoutput = ( context["LONGSERVICEOUTPUT"].replace("\\n", "
").replace("\n", "
") ) - context["LONGSERVICEOUTPUT_HTML"] = _replace_state_markers(long_serviceoutput) + context["LONGSERVICEOUTPUT_HTML"] = long_serviceoutput # Compute the subject of the mail if context["WHAT"] == "HOST": @@ -817,66 +597,40 @@ def extend_context(context: dict[str, str]) -> None: context["SUBJECT"] = utils.substitute_context(tmpl, context) -def event_templates(notification_type: str) -> tuple[str, str]: +def txt_event_template(notification_type: str) -> str: # Returns an event summary if notification_type in ["PROBLEM", "RECOVERY"]: - return ( - "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$", - '$PREVIOUS@HARDSTATE$$@STATE$', - ) + return "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$" if notification_type == "FLAPPINGSTART": - return "Started Flapping", "Started Flapping" + return "Started Flapping" if notification_type == "FLAPPINGSTOP": - return ( - "Stopped Flapping ($@SHORTSTATE$)", - 'Stopped Flapping (while $@STATE$)', - ) + return "Stopped Flapping ($@SHORTSTATE$)" if notification_type == "FLAPPINGDISABLED": - return ( - "Disabled Flapping ($@SHORTSTATE$)", - 'Disabled Flapping (while $@STATE$)', - ) + return "Disabled Flapping ($@SHORTSTATE$)" if notification_type == "DOWNTIMESTART": - return ( - "Downtime Start ($@SHORTSTATE$)", - 'Downtime Start (while $@STATE$)', - ) + return "Downtime Start ($@SHORTSTATE$)" if notification_type == "DOWNTIMEEND": - return ( - "Downtime End ($@SHORTSTATE$)", - 'Downtime End (while $@STATE$)', - ) + return "Downtime End ($@SHORTSTATE$)" if notification_type == "DOWNTIMECANCELLED": - return ( - "Downtime Cancelled ($@SHORTSTATE$)", - 'Downtime Cancelled (while $@STATE$)', - ) + return "Downtime Cancelled ($@SHORTSTATE$)" if notification_type == "ACKNOWLEDGEMENT": - return ( - "Acknowledged ($@SHORTSTATE$)", - 'Acknowledged (while $@STATE$)', - ) + return "Acknowledged ($@SHORTSTATE$)" if notification_type == "CUSTOM": - return ( - "Custom Notification ($@SHORTSTATE$)", - 'Custom Notification (while $@STATE$)', - ) + return "Custom Notification ($@SHORTSTATE$)" if notification_type.startswith("ALERTHANDLER"): # The notification_type here is "ALERTHANDLER (exit_code)" - return notification_type, notification_type - return notification_type, notification_type + return notification_type + return notification_type def body_templates( what: str, is_alert_handler: bool, elements: list[str], - body_elements: list[tuple[str, str, bool, str, str, str, str]], -) -> tuple[str, str]: - even = "even" + body_elements: list[tuple[str, str, bool, str, str, str]], +) -> str: tmpl_txt: list[str] = [] - tmpl_html: list[str] = [] - for name, whence, forced, nottype, title, txt, html in body_elements: + for name, whence, forced, nottype, title, txt in body_elements: if nottype == "alerthandler" and not is_alert_handler: continue @@ -885,10 +639,8 @@ def body_templates( if (whence in ("both", what)) and (forced or (name in elements)): tmpl_txt += "%-20s %s\n" % (title + ":", txt) - tmpl_html += f'{title}{html}' - even = "odd" if even == "even" else "even" - return "".join(tmpl_txt), "".join(tmpl_html) + return "".join(tmpl_txt) # TODO: NamedTuple? @@ -902,7 +654,7 @@ def __init__( reply_to: str, content_txt: str, content_html: str, - attachments: AttachmentList, + attachments: Sequence[Attachment], ) -> None: self.context = context self.mailto = mailto @@ -924,17 +676,28 @@ def __init__( parameters, contexts = context_function() hosts = set() - for i, c in enumerate(contexts, 1): - c.update(parameters) - escaped_context = utils.html_escape_context(c) + all_contexts_updated: list[dict[str, str]] = [] + for single_context in contexts: + single_context.update(parameters) + escaped_context = utils.html_escape_context(single_context) extend_context(escaped_context) - - txt, html, att = construct_content(escaped_context, is_bulk=True, notification_number=i) + all_contexts_updated.append(escaped_context) + + for i, c in enumerate(all_contexts_updated, 1): + txt, html, att = construct_content( + c, + is_bulk=True, + bulk_summary=all_contexts_updated if i == 1 else None, + last_bulk_entry=i == len(all_contexts_updated), + notification_number=i, + ) content_txt += txt content_html += html attachments += att hosts.add(c["HOSTNAME"]) + attachments = _add_template_attachments(escaped_context, attachments) + # TODO: cleanup duplicate code with SingleEmailContent # TODO: the context is only needed because of SMPT settings used in send_mail super().__init__( @@ -970,6 +733,8 @@ def __init__(self, context_function: Callable[[], dict[str, str]]) -> None: extend_context(escaped_context) content_txt, content_html, attachments = construct_content(escaped_context) + attachments = _add_template_attachments(context, attachments) + # TODO: cleanup duplicate code with BulkEmailContent # TODO: the context is only needed because of SMPT settings used in send_mail super().__init__( @@ -990,6 +755,38 @@ def __init__(self, context_function: Callable[[], dict[str, str]]) -> None: ) +def _add_template_attachments( + context: dict[str, str], + attachments: list[Attachment], +) -> list[Attachment]: + # always needed + for icon in [ + "checkmk_logo.png", + "overview.png", + ]: + attachments.append(attach_file(icon=icon)) + + if context.get("PARAMETER_CONTACT_GROUPS"): + attachments.append(attach_file(icon="contact_groups.png")) + if elements := context.get("PARAMETER_ELEMENTSS", "graph abstime longoutput").split(): + if "graph" in elements: + attachments.append(attach_file(icon="graph.png")) + elements.remove("graph") + if elements: + attachments.append(attach_file(icon="additional.png")) + if context.get("PARAMETER_SVC_LABELS") or context.get("PARAMETER_HOST_LABELS"): + attachments.append(attach_file(icon="label.png")) + if context.get("PARAMETER_HOST_TAGS"): + attachments.append(attach_file(icon="vector.png")) + + return attachments + + +def attach_file(icon: str) -> Attachment: + with open(web_dir + f"/htdocs/images/icons/{icon}", "rb") as file: + return Attachment(what="img", name=icon, contents=file.read(), how="inline") + + def main() -> NoReturn: content = ( BulkEmailContent(utils.read_bulk_contexts) diff --git a/cmk/notification_plugins/utils.py b/cmk/notification_plugins/utils.py index 48a7a34c82e..e2dc3a16a71 100644 --- a/cmk/notification_plugins/utils.py +++ b/cmk/notification_plugins/utils.py @@ -231,23 +231,44 @@ def get_bulk_notification_subject(contexts: list[dict[str, str]], hosts: Iterabl ################################################################################################# # REST -def retrieve_from_passwordstore(parameter: str) -> str: - values = parameter.split() - - if len(values) == 2: - if values[0] == "store": - value = cmk.utils.password_store.extract(values[1]) +def retrieve_from_passwordstore(parameter: str | list[str]) -> str: + if isinstance(parameter, list): + if "explicit_password" in parameter: + value: str | None = parameter[-1] + else: + value = cmk.utils.password_store.extract(parameter[-2]) if value is None: sys.stderr.write("Unable to retrieve password from passwordstore") sys.exit(2) - else: - value = values[1] else: - value = values[0] + # old valuespec style + values = parameter.split() + + if len(values) == 2: + if values[0] == "store": + value = cmk.utils.password_store.extract(values[1]) + if value is None: + sys.stderr.write("Unable to retrieve password from passwordstore") + sys.exit(2) + else: + value = values[1] + else: + value = values[0] + assert value is not None return value +def _get_password_from_env_or_context(key: str, context: dict[str, str] | None = None) -> str: + """ + Since 2.4 the passwords are stored in FormSpec format, this leads to + multiple keys in the notification context + """ + source = context if context else os.environ + password_parameter_list = [source[k] for k in source if k.startswith(key)] + return retrieve_from_passwordstore(password_parameter_list) + + def post_request( message_constructor: Callable[[dict[str, str]], dict[str, str | object]], url: str | None = None, diff --git a/cmk/piggyback/__init__.py b/cmk/piggyback/__init__.py index 3ee136c7800..139d92d4e14 100644 --- a/cmk/piggyback/__init__.py +++ b/cmk/piggyback/__init__.py @@ -6,27 +6,25 @@ from . import config from ._storage import ( cleanup_piggyback_files, - get_piggyback_raw_data, + get_messages_for, get_piggybacked_host_with_sources, - load_last_distribution_time, move_for_host_rename, PiggybackMessage, PiggybackMetaData, remove_source_status_file, - store_last_distribution_time, store_piggyback_raw_data, + watch_new_messages, ) __all__ = [ - "config", "cleanup_piggyback_files", + "config", + "get_messages_for", "get_piggybacked_host_with_sources", - "get_piggyback_raw_data", - "PiggybackMetaData", + "move_for_host_rename", "PiggybackMessage", + "PiggybackMetaData", "remove_source_status_file", "store_piggyback_raw_data", - "move_for_host_rename", - "load_last_distribution_time", - "store_last_distribution_time", + "watch_new_messages", ] diff --git a/cmk/piggyback/_inotify.py b/cmk/piggyback/_inotify.py new file mode 100644 index 00000000000..88b88ad73b9 --- /dev/null +++ b/cmk/piggyback/_inotify.py @@ -0,0 +1,189 @@ +#!/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. +"""Small wrapper for the kernels `inotify` feature + +Existing libraries seem to be rather unmaintained or lack +features that we want (type annotations). + +This is quite stripped down to only provide what we currently need, +rather than being a comprehensive interface to what the kernel offers. + +As this is currently only needed for the piggyback hub, we put it here. +""" + +import enum +import os +from collections.abc import Sequence +from ctypes import c_int, CDLL, get_errno +from ctypes.util import find_library +from dataclasses import dataclass +from fcntl import ioctl +from io import FileIO +from os import fsdecode, fsencode +from pathlib import Path +from select import poll +from struct import calcsize, unpack_from +from termios import FIONREAD +from typing import Iterator + + +class Masks(enum.IntFlag): + """For watching and describing occurred event. + + This list is outdated (incomplete), but currently + this is more than enough for our needs. + """ + + # These be passed to add_watch, *and* returned in an Event instance: + ACCESS = 0x00000001 #: File was accessed + MODIFY = 0x00000002 #: File was modified + ATTRIB = 0x00000004 #: Metadata changed + CLOSE_WRITE = 0x00000008 #: Writable file was closed + CLOSE_NOWRITE = 0x00000010 #: Unwritable file closed + OPEN = 0x00000020 #: File was opened + MOVED_FROM = 0x00000040 #: File was moved from X + MOVED_TO = 0x00000080 #: File was moved to Y + CREATE = 0x00000100 #: Subfile was created + DELETE = 0x00000200 #: Subfile was deleted + DELETE_SELF = 0x00000400 #: Self was deleted + MOVE_SELF = 0x00000800 #: Self was moved + + # These can passed to add_watch: + ONLYDIR = 0x01000000 #: only watch the path if it is a directory + DONT_FOLLOW = 0x02000000 #: don't follow a sym link + EXCL_UNLINK = 0x04000000 #: exclude events on unlinked objects + MASK_ADD = 0x20000000 #: add to the mask of an already existing watch + ONESHOT = 0x80000000 #: only send event once + + # These are returned in an Event instance: + UNMOUNT = 0x00002000 #: Backing fs was unmounted + Q_OVERFLOW = 0x00004000 #: Event queue overflowed + IGNORED = 0x00008000 #: File was ignored + ISDIR = 0x40000000 #: event occurred against dir + + +@dataclass(frozen=True) +class Watchee: + """Corresponding to the watch descriptor""" + + wd: int + path: Path + + +class Cookie(int): ... + + +@dataclass(frozen=True) +class Event: + watchee: Watchee + type: Masks + cookie: Cookie + name: str + + +class _EventParser: + _FIXED_EVENT_PART = "iIII" + _FIXED_EVENT_PART_LEN = calcsize(_FIXED_EVENT_PART) + + def __init__(self) -> None: + self._wd_map: dict[int, Path] = {} + + def track(self, wd: int, path: Path) -> None: + self._wd_map[wd] = path + + def drop(self, wd: int) -> None: + self._wd_map.pop(wd) + + def iterate_parsed_events(self, data: bytes) -> Iterator[Event]: + offset = 0 + while offset < len(data): + raw_watch_descriptor, raw_event_type, raw_cookie, bytes_remaining = unpack_from( + self._FIXED_EVENT_PART, data, offset + ) + raw_name = data[ + offset + self._FIXED_EVENT_PART_LEN : offset + + self._FIXED_EVENT_PART_LEN + + bytes_remaining + ].split(b"\x00", 1)[0] + offset = offset + self._FIXED_EVENT_PART_LEN + bytes_remaining + + yield Event( + Watchee(int(raw_watch_descriptor), self._wd_map[raw_watch_descriptor]), + Masks(raw_event_type), + Cookie(raw_cookie), + fsdecode(raw_name), + ) + + +class _LibCINotify: + """Wrap the CDLL object for proper typing""" + + __libc: CDLL | None = None + + def __init__(self): + if self.__libc is None: + libc_so = find_library("c") or "libc.so.6" + self.__libc = CDLL(libc_so, use_errno=True) + self._libc = self.__libc + + def init1(self, flags: int) -> int: + if (rc := int(self._libc.inotify_init1(flags))) == -1: + raise OSError(errno := get_errno(), os.strerror(errno)) + return rc + + def add_watch(self, fd: int, path: bytes, mask: int) -> int: + if (rc := int(self._libc.inotify_add_watch(fd, path, mask))) == -1: + raise OSError(errno := get_errno(), os.strerror(errno)) + return rc + + def rm_watch(self, fd: int, wd: int) -> None: + if self._libc.inotify_rm_watch(fd, wd) == -1: + raise OSError(errno := get_errno(), os.strerror(errno)) + + +class INotify: + def __init__(self): + self._libc = _LibCINotify() + self._parser = _EventParser() + self._fileio = FileIO(self._libc.init1(os.O_CLOEXEC), mode="rb") + self._poller = poll() + self._poller.register(self._fileio.fileno()) + + def add_watch(self, path: Path, mask: Masks) -> Watchee: + watch_descriptor = self._libc.add_watch(self._fileio.fileno(), fsencode(path), mask) + self._parser.track(watch_descriptor, path) + return Watchee(watch_descriptor, path) + + def rm_watch(self, watchee: Watchee) -> None: + self._libc.rm_watch(self._fileio.fileno(), watchee.wd) + self._parser.drop(watchee.wd) + + def read_forever(self) -> Iterator[Event]: + while True: + yield from self.read() + + def read(self, timeout: int | None = None) -> Sequence[Event]: + """Read occured events once. + + If timeout is set and there are no events, wait up to `timeout` + seconds. Otherwise block until there are events. + """ + if timeout is not None and timeout < 0: + raise ValueError(timeout) + data = self._read_bytes() + if ( + not data + and timeout != 0 + and self._poller.poll(None if timeout is None else timeout * 1000) + ): + data = self._read_bytes() + return list(self._parser.iterate_parsed_events(data)) + + def _read_bytes(self) -> bytes: + readable = c_int() + ioctl(self._fileio, FIONREAD, readable) + if not readable.value: + return b"" + return os.read(self._fileio.fileno(), readable.value) diff --git a/cmk/piggyback/_paths.py b/cmk/piggyback/_paths.py index 78859aa0f5c..4d8fda010ba 100644 --- a/cmk/piggyback/_paths.py +++ b/cmk/piggyback/_paths.py @@ -7,7 +7,6 @@ _RELATIVE_PAYLOAD_DIR = "tmp/check_mk/piggyback" _RELATIVE_SOURCE_STATUS_DIR = "tmp/check_mk/piggyback_sources" -_RELATIVE_DISTRIBUTION_STATUS_DIR = "tmp/check_mk/piggyback_distribution" def payload_dir(omd_root: Path) -> Path: @@ -16,7 +15,3 @@ def payload_dir(omd_root: Path) -> Path: def source_status_dir(omd_root: Path) -> Path: return omd_root / _RELATIVE_SOURCE_STATUS_DIR - - -def distribution_status_dir(omd_root: Path) -> Path: - return omd_root / _RELATIVE_DISTRIBUTION_STATUS_DIR diff --git a/cmk/piggyback/_storage.py b/cmk/piggyback/_storage.py index cc895ab7364..77637cb9e67 100644 --- a/cmk/piggyback/_storage.py +++ b/cmk/piggyback/_storage.py @@ -10,14 +10,15 @@ import os import shutil import tempfile -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Iterable, Iterator, Mapping, Sequence from dataclasses import asdict, dataclass from pathlib import Path from typing import Self from cmk.utils.hostaddress import HostAddress, HostName -from ._paths import distribution_status_dir, payload_dir, source_status_dir +from ._inotify import Event, INotify, Masks +from ._paths import payload_dir, source_status_dir logger = logging.getLogger(__name__) @@ -30,7 +31,7 @@ class PiggybackMetaData: last_contact: int | None def serialize(self) -> str: - return json.dumps({k: str(v) for k, v in asdict(self).items()}) + return json.dumps({k: None if v is None else str(v) for k, v in asdict(self).items()}) @classmethod def deserialize(cls, serialized: str, /) -> Self: @@ -67,7 +68,48 @@ class PiggybackMessage: # - Path(tmp/check_mk/piggyback_sources/SOURCE).name -def get_piggyback_raw_data( +def watch_new_messages(omd_root: Path) -> Iterator[PiggybackMessage]: + """Yields piggyback messages as they come in.""" + + inotify = INotify() + watch_for_new_piggybacked_hosts = inotify.add_watch(payload_dir(omd_root), Masks.CREATE) + for folder in _get_piggybacked_host_folders(omd_root): + inotify.add_watch(folder, Masks.MOVED_TO) + + for event in inotify.read_forever(): + # check if a new piggybacked host folder was created + if event.watchee == watch_for_new_piggybacked_hosts: + if event.type & Masks.CREATE: + inotify.add_watch(event.watchee.path / event.name, Masks.MOVED_TO) + # Handle all files already in the folder (we rather have duplicates than missing files) + yield from get_messages_for(HostAddress(event.name), omd_root) + continue + + if message := _make_message_from_event(event, omd_root): + yield message + + +def _make_message_from_event(event: Event, omd_root: Path) -> PiggybackMessage | None: + source = HostAddress(event.name) + piggybacked = HostName(event.watchee.path.name) + status_file_path = _get_source_status_file_path(source, omd_root) + payload_file_path = event.watchee.path / event.name + + if (mtime := _get_mtime(payload_file_path)) is None: + return None + + return PiggybackMessage( + PiggybackMetaData( + source=source, + piggybacked=piggybacked, + last_update=mtime, + last_contact=_get_mtime(status_file_path), + ), + payload_file_path.read_bytes(), + ) + + +def get_messages_for( piggybacked_hostname: HostAddress, omd_root: Path ) -> Sequence[PiggybackMessage]: """Returns piggyback messages for the given host""" @@ -132,19 +174,16 @@ def store_piggyback_raw_data( remove_source_status_file(source_hostname, omd_root) return - piggyback_file_paths = [] for piggybacked_hostname, lines in piggybacked_raw_data.items(): - piggyback_file_path = _get_piggybacked_file_path( - source_hostname, piggybacked_hostname, omd_root - ) logger.debug("Storing piggyback data for: %r", piggybacked_hostname) # Raw data is always stored as bytes. Later the content is # converted to unicode in abstact.py:_parse_info which respects # 'encoding' in section options. _write_file_with_mtime( - file_path=piggyback_file_path, content=b"%s\n" % b"\n".join(lines), mtime=timestamp + file_path=_get_piggybacked_file_path(source_hostname, piggybacked_hostname, omd_root), + content=b"%s\n" % b"\n".join(lines), + mtime=timestamp, ) - piggyback_file_paths.append(piggyback_file_path) # Store the last contact with this piggyback source to be able to filter outdated data later # We use the mtime of this file later for comparison. @@ -178,20 +217,6 @@ def _write_file_with_mtime( os.rename(tmp_path, str(file_path)) -def store_last_distribution_time( - source_host: HostName, piggybacked_host: HostName, timestamp: float, omd_root: Path -) -> None: - file_path = _get_distribution_status_file_path(source_host, piggybacked_host, omd_root) - _write_file_with_mtime(file_path=file_path, content=b"", mtime=timestamp) - - -def load_last_distribution_time( - source_host: HostName, piggybacked_host: HostName, omd_root: Path -) -> float | None: - file_path = _get_distribution_status_file_path(source_host, piggybacked_host, omd_root) - return _get_mtime(file_path) - - # .--folders/files-------------------------------------------------------. # | __ _ _ ____ _ _ | # | / _| ___ | | __| | ___ _ __ ___ / / _(_) | ___ ___ | @@ -263,12 +288,6 @@ def _get_piggybacked_file_path( return payload_dir(omd_root).joinpath(piggybacked_hostname, source_hostname) -def _get_distribution_status_file_path( - source_hostname: HostName, piggybacked_hostname: HostName | HostAddress, omd_root: Path -) -> Path: - return distribution_status_dir(omd_root).joinpath(piggybacked_hostname, source_hostname) - - # . # .--clean up------------------------------------------------------------. # | _ | diff --git a/cmk/piggyback_hub/config.py b/cmk/piggyback_hub/config.py index 91fe7963497..4755aa6d257 100644 --- a/cmk/piggyback_hub/config.py +++ b/cmk/piggyback_hub/config.py @@ -5,65 +5,64 @@ import logging import os -import tempfile -from collections.abc import Sequence -from dataclasses import dataclass +from collections.abc import Mapping from pathlib import Path -from typing import Callable, Self +from threading import Event +from typing import Callable from pydantic import BaseModel -from cmk.ccc import store - from cmk.utils.hostaddress import HostName -from cmk.messaging import Channel +from cmk.messaging import Channel, Connection, DeliveryTag, QueueName, RoutingKey -from .paths import create_paths +from .paths import create_paths, PiggybackHubPaths +from .utils import APP_NAME +CONFIG_ROUTE = RoutingKey("config") -@dataclass(frozen=True) -class Target: - host_name: HostName - site_id: str +CONFIG_QUEUE = QueueName("config") class PiggybackHubConfig(BaseModel): - targets: Sequence[Target] = [] - - def serialize(self) -> str: - return self.model_dump_json() - - @classmethod - def deserialize(cls, raw: str) -> Self: - return cls.model_validate_json(raw) + targets: Mapping[HostName, str] = {} def save_config_on_message( - logger: logging.Logger, omd_root: Path -) -> Callable[[Channel[PiggybackHubConfig], PiggybackHubConfig], None]: - def _on_message(_channel: Channel[PiggybackHubConfig], received: PiggybackHubConfig) -> None: + logger: logging.Logger, omd_root: Path, reload_config: Event +) -> Callable[[Channel[PiggybackHubConfig], DeliveryTag, PiggybackHubConfig], None]: + def _on_message( + channel: Channel[PiggybackHubConfig], + delivery_tag: DeliveryTag, + received: PiggybackHubConfig, + ) -> None: logger.debug("New configuration received") - config_path = create_paths(omd_root).config - config_path.parent.mkdir(mode=0o770, exist_ok=True, parents=True) - with tempfile.NamedTemporaryFile( - "w", dir=str(config_path.parent), prefix=f".{config_path.name}.new", delete=False - ) as tmp: - tmp_path = tmp.name - tmp.write(received.serialize()) + save_config(create_paths(omd_root), received) - os.rename(tmp_path, str(config_path)) + reload_config.set() + + channel.acknowledge(delivery_tag) return _on_message -def save_config(root_path: Path, config: PiggybackHubConfig) -> None: - store.save_text_to_file(create_paths(root_path).config, config.serialize()) +def save_config(paths: PiggybackHubPaths, config: PiggybackHubConfig) -> None: + paths.config.parent.mkdir(mode=0o770, exist_ok=True, parents=True) + tmp_path = paths.config.with_suffix(f".{os.getpid()}.tmp") + tmp_path.write_text(f"{config.model_dump_json()}\n") + tmp_path.rename(paths.config) -def load_config(root_path: Path) -> PiggybackHubConfig: - config_path = create_paths(root_path).config - if not config_path.exists(): +def load_config(paths: PiggybackHubPaths) -> PiggybackHubConfig: + try: + return PiggybackHubConfig.model_validate_json(paths.config.read_text()) + except FileNotFoundError: return PiggybackHubConfig() - return PiggybackHubConfig.deserialize(store.load_text_from_file(config_path)) + + +def distribute_config(configs: Mapping[str, PiggybackHubConfig], omd_root: Path) -> None: + for site_id, config in configs.items(): + with Connection(APP_NAME, omd_root) as conn: + channel = conn.channel(PiggybackHubConfig) + channel.publish_for_site(site_id, config, routing=CONFIG_ROUTE) diff --git a/cmk/piggyback_hub/main.py b/cmk/piggyback_hub/main.py index 3bc5374b4aa..f6c9cf25173 100644 --- a/cmk/piggyback_hub/main.py +++ b/cmk/piggyback_hub/main.py @@ -8,22 +8,25 @@ import os import signal import sys -import time from dataclasses import dataclass +from itertools import cycle from logging import getLogger from logging.handlers import WatchedFileHandler from pathlib import Path -from types import FrameType +from threading import Event from cmk.ccc.daemon import daemonize, pid_file_lock +from cmk.messaging import QueueName from cmk.piggyback_hub.config import PiggybackHubConfig, save_config_on_message from cmk.piggyback_hub.payload import ( PiggybackPayload, save_payload_on_message, - SendingPayloadThread, + SendingPayloadProcess, ) -from cmk.piggyback_hub.utils import ReceivingThread, SignalException + +from .config import CONFIG_QUEUE +from .utils import APP_NAME, ReceivingProcess VERBOSITY_MAP = { 0: logging.INFO, @@ -80,41 +83,54 @@ def _setup_logging(args: Arguments) -> logging.Logger: if args.foreground else WatchedFileHandler(Path(args.log_file)) ) - handler.setFormatter(logging.Formatter("%(asctime)s [%(levelno)s] [%(name)s] %(message)s")) + handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] [%(name)s] %(message)s")) logger.addHandler(handler) - logger.setLevel(VERBOSITY_MAP.get(args.verbosity, logging.INFO)) + logger.setLevel(VERBOSITY_MAP[min(args.verbosity, 2)]) return logger -def signal_handler(_signum: int, _stack_frame: FrameType | None) -> None: - raise SignalException() - +def run_piggyback_hub(logger: logging.Logger, omd_root: Path) -> int: + reload_config = Event() + processes = ( + ReceivingProcess( + logger, + omd_root, + PiggybackPayload, + save_payload_on_message(logger, omd_root), + QueueName("payload"), + message_ttl=600, + ), + SendingPayloadProcess(logger, omd_root, reload_config), + ReceivingProcess( + logger, + omd_root, + PiggybackHubConfig, + save_config_on_message(logger, omd_root, reload_config), + CONFIG_QUEUE, + message_ttl=None, + ), + ) -def _register_signal_handler() -> None: - signal.signal(signal.SIGTERM, signal_handler) + for p in processes: + p.start() + def terminate_all_processes() -> int: + logger.info("Stopping: %s", APP_NAME) + for p in processes: + p.terminate() + return 0 -def run_piggyback_hub(logger: logging.Logger, omd_root: Path) -> None: - # TODO: remove this loop when rabbitmq available in site - for _ in range(1_000_000): - time.sleep(1_000) + signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(terminate_all_processes())) - receiving_thread = ReceivingThread( - logger, omd_root, PiggybackPayload, save_payload_on_message(logger, omd_root), "payload" - ) - sending_thread = SendingPayloadThread(logger, omd_root) - receive_config_thread = ReceivingThread( - logger, omd_root, PiggybackHubConfig, save_config_on_message(logger, omd_root), "config" - ) + # All processes should run forever. Die if either finishes. + for proc in cycle(processes): + proc.join(timeout=5) + if not proc.is_alive(): + return terminate_all_processes() - receiving_thread.start() - sending_thread.start() - receive_config_thread.start() - receiving_thread.join() - sending_thread.join() - receive_config_thread.join() + raise RuntimeError("Unreachable code reached") def main(argv: list[str] | None = None) -> int: @@ -124,15 +140,7 @@ def main(argv: list[str] | None = None) -> int: args = _parse_arguments(argv) logger = _setup_logging(args) - logger.info("Starting Piggyback Hub daemon.") - - try: - _register_signal_handler() - except Exception as e: - if args.debug: - raise - logger.exception("Unhandled exception: %s.", e) - return 1 + logger.info("Starting: %s", APP_NAME) if not args.foreground: daemonize() @@ -140,14 +148,9 @@ def main(argv: list[str] | None = None) -> int: try: with pid_file_lock(Path(args.pid_file)): - run_piggyback_hub(logger, Path(args.omd_root)) - except SignalException: - logger.info("Stopping Piggyback Hub daemon.") - except Exception as e: + return run_piggyback_hub(logger, Path(args.omd_root)) + except Exception as exc: if args.debug: raise - logger.exception("Unhandled exception: %s.", e) + logger.exception("Exception: %s: %s", APP_NAME, exc) return 1 - - logger.info("Shutting down.") - return 0 diff --git a/cmk/piggyback_hub/payload.py b/cmk/piggyback_hub/payload.py index d4eb2777e26..36faae9c80b 100644 --- a/cmk/piggyback_hub/payload.py +++ b/cmk/piggyback_hub/payload.py @@ -3,32 +3,27 @@ # 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 import logging -import threading -import time -from collections.abc import Sequence +import multiprocessing +import signal from pathlib import Path +from threading import Event from typing import Callable, Self from pydantic import BaseModel from cmk.utils.hostaddress import HostName -from cmk.messaging import Channel, Connection +from cmk.messaging import Channel, CMKConnectionError, DeliveryTag, RoutingKey from cmk.piggyback import ( - get_piggyback_raw_data, - load_last_distribution_time, PiggybackMessage, - PiggybackMetaData, - store_last_distribution_time, store_piggyback_raw_data, + watch_new_messages, ) -from cmk.piggyback_hub.config import PiggybackHubConfig, Target -from cmk.piggyback_hub.paths import create_paths -from cmk.piggyback_hub.utils import SignalException -SENDING_PAUSE = 60 # [s] +from .config import load_config, PiggybackHubConfig +from .paths import create_paths +from .utils import make_log_and_exit, reconnect class PiggybackPayload(BaseModel): @@ -36,21 +31,26 @@ class PiggybackPayload(BaseModel): target_host: str last_update: int last_contact: int | None - sections: Sequence[bytes] - - def serialize(self) -> str: - return self.model_dump_json() + sections: bytes @classmethod - def deserialize(cls, raw: str) -> Self: - return cls.model_validate_json(raw) + def from_message(cls, message: PiggybackMessage) -> Self: + return cls( + source_host=message.meta.source, + target_host=message.meta.piggybacked, + last_update=message.meta.last_update, + last_contact=message.meta.last_contact, + sections=message.raw_data, + ) def save_payload_on_message( logger: logging.Logger, omd_root: Path, -) -> Callable[[Channel[PiggybackPayload], PiggybackPayload], None]: - def _on_message(_channel: Channel[PiggybackPayload], received: PiggybackPayload) -> None: +) -> Callable[[Channel[PiggybackPayload], DeliveryTag, PiggybackPayload], None]: + def _on_message( + channel: Channel[PiggybackPayload], delivery_tag: DeliveryTag, received: PiggybackPayload + ) -> None: logger.debug( "Received payload for piggybacked host '%s' from source host '%s'", received.target_host, @@ -58,110 +58,75 @@ def _on_message(_channel: Channel[PiggybackPayload], received: PiggybackPayload) ) store_piggyback_raw_data( source_hostname=HostName(received.source_host), - piggybacked_raw_data={HostName(received.target_host): received.sections}, + piggybacked_raw_data={HostName(received.target_host): (received.sections,)}, timestamp=received.last_update, omd_root=omd_root, status_file_timestamp=received.last_contact, ) + channel.acknowledge(delivery_tag) return _on_message -def _load_piggyback_targets( - piggyback_hub_config_path: Path, current_site_id: str -) -> Sequence[Target]: - if not piggyback_hub_config_path.exists(): - return [] - with open(piggyback_hub_config_path, "r") as f: - piggyback_hub_config = PiggybackHubConfig.model_validate_json(json.loads(f.read())) - - targets = [] - for target in piggyback_hub_config.targets: - match target: - case Target(): - if target.site_id != current_site_id: - targets.append(target) - case other: - raise ValueError(f"Invalid piggyback_hub configuration: {other}") - return targets - - -def _is_message_already_distributed(meta: PiggybackMetaData, omd_root: Path) -> bool: - if ( - distribution_time := load_last_distribution_time(meta.source, meta.piggybacked, omd_root) - ) is None: - return False - - return distribution_time >= meta.last_update - - -def _get_piggyback_raw_data_to_send( - target_host: HostName, omd_root: Path -) -> Sequence[PiggybackMessage]: - return [ - data - for data in get_piggyback_raw_data(target_host, omd_root) - if not _is_message_already_distributed(data.meta, omd_root) - ] - - -def _send_message( - channel: Channel, - piggyback_message: PiggybackMessage, - target_site_id: str, - omd_root: Path, - routing: str, -) -> None: - channel.publish_for_site( - target_site_id, - PiggybackPayload( - source_host=piggyback_message.meta.source, - target_host=piggyback_message.meta.piggybacked, - last_update=piggyback_message.meta.last_update, - last_contact=piggyback_message.meta.last_contact, - sections=[piggyback_message.raw_data], - ), - routing=routing, - ) - store_last_distribution_time( - piggyback_message.meta.source, - piggyback_message.meta.piggybacked, - piggyback_message.meta.last_update, - omd_root, - ) - - -class SendingPayloadThread(threading.Thread): - def __init__(self, logger: logging.Logger, omd_root: Path): +class SendingPayloadProcess(multiprocessing.Process): + def __init__(self, logger: logging.Logger, omd_root: Path, reload_config: Event) -> None: super().__init__() self.logger = logger self.omd_root = omd_root - self.config_path = create_paths(omd_root).config + self.site = omd_root.name + self.paths = create_paths(omd_root) + self.reload_config = reload_config + self.task_name = "publishing on queue 'payload'" def run(self): + self.logger.info("Starting: %s", self.task_name) + signal.signal( + signal.SIGTERM, + make_log_and_exit(self.logger.debug, f"Stopping: {self.task_name}"), + ) + + config = load_config(self.paths) + self.logger.debug("Loaded configuration: %r", config) + try: - with Connection("piggyback-hub", self.omd_root) as conn: - channel = conn.channel(PiggybackPayload) - - while True: - targets = _load_piggyback_targets(self.config_path, self.omd_root.name) - for target in targets: - for piggyback_message in _get_piggyback_raw_data_to_send( - target.host_name, self.omd_root - ): - self.logger.debug( - "Sending payload for piggybacked host '%s' from source host '%s' to site '%s'", - piggyback_message.meta.piggybacked, - piggyback_message.meta.source, - target.site_id, - ) - _send_message( - channel, piggyback_message, target.site_id, self.omd_root, "payload" - ) - - time.sleep(SENDING_PAUSE) - except SignalException: - self.logger.debug("Stopping distributing messages") + for conn in reconnect(self.omd_root, self.logger, self.task_name): + with conn: + channel = conn.channel(PiggybackPayload) + for piggyback_message in watch_new_messages(self.omd_root): + self._handle_message(channel, config, piggyback_message) + + except CMKConnectionError as exc: + self.logger.error("Stopping: %s: %s", self.task_name, exc) + except Exception as exc: + self.logger.exception("Exception: %s: %s", self.task_name, exc) + raise + + def _handle_message( + self, + channel: Channel[PiggybackPayload], + config: PiggybackHubConfig, + message: PiggybackMessage, + ) -> None: + config = self._check_for_config_reload(config) + + if (site_id := config.targets.get(message.meta.piggybacked, self.site)) is self.site: return - except Exception as e: - self.logger.exception("Unhandled exception: %s.", e) + + self.logger.debug( + "%s: from host '%s' to host '%s' on site '%s'", + self.task_name.title(), + message.meta.source, + message.meta.piggybacked, + site_id, + ) + channel.publish_for_site( + site_id, PiggybackPayload.from_message(message), routing=RoutingKey("payload") + ) + + def _check_for_config_reload(self, current_config: PiggybackHubConfig) -> PiggybackHubConfig: + if not self.reload_config.is_set(): + return current_config + self.logger.debug("Reloading configuration") + config = load_config(self.paths) + self.reload_config.clear() + return config diff --git a/cmk/piggyback_hub/utils.py b/cmk/piggyback_hub/utils.py index e583f12794e..0a71a5188ae 100644 --- a/cmk/piggyback_hub/utils.py +++ b/cmk/piggyback_hub/utils.py @@ -4,37 +4,41 @@ # conditions defined in the file COPYING, which is part of this source code package. import logging -import threading -from collections.abc import Mapping +import multiprocessing +import signal +import sys +import time +from collections.abc import Iterator from pathlib import Path -from typing import Callable, Generic, Protocol, Self, TypeVar +from ssl import SSLCertVerificationError +from typing import Callable, Generic, TypeVar -from cmk.messaging import Channel, Connection +from pydantic import BaseModel -from .config import PiggybackHubConfig +from cmk.messaging import AppName, Channel, CMKConnectionError, Connection, DeliveryTag, QueueName +APP_NAME = AppName("piggyback-hub") -class _ModelP(Protocol): - def serialize(self) -> str: ... - @classmethod - def deserialize(cls, raw: str) -> Self: ... +_ModelT = TypeVar("_ModelT", bound=BaseModel) -_ModelT = TypeVar("_ModelT", bound=_ModelP) +def make_log_and_exit(log: Callable[[str], None], message: str) -> Callable[[object, object], None]: + def log_and_exit(signum: object, frame: object) -> None: + log(message) + sys.exit(0) + return log_and_exit -class SignalException(Exception): - pass - -class ReceivingThread(threading.Thread, Generic[_ModelT]): +class ReceivingProcess(multiprocessing.Process, Generic[_ModelT]): def __init__( self, logger: logging.Logger, omd_root: Path, model: type[_ModelT], - callback: Callable[[Channel[_ModelT], _ModelT], None], - queue: str, + callback: Callable[[Channel[_ModelT], DeliveryTag, _ModelT], None], + queue: QueueName, + message_ttl: int | None, ) -> None: super().__init__() self.logger = logger @@ -42,27 +46,47 @@ def __init__( self.model = model self.callback = callback self.queue = queue + self.message_ttl = message_ttl + self.task_name = f"receiving on queue '{self.queue.value}'" def run(self) -> None: + self.logger.info("Starting: %s", self.task_name) + signal.signal( + signal.SIGTERM, + make_log_and_exit(self.logger.debug, f"Stopping: {self.task_name}"), + ) try: - with Connection("piggyback-hub", self.omd_root) as conn: - channel: Channel[_ModelT] = conn.channel(self.model) - channel.queue_declare(queue=self.queue, bindings=(self.queue,)) - - self.logger.debug("Waiting for messages in queue %s", self.queue) - channel.consume(self.callback, queue=self.queue) - - except SignalException: - self.logger.debug("Stopping receiving messages") - return - except Exception as e: - self.logger.exception("Unhandled exception: %s.", e) - - -def distribute(configs: Mapping[str, PiggybackHubConfig], omd_root: Path) -> None: - # TODO: remove the return statement and uncomment the code below after fix the flaky integration test - return - # for site_id, config in configs.items(): - # with Connection("piggyback-hub", omd_root) as conn: - # channel = conn.channel(PiggybackHubConfig) - # channel.publish_for_site(site_id, config, routing="config") + for conn in reconnect(self.omd_root, self.logger, self.task_name): + with conn: + channel: Channel[_ModelT] = conn.channel(self.model) + channel.queue_declare(queue=self.queue, message_ttl=self.message_ttl) + + self.logger.debug("Consuming: %s", self.task_name) + channel.consume(self.queue, self.callback) + + except CMKConnectionError as exc: + self.logger.error("Stopping: %s: %s", self.task_name, exc) + except Exception as exc: + self.logger.exception("Exception: %s: %s", self.task_name, exc) + raise + + +def reconnect(omd_root: Path, logger: logging.Logger, task_name: str) -> Iterator[Connection]: + attempts = 10 + interval = 3 + + def _try_to_reconnect() -> Connection: + error_message = "" + for _attempt in range(attempts): + try: + # Note: We re-read the certificates here. + return Connection(APP_NAME, omd_root) + except SSLCertVerificationError as exc: + # Certs could have changed. Retry. + time.sleep(interval) + logger.debug("Reconnecting: %s: %s", task_name, exc) + error_message = str(exc) + raise CMKConnectionError(f"Unable to reconnect after {attempts} attempts: {error_message}") + + while True: + yield _try_to_reconnect() diff --git a/cmk/plugins/azure/rulesets/azure.py b/cmk/plugins/azure/rulesets/azure.py index 8c8bafd99fb..921ba2c6a8e 100644 --- a/cmk/plugins/azure/rulesets/azure.py +++ b/cmk/plugins/azure/rulesets/azure.py @@ -180,7 +180,87 @@ def _migrate_services_to_monitor(values: object) -> list[str]: raise TypeError(values) -def _get_services_fs() -> Mapping[str, DictElement]: +def _migrate(value: object) -> Mapping[str, object]: + if not isinstance(value, dict): + raise TypeError(value) + + value.pop("sequential", None) + + # Migrate from 2.3 valuespec to 2.4 formspec + if import_tags := value.get("import_tags"): + if import_tags == "all_tags": + value["import_tags"] = (import_tags, None) + + return value + + +def _migrate_authority(value: object) -> str: + if value == "global": + return "global_" + if isinstance(value, str): + return value + raise TypeError(value) + + +def configuration_authentication() -> Mapping[str, DictElement]: + return { + "subscription": DictElement( + parameter_form=String( + title=Title("Subscription ID"), + ) + ), + "tenant": DictElement( + parameter_form=String( + title=Title("Tenant ID / Directory ID"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + required=True, + ), + "client": DictElement( + parameter_form=String( + title=Title("Client ID / Application ID"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + required=True, + ), + "secret": DictElement( + parameter_form=Password( + migrate=migrate_to_password, + title=Title("Client Secret"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + required=True, + ), + } + + +def configuration_authority() -> Mapping[str, DictElement]: + return { + "authority": DictElement( + parameter_form=SingleChoice( + title=Title("Authority"), + migrate=_migrate_authority, + elements=[ + SingleChoiceElement(name="global_", title=Title("Global")), + SingleChoiceElement(name="china", title=Title("China")), + ], + prefill=DefaultValue("global_"), + help_text=Help( + "Specify the authority you want to connect to:" + "
    " + "
  • Global: Login into 'https://login.microsoftonline.com'," + " get data from 'https://graph.microsoft.com'
  • " + "
  • China: Login into 'https://login.partner.microsoftonline.cn'," + " get data from 'https://microsoftgraph.chinacloudapi.cn'
  • " + "
" + ), + ), + required=True, + ) + } + + +def configuration_services() -> Mapping[str, DictElement]: return { "services": DictElement( parameter_form=MultipleChoice( @@ -202,155 +282,97 @@ def _get_services_fs() -> Mapping[str, DictElement]: } -def _migrate_sequential(value: object) -> Mapping[str, object]: - if not isinstance(value, dict): - raise TypeError(value) - - value.pop("sequential", None) - return value - - -def _migrate_authority(value: object) -> str: - if value == "global": - return "global_" - if isinstance(value, str): - return value - raise TypeError(value) - - -def _formspec() -> Dictionary: - return Dictionary( - migrate=_migrate_sequential, - elements={ - "authority": DictElement( - parameter_form=SingleChoice( - title=Title("Authority"), - migrate=_migrate_authority, - elements=[ - SingleChoiceElement(name="global_", title=Title("Global")), - SingleChoiceElement(name="china", title=Title("China")), - ], - prefill=DefaultValue("global_"), - help_text=Help( - "Specify the authority you want to connect to:" - "
    " - "
  • Global: Login into 'https://login.microsoftonline.com'," - " get data from 'https://graph.microsoft.com'
  • " - "
  • China: Login into 'https://login.partner.microsoftonline.cn'," - " get data from 'https://microsoftgraph.chinacloudapi.cn'
  • " - "
" - ), - ), - required=True, +def configuration_advanced() -> Mapping[str, DictElement]: + return { + "proxy": DictElement( + parameter_form=Proxy( + migrate=migrate_to_proxy, ), - "subscription": DictElement( - parameter_form=String( - title=Title("Subscription ID"), + ), + "config": DictElement( + parameter_form=Dictionary( + title=Title("Retrieve information about..."), + # Since we introduced this, Microsoft has already reduced the number + # of allowed API requests. At the time of this writing (11/2018) + # you can find the number here: + # https://docs.microsoft.com/de-de/azure/azure-resource-manager/resource-manager-request-limits + help_text=Help( + "By default, all resources associated to the configured tenant ID" + " will be monitored. " + "However, since Microsoft limits API calls to %s per hour" + " (%s per minute), you can restrict the monitoring to individual" + " resource groups and resources." ) + % ("12000", "200"), + elements={ + "explicit": _special_agents_azure_explicit_config(), + "tag_based": _special_agents_azure_tag_based_config(), + }, ), - "tenant": DictElement( - parameter_form=String( - title=Title("Tenant ID / Directory ID"), - custom_validate=(validators.LengthInRange(min_value=1),), - ), - required=True, - ), - "client": DictElement( - parameter_form=String( - title=Title("Client ID / Application ID"), - custom_validate=(validators.LengthInRange(min_value=1),), - ), - required=True, - ), - "secret": DictElement( - parameter_form=Password( - migrate=migrate_to_password, - title=Title("Client Secret"), - custom_validate=(validators.LengthInRange(min_value=1),), - ), - required=True, - ), - "proxy": DictElement( - parameter_form=Proxy( - migrate=migrate_to_proxy, + required=True, + ), + "piggyback_vms": DictElement( + parameter_form=SingleChoice( + title=Title("Map data relating to VMs"), + help_text=Help( + "By default, data relating to a VM is sent to the group host" + " corresponding to the resource group of the VM, the same way" + " as for any other resource. If the VM is present in your" + " monitoring as a separate host, you can choose to send the data" + " to the VM itself." ), + elements=[ + SingleChoiceElement(name="grouphost", title=Title("Map data to group host")), + SingleChoiceElement(name="self", title=Title("Map data to the VM itself")), + ], + prefill=DefaultValue("grouphost"), ), - **_get_services_fs(), - "config": DictElement( - parameter_form=Dictionary( - title=Title("Retrieve information about..."), - # Since we introduced this, Microsoft has already reduced the number - # of allowed API requests. At the time of this writing (11/2018) - # you can find the number here: - # https://docs.microsoft.com/de-de/azure/azure-resource-manager/resource-manager-request-limits - help_text=Help( - "By default, all resources associated to the configured tenant ID" - " will be monitored. " - "However, since Microsoft limits API calls to %s per hour" - " (%s per minute), you can restrict the monitoring to individual" - " resource groups and resources." - ) - % ("12000", "200"), - elements={ - "explicit": _special_agents_azure_explicit_config(), - "tag_based": _special_agents_azure_tag_based_config(), - }, + ), + "import_tags": DictElement( + parameter_form=CascadingSingleChoice( + title=Title("Import tags as host/service labels"), + help_text=Help( + "By default, Checkmk imports all Azure tags as host/service labels. " + "The imported tags are added as host labels for resource groups and " + "VMs monitored as hosts and as service labels for resources monitored " + "as services. The label syntax is 'cmk/azure/tag/{key}:{value}'.
" + "Additionally, each host representing a resource group is given the " + "host label 'cmk/azure/resource_group:{rg_name}', and VMs monitored as " + "hosts are given the host label 'cmk/azure/vm:instance', which is done " + "independent of this option.
" + "You can further restrict the imported tags by specifying a pattern " + "which Checkmk searches for in the key of the Azure tag, or you can " + "disable the import of Azure tags altogether." ), - required=True, - ), - "piggyback_vms": DictElement( - parameter_form=SingleChoice( - title=Title("Map data relating to VMs"), - help_text=Help( - "By default, data relating to a VM is sent to the group host" - " corresponding to the resource group of the VM, the same way" - " as for any other resource. If the VM is present in your" - " monitoring as a separate host, you can choose to send the data" - " to the VM itself." + elements=[ + CascadingSingleChoiceElement( + name="all_tags", + title=Title("Import all valid tags"), + parameter_form=FixedValue(value=None), ), - elements=[ - SingleChoiceElement( - name="grouphost", title=Title("Map data to group host") + CascadingSingleChoiceElement( + name="filter_tags", + title=Title("Filter valid tags by key pattern"), + parameter_form=RegularExpression( + custom_validate=(validators.LengthInRange(min_value=1),), + predefined_help_text=MatchingScope.INFIX, ), - SingleChoiceElement(name="self", title=Title("Map data to the VM itself")), - ], - prefill=DefaultValue("grouphost"), - ), - ), - "import_tags": DictElement( - parameter_form=CascadingSingleChoice( - title=Title("Import tags as host/service labels"), - help_text=Help( - "By default, Checkmk imports all Azure tags as host/service labels. " - "The imported tags are added as host labels for resource groups and " - "VMs monitored as hosts and as service labels for resources monitored " - "as services. The label syntax is 'cmk/azure/tag/{key}:{value}'.
" - "Additionally, each host representing a resource group is given the " - "host label 'cmk/azure/resource_group:{rg_name}', and VMs monitored as " - "hosts are given the host label 'cmk/azure/vm:instance', which is done " - "independent of this option.
" - "You can further restrict the imported tags by specifying a pattern " - "which Checkmk searches for in the key of the Azure tag, or you can " - "disable the import of Azure tags altogether." ), - elements=[ - CascadingSingleChoiceElement( - name="all_tags", - title=Title("Import all valid tags"), - parameter_form=FixedValue(value=None), - ), - CascadingSingleChoiceElement( - name="filter_tags", - title=Title("Filter valid tags by key pattern"), - parameter_form=RegularExpression( - custom_validate=(validators.LengthInRange(min_value=1),), - predefined_help_text=MatchingScope.INFIX, - ), - ), - ], - prefill=DefaultValue("all_tags"), - ), + ], + prefill=DefaultValue("all_tags"), ), + ), + } + + +def formspec() -> Dictionary: + return Dictionary( + migrate=_migrate, + elements={ + **configuration_authentication(), + **configuration_authority(), + **configuration_services(), + **configuration_advanced(), }, ) @@ -366,5 +388,5 @@ def _formspec() -> Dictionary: "service of the host owning the datasource program." ), topic=Topic.CLOUD, - parameter_form=_formspec, + parameter_form=formspec, ) diff --git a/cmk/plugins/collection/agent_based/apc_ats_output.py b/cmk/plugins/collection/agent_based/apc_ats_output.py new file mode 100644 index 00000000000..4fc9a3c4c85 --- /dev/null +++ b/cmk/plugins/collection/agent_based/apc_ats_output.py @@ -0,0 +1,125 @@ +#!/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 +from typing import Any, Dict, Literal, TypedDict + +from cmk.agent_based.v1.render import percent +from cmk.agent_based.v2 import ( + check_levels, + CheckPlugin, + CheckResult, + DiscoveryResult, + LevelsT, + Result, + Service, + SimpleSNMPSection, + SNMPTree, + State, + StringTable, +) +from cmk.plugins.lib.apc import DETECT_ATS + + +class ATS(TypedDict, total=False): + voltage: float + current: float + perc_load: float + power: float + + +Section = Dict[str, ATS] + + +class DefaultParameters(TypedDict): + output_voltage_max: LevelsT[float] + output_voltage_min: LevelsT[float] + load_perc_max: LevelsT[float] + load_perc_min: LevelsT[float] + + +def parse_apc_ats_output(string_table: StringTable) -> Section: + parsed: Section = {} + + # Define a mapping of keys to their respective factors + conversion_factors: Dict[Literal["voltage", "current", "perc_load", "power"], float] = { + "voltage": 1.0, + "current": 0.1, + "perc_load": 1.0, + "power": 1.0, + } + + for index, voltage_str, current_str, perc_load_str, power_str in string_table: + for key, value_str in zip( + conversion_factors.keys(), + [voltage_str, current_str, perc_load_str, power_str], + ): + factor: float = conversion_factors[key] + try: + value: float = float(value_str) * factor + except ValueError: + continue + instance = parsed.setdefault(index, {}) + instance[key] = value + return parsed + + +def discover_apc_ats_output(section: Any) -> DiscoveryResult: + yield from (Service(item=item) for item in section) + + +def check_apc_ats_output(item: str, params: Mapping[str, Any], section: Section) -> CheckResult: + if not (data := section.get(item)): + return + + if (voltage := data.get("voltage")) is not None: + yield from check_levels( + value=voltage, + metric_name="volt", + levels_upper=params.get("output_voltage_max", None), + levels_lower=params.get("output_voltage_min", None), + label="Voltage", + render_func=lambda v: f"{v} V", + ) + if (power := data.get("power")) is not None: + yield Result(state=State.OK, summary="Power: %.2f W" % power) + + if (current := data.get("current")) is not None: + yield Result(state=State.OK, summary="Current: %.2f A" % current) + + if (perc_load := data.get("perc_load")) is not None: + # -1 means that the ATS doesn't support this value + yield from check_levels( + value=perc_load, + metric_name="load_perc", + levels_lower=params.get("load_perc_min", None), + levels_upper=params.get("load_perc_max", None), + label="Load", + render_func=percent, + ) + + +snmp_section_apc_ats_output = SimpleSNMPSection( + name="apc_ats_output", + detect=DETECT_ATS, + fetch=SNMPTree( + base=".1.3.6.1.4.1.318.1.1.8.5.4.3.1", + oids=["1", "3", "4", "10", "13"], + ), + parse_function=parse_apc_ats_output, +) + +check_plugin_apc_ats_output = CheckPlugin( + name="apc_ats_output", + service_name="Phase %s output", + discovery_function=discover_apc_ats_output, + check_function=check_apc_ats_output, + check_ruleset_name="apc_ats_output", + check_default_parameters=DefaultParameters( + output_voltage_max=("fixed", (240, 250)), + output_voltage_min=("no_levels", None), + load_perc_min=("no_levels", None), + load_perc_max=("fixed", (85.0, 95.0)), + ), +) diff --git a/cmk/plugins/collection/agent_based/chrony.py b/cmk/plugins/collection/agent_based/chrony.py index a5d6d2cd952..758a5095617 100644 --- a/cmk/plugins/collection/agent_based/chrony.py +++ b/cmk/plugins/collection/agent_based/chrony.py @@ -50,7 +50,8 @@ def parse_chrony(string_table: StringTable) -> dict[str, Any] | None: if key == "Reference ID": parsed[key] = value try: - parsed["address"] = value.split(" ")[1] + # if brackets are empty, NTP servers are unreachable + parsed["address"] = value.split(" ")[1].replace("()", "") or None except IndexError: pass elif key == "System time": @@ -106,13 +107,10 @@ def check_chrony(params, section_chrony, section_ntp): return address = section_chrony.get("address") - if address in (None, "", "()"): - # if brackets are empty, NTP servers are unreachable - address = "unreachable" ref_id = section_chrony.get("Reference ID") yield Result( - state=State.WARN if address == "unreachable" else State.OK, - notice=f"NTP servers: {address}\nReference ID: {ref_id}", + state=State.OK if address else State.WARN, + notice=f"NTP servers: {address or 'unreachable'}\nReference ID: {ref_id}", ) crit_stratum, warn, crit = params["ntp_levels"] @@ -127,6 +125,11 @@ def check_chrony(params, section_chrony, section_ntp): boundaries=(0, None), ) + # without address ('Reference ID') being specified `last_sync` ('Ref time (UTC)') and + # Stratum are semantically 'n/a' - don't execute checks or return metrics in that case! + if not address: + return + if (stratum := section_chrony.get("Stratum")) is not None: yield from check_levels_v1( stratum, diff --git a/cmk/plugins/collection/agent_based/etherbox.py b/cmk/plugins/collection/agent_based/etherbox.py index de167c8e716..c44b94374cb 100644 --- a/cmk/plugins/collection/agent_based/etherbox.py +++ b/cmk/plugins/collection/agent_based/etherbox.py @@ -23,6 +23,7 @@ from cmk.agent_based.v1 import check_levels as check_levels_v1 from cmk.agent_based.v2 import ( + check_levels, CheckPlugin, CheckResult, DiscoveryResult, @@ -379,7 +380,7 @@ def check_etherbox_voltage(item: str, params: Mapping[str, Any], section: Sectio except SensorException as error: yield Result(state=State.UNKNOWN, summary=str(error)) return - yield from check_levels_v1( + yield from check_levels( data.value, levels_upper=params["levels"], metric_name="voltage", @@ -398,5 +399,5 @@ def discovery_voltage(section: Section) -> DiscoveryResult: discovery_function=discovery_voltage, service_name="Sensor %s", check_ruleset_name="etherbox_voltage", - check_default_parameters={"levels": None}, + check_default_parameters={"levels": ("no_levels", None)}, ) diff --git a/cmk/plugins/collection/agent_based/if64.py b/cmk/plugins/collection/agent_based/if64.py index 54b4add2d82..f1ddf2d3e88 100644 --- a/cmk/plugins/collection/agent_based/if64.py +++ b/cmk/plugins/collection/agent_based/if64.py @@ -3,6 +3,8 @@ # 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 dataclasses +import time from collections.abc import Mapping, Sequence from typing import Any @@ -15,7 +17,7 @@ SNMPTree, StringTable, ) -from cmk.plugins.lib import if64, interfaces +from cmk.plugins.lib import if64, interfaces, uptime If64AdmSection = Sequence[str] @@ -59,10 +61,17 @@ def _add_admin_status_to_ifaces( iface.attributes.admin_status = admin_status +def _uptime_or_server_time(now: float, section_uptime: uptime.Section | None) -> float: + if section_uptime is None: + return now + return section_uptime.uptime_sec or now + + def discover_if64( params: Sequence[Mapping[str, Any]], section_if64: interfaces.Section[interfaces.TInterfaceType] | None, section_if64adm: If64AdmSection | None, + section_uptime: uptime.Section | None, ) -> DiscoveryResult: if section_if64 is None: return @@ -78,14 +87,17 @@ def check_if64( params: Mapping[str, Any], section_if64: interfaces.Section[interfaces.TInterfaceType] | None, section_if64adm: If64AdmSection | None, + section_uptime: uptime.Section | None, ) -> CheckResult: if section_if64 is None: return _add_admin_status_to_ifaces(section_if64, section_if64adm) - yield from if64.generic_check_if64( + timestamp = _uptime_or_server_time(time.time(), section_uptime) + yield from interfaces.check_multiple_interfaces( item, params, section_if64, + timestamps=[timestamp] * len(section_if64), ) @@ -94,6 +106,7 @@ def cluster_check_if64( params: Mapping[str, Any], section_if64: Mapping[str, interfaces.Section[interfaces.TInterfaceType] | None], section_if64adm: Mapping[str, If64AdmSection | None], + section_uptime: Mapping[str, uptime.Section | None], ) -> CheckResult: sections_w_admin_status: dict[str, interfaces.Section[interfaces.TInterfaceType]] = {} for node_name, node_section_if64 in section_if64.items(): @@ -101,16 +114,32 @@ def cluster_check_if64( _add_admin_status_to_ifaces(node_section_if64, section_if64adm[node_name]) sections_w_admin_status[node_name] = node_section_if64 - yield from interfaces.cluster_check( + ifaces = [] + timestamps = [] + now = time.time() + for node, node_ifaces in sections_w_admin_status.items(): + for iface in node_ifaces or (): + ifaces.append( + dataclasses.replace( + iface, + attributes=dataclasses.replace( + iface.attributes, + node=node, + ), + ) + ) + timestamps.append(_uptime_or_server_time(now, section_uptime[node])) + yield from interfaces.check_multiple_interfaces( item, params, - sections_w_admin_status, + ifaces, + timestamps=timestamps, ) check_plugin_if64 = CheckPlugin( name="if64", - sections=["if64", "if64adm"], + sections=["if64", "if64adm", "uptime"], service_name="Interface %s", discovery_ruleset_name="inventory_if_rules", discovery_ruleset_type=RuleSetType.ALL, diff --git a/cmk/plugins/collection/agent_based/if64_basic.py b/cmk/plugins/collection/agent_based/if64_basic.py index 3730e8a107c..686d115a222 100644 --- a/cmk/plugins/collection/agent_based/if64_basic.py +++ b/cmk/plugins/collection/agent_based/if64_basic.py @@ -3,7 +3,6 @@ # 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 time from collections.abc import Mapping from typing import Any @@ -21,7 +20,6 @@ def check_interfaces( params=params, section=section, group_name="Interface group", - timestamp=time.time(), ) diff --git a/cmk/plugins/collection/agent_based/inventory_win_reg_uninstall.py b/cmk/plugins/collection/agent_based/inventory_win_reg_uninstall.py index e00db19f453..701ab1c3be3 100644 --- a/cmk/plugins/collection/agent_based/inventory_win_reg_uninstall.py +++ b/cmk/plugins/collection/agent_based/inventory_win_reg_uninstall.py @@ -3,15 +3,17 @@ # 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 import re import time from collections.abc import Sequence -from typing import NamedTuple +from dataclasses import dataclass from cmk.agent_based.v2 import AgentSection, InventoryPlugin, InventoryResult, StringTable, TableRow -class Package(NamedTuple): +@dataclass(frozen=True) +class Package: name: str version: str vendor: str @@ -20,12 +22,39 @@ class Package(NamedTuple): size: int | None path: str language: str - package_type: str Section = Sequence[Package] +_DATE_PATTERN = re.compile(r"^20\d{6}") + + +def parse_win_reg_uninstall_json(string_table: StringTable) -> Section: + return [ + Package( + name=name, + version=raw["DisplayVersion"], + vendor=raw["Publisher"], + summary=raw["DisplayName"], + install_date=_parse_date(raw["InstallDate"]), + size=_parse_size(raw["EstimatedSize"]), + path=raw["InstallLocation"], + language=raw["Language"], + ) + for (word,) in string_table + if (raw := json.loads(word)) + and (name := _parse_package_name(raw["DisplayName"], raw["PSChildName"])) + ] + + +agent_section_win_reg_uninstall_json = AgentSection( + name="win_reg_uninstall_json", + parsed_section_name="win_reg_uninstall", + parse_function=parse_win_reg_uninstall_json, +) + + def parse_win_reg_uninstall(string_table: StringTable) -> Section: parsed_packages: list[Package] = [] for line in string_table: @@ -37,27 +66,14 @@ def parse_win_reg_uninstall(string_table: StringTable) -> Section: else: continue - install_date = None - if re.match(r"^20\d{6}", date): - # Dates look like '20160930', but we saw also dates like '20132804' - # which have transposed month and day fields. - try: - install_date = int(time.mktime(time.strptime(date, "%Y%m%d"))) - except ValueError: - try: - install_date = int(time.mktime(time.strptime(date, "%Y%d%m"))) - except ValueError: - pass - - if pacname.startswith("{"): - pacname = display_name - - if pacname == "": + install_date = _parse_date(date) + + if (name := _parse_package_name(display_name, pacname)) is None: continue parsed_packages.append( Package( - name=pacname, + name=name, version=version, vendor=publisher, summary=display_name, @@ -65,12 +81,32 @@ def parse_win_reg_uninstall(string_table: StringTable) -> Section: size=_parse_size(estimated_size), path=path, language=language, - package_type="registry", ) ) return parsed_packages +def _parse_package_name(raw_display_name: str, raw_ps_child_name: str) -> str | None: + pacname = raw_display_name if raw_ps_child_name.startswith("{") else raw_ps_child_name + return pacname or None + + +def _parse_date(raw_date: str) -> int | None: + if not _DATE_PATTERN.match(raw_date): + return None + # Dates look like '20160930', but we saw also dates like '20132804' + # which have transposed month and day fields. + try: + return int(time.mktime(time.strptime(raw_date, "%Y%m%d"))) + except ValueError: + pass + + try: + return int(time.mktime(time.strptime(raw_date, "%Y%d%m"))) + except ValueError: + return None + + def _parse_size(size: str) -> int | None: try: return int(size) @@ -99,7 +135,7 @@ def inventory_win_reg_uninstall(section: Section) -> InventoryResult: "size": package.size, "path": package.path, "language": package.language, - "package_type": package.package_type, + "package_type": "registry", }, status_columns={}, ) diff --git a/cmk/plugins/collection/agent_based/inventory_win_wmi_software.py b/cmk/plugins/collection/agent_based/inventory_win_wmi_software.py index e0dc921a06e..c8f647b7d70 100644 --- a/cmk/plugins/collection/agent_based/inventory_win_wmi_software.py +++ b/cmk/plugins/collection/agent_based/inventory_win_wmi_software.py @@ -12,26 +12,54 @@ # VMware vSphere Client 4.1|VMware, Inc.|4.1.0.17435 # Microsoft Office Professional Plus 2010|Microsoft Corporation|14.0.7015.1000 +import json import re import time from collections.abc import Sequence -from typing import NamedTuple +from dataclasses import dataclass from cmk.agent_based.v2 import AgentSection, InventoryPlugin, InventoryResult, StringTable, TableRow +DATE_PATTERN = re.compile("^20......$") -class Package(NamedTuple): + +@dataclass(frozen=True) +class Package: name: str - version: str vendor: str + version: str install_date: int | None language: str - package_type: str Section = Sequence[Package] +def parse_win_wmi_software_json(string_table: StringTable) -> Section: + return [ + Package( + name=str(raw["ProductName"]), + vendor=str(raw["Publisher"]).replace("\x00", ""), # Can happen, reason unclear + version=str(raw["VersionString"]), + install_date=( + int(time.mktime(time.strptime(raw_date, "%Y%m%d"))) + if DATE_PATTERN.match(raw_date := raw["InstallDate"]) + else None + ), + language=str(raw["Language"]), + ) + for (word,) in string_table + if (raw := json.loads(word)) + ] + + +agent_section_win_wmi_software_json = AgentSection( + name="win_wmi_software_json", + parsed_section_name="win_wmi_software", + parse_function=parse_win_wmi_software_json, +) + + def parse_win_wmi_software(string_table: StringTable) -> Section: parsed_packages: list[Package] = [] for line in string_table: @@ -41,9 +69,9 @@ def parse_win_wmi_software(string_table: StringTable) -> Section: pacname, vendor, version = line[:3] dat = line[3] if len(line) > 3 else "" - install_date = None - if len(dat) == 8 and re.match("^20", dat): - install_date = int(time.mktime(time.strptime(dat, "%Y%m%d"))) + install_date = ( + int(time.mktime(time.strptime(dat, "%Y%m%d"))) if DATE_PATTERN.match(dat) else None + ) # contains language as well language = line[4] if len(line) == 5 else "" @@ -55,7 +83,6 @@ def parse_win_wmi_software(string_table: StringTable) -> Section: vendor=vendor.replace("\x00", ""), # Can happen, reason unclear install_date=install_date, language=language, - package_type="wmi", ) ) return parsed_packages @@ -79,7 +106,7 @@ def inventory_win_wmi_software(section: Section) -> InventoryResult: "vendor": package.vendor, "install_date": package.install_date, "language": package.language, - "package_type": package.package_type, + "package_type": "wmi", }, status_columns={}, ) diff --git a/cmk/plugins/collection/agent_based/winperf_if.py b/cmk/plugins/collection/agent_based/winperf_if.py index 0b1e6c6812e..8239309eca2 100644 --- a/cmk/plugins/collection/agent_based/winperf_if.py +++ b/cmk/plugins/collection/agent_based/winperf_if.py @@ -582,16 +582,22 @@ def _check_winperf_if( if not section_winperf_if: return + ifaces = _merge_sections( + section_winperf_if.interfaces, + section_winperf_if_teaming, + section_winperf_if_extended, + ) + timestamps = ( + [section_winperf_if.timestamp] * len(ifaces) + if section_winperf_if.timestamp is not None + else None + ) yield from interfaces.check_multiple_interfaces( item, params, - _merge_sections( - section_winperf_if.interfaces, - section_winperf_if_teaming, - section_winperf_if_extended, - ), + ifaces, group_name="Teaming", - timestamp=section_winperf_if.timestamp, + timestamps=timestamps, value_store=value_store, ) if section_winperf_if_dhcp and ( diff --git a/cmk/plugins/collection/checkman/jolokia_generic b/cmk/plugins/collection/checkman/jolokia_generic index 741d326f7e7..8753e826b1d 100644 --- a/cmk/plugins/collection/checkman/jolokia_generic +++ b/cmk/plugins/collection/checkman/jolokia_generic @@ -19,7 +19,7 @@ description: of services always in UNKNOWN state), and is therefore strongly discouraged. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the instance and the MBean value diff --git a/cmk/plugins/collection/checkman/jolokia_generic_rate b/cmk/plugins/collection/checkman/jolokia_generic_rate index dc6f21d9d0d..ca372ddddbd 100644 --- a/cmk/plugins/collection/checkman/jolokia_generic_rate +++ b/cmk/plugins/collection/checkman/jolokia_generic_rate @@ -19,7 +19,7 @@ description: of services always in UNKNOWN state), and is therefore strongly discouraged. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the instance and the MBean value diff --git a/cmk/plugins/collection/checkman/jolokia_generic_string b/cmk/plugins/collection/checkman/jolokia_generic_string index 409202d35ec..c3257f8e9b9 100644 --- a/cmk/plugins/collection/checkman/jolokia_generic_string +++ b/cmk/plugins/collection/checkman/jolokia_generic_string @@ -19,7 +19,7 @@ description: of services always in UNKNOWN state), and is therefore strongly discouraged. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the instance and the MBean value diff --git a/cmk/plugins/collection/checkman/jolokia_info b/cmk/plugins/collection/checkman/jolokia_info index 1ea9997d287..d8bb779e493 100644 --- a/cmk/plugins/collection/checkman/jolokia_info +++ b/cmk/plugins/collection/checkman/jolokia_info @@ -7,7 +7,7 @@ description: monitor the uptime of a Java application server like Tomcat or JBoss. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_garbagecollectors b/cmk/plugins/collection/checkman/jolokia_jvm_garbagecollectors index f78a6b24c0a..49c84f0f63c 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_garbagecollectors +++ b/cmk/plugins/collection/checkman/jolokia_jvm_garbagecollectors @@ -15,7 +15,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be installed on the monitored server (ore the special agent must be configured). - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance and name of the garbage collection diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_memory b/cmk/plugins/collection/checkman/jolokia_jvm_memory index a840b996dcc..392248081ce 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_memory +++ b/cmk/plugins/collection/checkman/jolokia_jvm_memory @@ -15,7 +15,7 @@ description: The check can alert if the {WARN}/{CRIT} thresholds for a configurable heap, nonheap or total is exceeded. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_memory_pools b/cmk/plugins/collection/checkman/jolokia_jvm_memory_pools index 3c3965933bf..a016e6de544 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_memory_pools +++ b/cmk/plugins/collection/checkman/jolokia_jvm_memory_pools @@ -12,7 +12,7 @@ description: It will then fetch the memory usage from the JMX status info of the remote Java Virtual Machine. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance followed by the statement {{Memory Pool}} diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_runtime b/cmk/plugins/collection/checkman/jolokia_jvm_runtime index 1909ac3f666..da228dcb505 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_runtime +++ b/cmk/plugins/collection/checkman/jolokia_jvm_runtime @@ -11,7 +11,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be installed on the monitored server. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_threading b/cmk/plugins/collection/checkman/jolokia_jvm_threading index 6665a583c4b..b6b4696b8e0 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_threading +++ b/cmk/plugins/collection/checkman/jolokia_jvm_threading @@ -12,7 +12,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be installed on the monitored server. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_jvm_threading_pool b/cmk/plugins/collection/checkman/jolokia_jvm_threading_pool index 439e9ee09d7..756fa7dc591 100644 --- a/cmk/plugins/collection/checkman/jolokia_jvm_threading_pool +++ b/cmk/plugins/collection/checkman/jolokia_jvm_threading_pool @@ -12,7 +12,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be installed on the monitored server. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_app_sess b/cmk/plugins/collection/checkman/jolokia_metrics_app_sess index 1ca7d9d47eb..6e62e13c263 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_app_sess +++ b/cmk/plugins/collection/checkman/jolokia_metrics_app_sess @@ -13,7 +13,7 @@ description: The check can alert if the {WARN}/{CRIT} thresholds for a configurable total is exceeded. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_app_state b/cmk/plugins/collection/checkman/jolokia_metrics_app_state index 39724a9bb96..63322a2b87f 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_app_state +++ b/cmk/plugins/collection/checkman/jolokia_metrics_app_state @@ -12,7 +12,7 @@ description: The check will return {OK} if the application is found running, or {CRIT} if it is stopped. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_bea_queue b/cmk/plugins/collection/checkman/jolokia_metrics_bea_queue index 7b50c2bb431..e62cdaca0c5 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_bea_queue +++ b/cmk/plugins/collection/checkman/jolokia_metrics_bea_queue @@ -14,7 +14,7 @@ description: The check can alert if the {WARN}/{CRIT} thresholds for a configurable total is exceeded. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_bea_requests b/cmk/plugins/collection/checkman/jolokia_metrics_bea_requests index d6b80b0efe6..4461f6258f3 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_bea_requests +++ b/cmk/plugins/collection/checkman/jolokia_metrics_bea_requests @@ -10,7 +10,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be deployed on the monitored server in each application container. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_bea_sess b/cmk/plugins/collection/checkman/jolokia_metrics_bea_sess index ddea56f7220..70778c444cd 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_bea_sess +++ b/cmk/plugins/collection/checkman/jolokia_metrics_bea_sess @@ -13,7 +13,7 @@ description: The check can alert if the {WARN}/{CRIT} thresholds for a configurable total is exceeded. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_bea_threads b/cmk/plugins/collection/checkman/jolokia_metrics_bea_threads index 856b1b8f4d3..150204b603d 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_bea_threads +++ b/cmk/plugins/collection/checkman/jolokia_metrics_bea_threads @@ -12,7 +12,7 @@ description: This check does not have configurable levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_cache_hits b/cmk/plugins/collection/checkman/jolokia_metrics_cache_hits index 950c9e0e034..84349afad6b 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_cache_hits +++ b/cmk/plugins/collection/checkman/jolokia_metrics_cache_hits @@ -9,7 +9,7 @@ description: These metrics are purely informational, there are currently no warn/crit levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent followed diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_in_memory b/cmk/plugins/collection/checkman/jolokia_metrics_in_memory index c296e9cdb53..76b651e37b2 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_in_memory +++ b/cmk/plugins/collection/checkman/jolokia_metrics_in_memory @@ -10,7 +10,7 @@ description: These metrics are purely informational, there are currently no warn/crit levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent followed diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_off_heap b/cmk/plugins/collection/checkman/jolokia_metrics_off_heap index 95489af8c60..829325586af 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_off_heap +++ b/cmk/plugins/collection/checkman/jolokia_metrics_off_heap @@ -10,7 +10,7 @@ description: These metrics are purely informational, there are currently no warn/crit levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent followed diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_on_disk b/cmk/plugins/collection/checkman/jolokia_metrics_on_disk index 61f23881e74..2f2ae59d551 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_on_disk +++ b/cmk/plugins/collection/checkman/jolokia_metrics_on_disk @@ -10,7 +10,7 @@ description: These metrics are purely informational, there are currently no warn/crit levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent followed diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_requests b/cmk/plugins/collection/checkman/jolokia_metrics_requests index 54a4b6e822e..8c14693ee26 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_requests +++ b/cmk/plugins/collection/checkman/jolokia_metrics_requests @@ -10,7 +10,7 @@ description: To use this plugin, Jolokia and the agent plug-in need to be deployed on the monitored server in each application container. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_serv_req b/cmk/plugins/collection/checkman/jolokia_metrics_serv_req index 87e42cb2ff8..9c6c394874c 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_serv_req +++ b/cmk/plugins/collection/checkman/jolokia_metrics_serv_req @@ -12,7 +12,7 @@ description: The check returns {WARN}/{CRIT} if the number of requests is outside the given ranges. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent. diff --git a/cmk/plugins/collection/checkman/jolokia_metrics_writer b/cmk/plugins/collection/checkman/jolokia_metrics_writer index b1f503efd3c..64df4afbf43 100644 --- a/cmk/plugins/collection/checkman/jolokia_metrics_writer +++ b/cmk/plugins/collection/checkman/jolokia_metrics_writer @@ -8,7 +8,7 @@ description: These metrics are purely informational, there are currently no warn/crit levels. - Both, version 1.7 and 2.0 of Jolokia are supported. + Versions 1.7, 2.0 and 2.1 of Jolokia are supported. item: The name of the application server instance as configured by the agent followed diff --git a/cmk/plugins/collection/checkman/raritan_pdu_plugs b/cmk/plugins/collection/checkman/raritan_pdu_plugs index 32b0e49f5d5..cb1930e5740 100644 --- a/cmk/plugins/collection/checkman/raritan_pdu_plugs +++ b/cmk/plugins/collection/checkman/raritan_pdu_plugs @@ -9,8 +9,11 @@ description: It has been tested with the model PX2-2180CR. As default the state of the time from inventory will result in the state {OK}, other states are in the state {CRIT}. - The required state can be configured to {on} or {off}. Then these plugs are in - the state {OK} when they are in the configured state, and {CRIT} otherwise. + The required state can be configured to {on}, {off} or {None} (default). + When the required state is set to None, the service will compare the + current state with the state found during discovery. + Plugs are considered {OK} when their current state matches the required + or discovered state (required state takes precedence), and {CRIT} otherwise. item: The ID of the plug as given by the device diff --git a/cmk/plugins/collection/graphing/translations.py b/cmk/plugins/collection/graphing/translations.py index 84d39e67e8b..c583a74099b 100644 --- a/cmk/plugins/collection/graphing/translations.py +++ b/cmk/plugins/collection/graphing/translations.py @@ -802,6 +802,20 @@ }, ) +translation_ping_exe = translations.Translation( + name="ping_exe", + check_commands=[translations.NagiosPlugin("check_ping.exe")], + translations={ + "~.*rta": translations.ScaleBy(0.001), + }, +) + +translation_tcp_exe = translations.Translation( + name="tcp_exe", + check_commands=[translations.NagiosPlugin("check_tcp.exe")], + translations={"time": translations.RenameTo("response_time")}, +) + translation_icmp_host_ping_host_service_ping = translations.Translation( name="icmp_host-ping_host-service_ping", check_commands=[ diff --git a/cmk/plugins/collection/rulesets/apc_ats_output.py b/cmk/plugins/collection/rulesets/apc_ats_output.py new file mode 100644 index 00000000000..2c1328c40b8 --- /dev/null +++ b/cmk/plugins/collection/rulesets/apc_ats_output.py @@ -0,0 +1,74 @@ +#!/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 ( + DictElement, + Dictionary, + Float, + InputHint, + Integer, + SimpleLevels, +) +from cmk.rulesets.v1.form_specs._levels import LevelDirection +from cmk.rulesets.v1.form_specs._migrations import ( + migrate_to_float_simple_levels, + migrate_to_integer_simple_levels, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostAndItemCondition, Topic + + +def _parameter_valuespec_apc_ats_output(): + return Dictionary( + title=Title("Levels for ATS output parameters"), + elements={ + "output_voltage_max": DictElement( + parameter_form=SimpleLevels( + level_direction=LevelDirection.UPPER, + title=Title("Maximum levels for voltage"), + form_spec_template=Integer(unit_symbol="Volt"), + prefill_fixed_levels=InputHint(value=(0, 0)), + migrate=migrate_to_integer_simple_levels, + ) + ), + "output_voltage_min": DictElement( + parameter_form=SimpleLevels( + level_direction=LevelDirection.LOWER, + title=Title("Minimum levels for voltage"), + form_spec_template=Integer(unit_symbol="Volt"), + prefill_fixed_levels=InputHint(value=(0, 0)), + migrate=migrate_to_integer_simple_levels, + ) + ), + "load_perc_max": DictElement( + parameter_form=SimpleLevels( + level_direction=LevelDirection.UPPER, + title=Title("Maximum levels for load in percent"), + form_spec_template=Float(unit_symbol="%"), + prefill_fixed_levels=InputHint(value=(0, 0)), + migrate=migrate_to_float_simple_levels, + ) + ), + "load_perc_min": DictElement( + parameter_form=SimpleLevels( + level_direction=LevelDirection.LOWER, + title=Title("Minimum levels for load in percent"), + form_spec_template=Float(unit_symbol="%"), + prefill_fixed_levels=InputHint(value=(0, 0)), + migrate=migrate_to_float_simple_levels, + ) + ), + }, + ) + + +rule_spec_ovs_bonding = CheckParameters( + name="apc_ats_output", + title=Title("APC Automatic Transfer Switch Output"), + topic=Topic.ENVIRONMENTAL, + parameter_form=_parameter_valuespec_apc_ats_output, + condition=HostAndItemCondition(item_title=Title("ID of phase")), +) diff --git a/cmk/plugins/collection/rulesets/etherbox.py b/cmk/plugins/collection/rulesets/etherbox.py new file mode 100644 index 00000000000..1ee53e45874 --- /dev/null +++ b/cmk/plugins/collection/rulesets/etherbox.py @@ -0,0 +1,53 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import ( + DictElement, + Dictionary, + Float, + InputHint, + LevelDirection, + migrate_to_float_simple_levels, + SimpleLevels, + String, +) +from cmk.rulesets.v1.rule_specs import CheckParameters, HostAndItemCondition, Topic + + +def _make_form() -> Dictionary: + return Dictionary( + title=Title("Voltage levels"), + elements={ + "levels": DictElement( + required=True, + parameter_form=SimpleLevels( + title=Title("Voltage Levels"), + level_direction=LevelDirection.UPPER, + form_spec_template=Float(unit_symbol="V"), + migrate=migrate_to_float_simple_levels, + prefill_fixed_levels=InputHint((0.0, 0.0)), + ), + ) + }, + ) + + +rule_spec_etherbox_voltage = CheckParameters( + name="etherbox_voltage", + title=Title("Etherbox voltage"), + topic=Topic.SERVER_HARDWARE, + parameter_form=_make_form, + condition=HostAndItemCondition( + item_title=Title("Contact sensor type"), + item_form=String( + help_text=Help( + "The item of etherbox checks is build as 'contact.sensor_type'." + " For example, you want the rule to only apply to a temperature" + " sensor (type 1) on contact 3 then set the item to 3.1 ." + ) + ), + ), +) diff --git a/cmk/plugins/collection/rulesets/httpv2.py b/cmk/plugins/collection/rulesets/httpv2.py index d34b266c9b1..7f83dbe94f6 100644 --- a/cmk/plugins/collection/rulesets/httpv2.py +++ b/cmk/plugins/collection/rulesets/httpv2.py @@ -466,6 +466,7 @@ def _valuespec_connection() -> Dictionary: "valid string for a header value." ), prefill=DefaultValue(_DEFAULT_USER_AGENT), + macro_support=True, ), ), "add_headers": DictElement( @@ -685,6 +686,7 @@ def _valuespec_endpoints() -> List: ), custom_validate=(validators.LengthInRange(min_value=1),), prefill=InputHint("My service name"), + macro_support=True, ), required=True, ), @@ -713,6 +715,7 @@ def _valuespec_endpoints() -> List: [validators.UrlProtocol.HTTP, validators.UrlProtocol.HTTPS], ), ), + # macro_support=True, # deactivated to avoid conflicts with manual help_text ), required=True, ), diff --git a/cmk/plugins/collection/server_side_calls/httpv2.py b/cmk/plugins/collection/server_side_calls/httpv2.py index a059eef790d..b646e12354c 100644 --- a/cmk/plugins/collection/server_side_calls/httpv2.py +++ b/cmk/plugins/collection/server_side_calls/httpv2.py @@ -238,19 +238,18 @@ def generate_http_services( for endpoint in params: protocol = "HTTPS" if endpoint.url.startswith("https://") else "HTTP" prefix = f"{protocol} " if endpoint.service_name.prefix is ServicePrefix.AUTO else "" - endpoint.url = replace_macros(endpoint.url, macros) yield ActiveCheckCommand( service_description=f"{prefix}{replace_macros(endpoint.service_name.name, macros)}", - command_arguments=list(_command_arguments(endpoint)), + command_arguments=list(_command_arguments(endpoint, macros)), ) -def _command_arguments(endpoint: HttpEndpoint) -> Iterator[str | Secret]: +def _command_arguments(endpoint: HttpEndpoint, macros: Mapping[str, str]) -> Iterator[str | Secret]: yield "--url" - yield endpoint.url + yield replace_macros(endpoint.url, macros) if (connection := endpoint.settings.connection) is not None: - yield from _connection_args(connection) + yield from _connection_args(connection, macros) if (response_time := endpoint.settings.response_time) is not None: yield from _response_time_arguments(response_time) if (server_response := endpoint.settings.server_response) is not None: @@ -263,7 +262,7 @@ def _command_arguments(endpoint: HttpEndpoint) -> Iterator[str | Secret]: yield from _content_args(content) -def _connection_args(connection: Connection) -> Iterator[str | Secret]: +def _connection_args(connection: Connection, macros: Mapping[str, str]) -> Iterator[str | Secret]: yield from _method_args(connection.method) if (auth := connection.auth) is not None: yield from _auth_args(auth) @@ -278,7 +277,7 @@ def _connection_args(connection: Connection) -> Iterator[str | Secret]: if (timeout := connection.timeout) is not None: yield from _timeout_args(timeout) if (user_agent := connection.user_agent) is not None: - yield from _user_agent_args(user_agent) + yield from _user_agent_args(replace_macros(user_agent, macros)) if (add_headers := connection.add_headers) is not None: yield from _send_header_args(add_headers) diff --git a/cmk/plugins/gerrit/agent_based/gerrit_version.py b/cmk/plugins/gerrit/agent_based/gerrit_version.py new file mode 100644 index 00000000000..b1a49903cb2 --- /dev/null +++ b/cmk/plugins/gerrit/agent_based/gerrit_version.py @@ -0,0 +1,122 @@ +#!/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 typing import Literal, TypedDict + +import pydantic + +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + CheckResult, + DiscoveryResult, + Result, + Service, + State, + StringTable, +) + + +class LatestVersions(TypedDict): + """Mapping of the latest available Gerrit version by release type.""" + + major: str | None + minor: str | None + patch: str | None + + +class VersionInfo(pydantic.BaseModel): + """Version information related to deployed Gerrit instance.""" + + model_config = pydantic.ConfigDict(frozen=True) + + current: str + """The current version of deployed Gerrit instance.""" + latest: LatestVersions + """The latest available major, minor and patch Gerrit release.""" + + +def parse_gerrit_version(string_table: StringTable) -> VersionInfo | None: + """Parse Gerrit version from agent output.""" + match string_table: + case [[payload]]: + return VersionInfo.model_validate_json(payload) + case _: + return None + + +def discover_gerrit_version(section: VersionInfo | None) -> DiscoveryResult: + """Runs empty discovery since there is only a single service.""" + yield Service() + + +class CheckParams(TypedDict): + """Parameters passed to plugin via ruleset (see defaults).""" + + major: int + minor: int + patch: int + + +ReleaseType = Literal["major", "minor", "patch"] +"""Release types based on semantic versioning.""" + + +def get_changelog_url(release: str, release_type: ReleaseType) -> str: + """Build Gerrit changelog url for a given release.""" + major, minor, patch = release.split(".") + base_url = f"https://www.gerritcodereview.com/{major}.{minor}.html" + + match release_type: + case "major" | "minor": + return base_url + case "patch": + return f"{base_url}#{major}{minor}{patch}" + + +def get_latest_version_notice( + params: CheckParams, latest_versions: LatestVersions, release_type: ReleaseType +) -> Result: + """Build result notice based on whether there's an available version update.""" + if (latest := latest_versions[release_type]) is None: + return Result(state=State.OK, notice=f"No new {release_type} release available.") + + changelog_url = get_changelog_url(latest, release_type) + + return Result( + state=State(params[release_type]), + notice=f"Latest {release_type} release: {latest} {changelog_url} ", + ) + + +def check_gerrit_version(params: CheckParams, section: VersionInfo | None) -> CheckResult: + """Checks the Gerrit version section returning valid checkmk results.""" + if not section: + return + + yield Result(state=State.OK, summary=f"Current: {section.current}") + + yield get_latest_version_notice(params, section.latest, "major") + yield get_latest_version_notice(params, section.latest, "minor") + yield get_latest_version_notice(params, section.latest, "patch") + + +agent_section_gerrit_version = AgentSection( + name="gerrit_version", + parse_function=parse_gerrit_version, +) + +check_plugin_gerrit_version = CheckPlugin( + name="gerrit_version", + service_name="Gerrit Version", + discovery_function=discover_gerrit_version, + check_function=check_gerrit_version, + check_ruleset_name="gerrit_version", + check_default_parameters=CheckParams( + major=State.WARN.value, + minor=State.WARN.value, + patch=State.WARN.value, + ), +) diff --git a/cmk/plugins/gerrit/checkman/gerrit_version b/cmk/plugins/gerrit/checkman/gerrit_version new file mode 100644 index 00000000000..4eac0657d81 --- /dev/null +++ b/cmk/plugins/gerrit/checkman/gerrit_version @@ -0,0 +1,16 @@ +title: Gerrit: Version +agents: gerrit +catalog: app/gerrit +license: GPLv2 +distribution: check_mk +description: + This check compares a currently deployed Gerrit instance with newer available releases. + + Since Gerrit uses a release cycle similar to semantic versioning, this check can monitor when + a major, minor, or patch release is available. With the service configuration, a user can specify + the specific type of release(s) they would like to be notified about. + + Requires the integration "Gerrit" to be configured. + +discovery: + One service is created ({"Gerrit Version"}). diff --git a/cmk/plugins/gerrit/lib/agent.py b/cmk/plugins/gerrit/lib/agent.py new file mode 100644 index 00000000000..106e51a666b --- /dev/null +++ b/cmk/plugins/gerrit/lib/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. + +import argparse +import dataclasses +import json +import pathlib +import sys +from collections.abc import Collection, Sequence +from typing import Any, NewType, Protocol, Self, TypeAlias + +import requests + +from cmk.utils import password_store +from cmk.utils.semantic_version import SemanticVersion + +from cmk.special_agents.v0_unstable.agent_common import SectionWriter, special_agent_main +from cmk.special_agents.v0_unstable.argument_parsing import Args, create_default_argument_parser + + +def main() -> int: + """Entrypoint for Gerrit special agent.""" + return special_agent_main(parse_arguments, run_agent) + + +def parse_arguments(argv: Sequence[str] | None) -> argparse.Namespace: + """Parse commandline arguments passed to special agent.""" + parser = create_default_argument_parser(description=__doc__) + + parser.add_argument("-u", "--user", default="", help="Username for Gerrit login") + group_password = parser.add_mutually_exclusive_group(required=True) + group_password.add_argument( + "--password-ref", + help="Password store reference to the secret password for your Gerrit account.", + ) + group_password.add_argument("-s", "--password", help="Password for Gerrit login") + parser.add_argument( + "-P", + "--proto", + choices=("https", "http"), + default="https", + help="Protocol (default: 'https')", + ) + parser.add_argument("-p", "--port", default=443, type=int, help="Port (default: 443)") + parser.add_argument("hostname", metavar="HOSTNAME", help="Hostname of Gerrit instance.") + + return parser.parse_args(argv) + + +def run_agent(args: Args) -> int: + """Run Gerrit special agent.""" + api_url = f"{args.proto}://{args.hostname}:{args.port}/a" + auth = (args.user, get_password_from_args(args)) + + collector = SyncSectionCollector(api_url=api_url, auth=auth) + sections = collect_sections(collector) + write_sections(sections) + + return 0 + + +def get_password_from_args(args: Args) -> str: + """Extract password from store if explicit password not passed as argument.""" + if args.password: + return args.password + + pw_id, pw_file = args.password_ref.split(":", maxsplit=1) + + return password_store.lookup(pathlib.Path(pw_file), pw_id) + + +SectionName = NewType("SectionName", str) +"""The name that will be provided to agent output section heading.""" +SectionData: TypeAlias = dict[str, Any] +"""The (JSON) data that the will be written out to agent output section.""" +Sections: TypeAlias = dict[SectionName, SectionData] +"""A mapping of all section names and respective data.""" + + +class SectionCollector(Protocol): + """An interface for collecting agent sections.""" + + def collect(self) -> Sections: + """Collect Gerrit related data grouped by section.""" + + +def collect_sections(collector: SectionCollector) -> Sections: + """Send off requests and collect the results.""" + return collector.collect() + + +def write_sections(sections: Sections) -> None: + """Write out sections to the special agent output.""" + for name, data in sections.items(): + with SectionWriter(f"gerrit_{name}") as writer: + writer.append_json(data) + + +@dataclasses.dataclass +class LatestVersions: + """Latest release major, minor, and patch version, if available.""" + + major: str | None + minor: str | None + patch: str | None + + @classmethod + def build(cls, current: SemanticVersion, versions: Collection[SemanticVersion]) -> Self: + """Search for potential updates based on the current and provided versions.""" + return cls( + major=str(max((v for v in versions if v.major > current.major), default="")) or None, + minor=str(max((v for v in versions if v.minor > current.minor), default="")) or None, + patch=str(max((v for v in versions if v.patch > current.patch), default="")) or None, + ) + + +class SyncSectionCollector: + """Client for collecting sections synchronously.""" + + def __init__(self, api_url: str, auth: tuple[str, str]) -> None: + self.api_url = api_url + self.auth = auth + + def collect(self) -> Sections: + current_version = self._get_current_section() + latest_versions = self._get_latest_versions(current_version) + + return { + SectionName("version"): { + "current": str(current_version), + "latest": dataclasses.asdict(latest_versions), + }, + } + + def _get_current_section(self) -> SemanticVersion: + uri = "/config/server/version?verbose" + + resp = requests.get(self.api_url + uri, auth=self.auth, timeout=30) + resp.raise_for_status() + + clean_content = resp.content.lstrip(b")]}'") # prefixed with )]}' for security + data = json.loads(clean_content) + + return SemanticVersion.from_string(data["gerrit_version"]) + + @staticmethod + def _get_latest_versions(current: SemanticVersion) -> LatestVersions: + gerrit_releases_url = "https://www.googleapis.com/storage/v1/b/gerrit-releases/o" + query = "?projection=noAcl&fields=items(name)&matchGlob=gerrit-[0-9]*.[0-9]*.[0-9]*.war" + + resp = requests.get(gerrit_releases_url + query, timeout=30) + resp.raise_for_status() + + versions = {SemanticVersion.from_string(item["name"]) for item in resp.json()["items"]} + + return LatestVersions.build(current, versions) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/cmk/plugins/gerrit/libexec/agent_gerrit b/cmk/plugins/gerrit/libexec/agent_gerrit new file mode 100755 index 00000000000..6ff4bb2febc --- /dev/null +++ b/cmk/plugins/gerrit/libexec/agent_gerrit @@ -0,0 +1,11 @@ +#!/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. + +import sys + +from cmk.plugins.gerrit.lib import agent + +if __name__ == "__main__": + sys.exit(agent.main()) diff --git a/cmk/plugins/gerrit/rulesets/special_agent.py b/cmk/plugins/gerrit/rulesets/special_agent.py new file mode 100644 index 00000000000..9379fdf9c40 --- /dev/null +++ b/cmk/plugins/gerrit/rulesets/special_agent.py @@ -0,0 +1,79 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + Integer, + Password, + SingleChoice, + SingleChoiceElement, + String, +) +from cmk.rulesets.v1.form_specs.validators import LengthInRange, NetworkPort +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + +rule_spec_gerrit = SpecialAgent( + name="gerrit", + title=Title("Gerrit"), + topic=Topic.APPLICATIONS, + parameter_form=lambda: Dictionary( + title=Title("Gerrit connection"), + help_text=Help("Requests data from a Gerrit instance."), + elements={ + "instance": DictElement( + parameter_form=String( + title=Title("Gerrit instance to query."), + help_text=Help( + "Use this option to set which instance should be checked by the special " + "agent. Please add the host name here, e.g. my_gerrit.com." + ), + custom_validate=[LengthInRange(min_value=1)], + macro_support=True, + ), + required=True, + ), + "protocol": DictElement( + parameter_form=SingleChoice( + title=Title("Protocol"), + help_text=Help("Defaults to 'https' when not provided."), + elements=[ + SingleChoiceElement(name="http", title=Title("HTTP")), + SingleChoiceElement(name="https", title=Title("HTTPS")), + ], + prefill=DefaultValue("https"), + ), + ), + "port": DictElement( + parameter_form=Integer( + title=Title("Port"), + help_text=Help("Use this option to query a non-standard port."), + prefill=DefaultValue(443), + custom_validate=[NetworkPort()], + ) + ), + "user": DictElement( + parameter_form=String( + title=Title("Username"), + help_text=Help( + "The username that should be used for accessing the Gerrit API. " + "Must have (at least) read permissions." + ), + custom_validate=[LengthInRange(min_value=1)], + ), + required=True, + ), + "password": DictElement( + parameter_form=Password( + title=Title("Password of the user"), + custom_validate=[LengthInRange(min_value=1)], + ), + required=True, + ), + }, + ), +) diff --git a/cmk/plugins/gerrit/rulesets/version.py b/cmk/plugins/gerrit/rulesets/version.py new file mode 100644 index 00000000000..ae651421af4 --- /dev/null +++ b/cmk/plugins/gerrit/rulesets/version.py @@ -0,0 +1,41 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import DefaultValue, DictElement, Dictionary, ServiceState +from cmk.rulesets.v1.rule_specs import CheckParameters, HostCondition, Topic + +rule_spec_check_parameters = CheckParameters( + title=Title("Gerrit Version"), + topic=Topic.APPLICATIONS, + parameter_form=lambda: Dictionary( + elements={ + "major": DictElement( + parameter_form=ServiceState( + title=Title("Alert when a major version release is available"), + help_text=Help("Version will only appear in summary if non-OK state set."), + prefill=DefaultValue(ServiceState.WARN), + ) + ), + "minor": DictElement( + parameter_form=ServiceState( + title=Title("Alert when a minor version release is available"), + help_text=Help("Version will only appear in summary if non-OK state set."), + prefill=DefaultValue(ServiceState.WARN), + ) + ), + "patch": DictElement( + parameter_form=ServiceState( + title=Title("Alert when a patch version release is available"), + help_text=Help("Version will only appear in summary if non-OK state set."), + prefill=DefaultValue(ServiceState.WARN), + ) + ), + }, + ), + name="gerrit_version", + condition=HostCondition(), +) diff --git a/cmk/plugins/gerrit/server_side_calls/__init__.py b/cmk/plugins/gerrit/server_side_calls/__init__.py new file mode 100644 index 00000000000..c42b91132bf --- /dev/null +++ b/cmk/plugins/gerrit/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/cmk/plugins/gerrit/server_side_calls/gerrit.py b/cmk/plugins/gerrit/server_side_calls/gerrit.py new file mode 100644 index 00000000000..1cc7a740694 --- /dev/null +++ b/cmk/plugins/gerrit/server_side_calls/gerrit.py @@ -0,0 +1,50 @@ +#!/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 Iterator +from typing import Literal + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import ( + HostConfig, + replace_macros, + Secret, + SpecialAgentCommand, + SpecialAgentConfig, +) + + +class GerritParams(BaseModel): + """The expected parameters to receive from the special agent ruleset.""" + + instance: str + user: str + password: Secret + protocol: Literal["http", "https"] | None = None + port: int | None = None + + +def agent_gerrit_config( + params: GerritParams, host_config: HostConfig +) -> Iterator[SpecialAgentCommand]: + args: list[str | Secret] = ["--user", params.user, "--password-ref", params.password] + + if params.protocol: + args.extend(["--proto", params.protocol]) + + if params.port: + args.extend(["--port", str(params.port)]) + + args.append(replace_macros(params.instance, host_config.macros)) + + yield SpecialAgentCommand(command_arguments=args) + + +special_agent_gerrit = SpecialAgentConfig( + name="gerrit", + parameter_parser=GerritParams.model_validate, + commands_function=agent_gerrit_config, +) diff --git a/cmk/plugins/hivemanager/rulesets/special_agent.py b/cmk/plugins/hivemanager/rulesets/special_agent.py new file mode 100644 index 00000000000..c590c86963e --- /dev/null +++ b/cmk/plugins/hivemanager/rulesets/special_agent.py @@ -0,0 +1,55 @@ +#!/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 Help, Title +from cmk.rulesets.v1.form_specs import ( + DictElement, + Dictionary, + migrate_to_password, + Password, + String, +) +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + migrate=_migrate, + help_text=Help("Activate monitoring of host via a HTTP connect to the HiveManager"), + elements={ + "username": DictElement( + required=True, + parameter_form=String( + title=Title("Username"), + ), + ), + "password": DictElement( + required=True, + parameter_form=Password( + title=Title("Password"), + migrate=migrate_to_password, + ), + ), + }, + ) + + +rule_spec_special_agent_hivemanager = SpecialAgent( + name="hivemanager", + title=Title("Aerohive HiveManager"), + topic=Topic.SERVER_HARDWARE, + parameter_form=_parameter_form, +) + + +def _migrate(value: object) -> dict[str, object]: + if isinstance(value, dict): + return value + if isinstance(value, tuple): + return { + "username": value[0], + "password": value[1], + } + raise TypeError(value) diff --git a/cmk/plugins/hivemanager/server_side_calls/special_agent.py b/cmk/plugins/hivemanager/server_side_calls/special_agent.py new file mode 100644 index 00000000000..7b971f804fc --- /dev/null +++ b/cmk/plugins/hivemanager/server_side_calls/special_agent.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 collections.abc import Iterable + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, Secret, SpecialAgentCommand, SpecialAgentConfig + + +class _Params(BaseModel, frozen=True): + username: str + password: Secret + + +def _commands_function( + params: _Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + yield SpecialAgentCommand( + command_arguments=[ + host_config.primary_ip_config.address, + params.username, + params.password.unsafe(), + "--cert-server-name", + host_config.name, + ] + ) + + +special_agent_hivemanager = SpecialAgentConfig( + name="hivemanager", + parameter_parser=_Params.model_validate, + commands_function=_commands_function, +) diff --git a/cmk/plugins/hivemanager_ng/rulesets/special_agent.py b/cmk/plugins/hivemanager_ng/rulesets/special_agent.py new file mode 100644 index 00000000000..33ee1d856ec --- /dev/null +++ b/cmk/plugins/hivemanager_ng/rulesets/special_agent.py @@ -0,0 +1,89 @@ +#!/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 Help, Title +from cmk.rulesets.v1.form_specs import ( + DictElement, + Dictionary, + FieldSize, + migrate_to_password, + Password, + String, + validators, +) +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + help_text=Help("Activate monitoring of the HiveManagerNG cloud."), + elements={ + "url": DictElement( + required=True, + parameter_form=String( + title=Title("URL to HiveManagerNG, e.g. https://cloud.aerohive.com"), + custom_validate=( + validators.Url( + protocols=[ + validators.UrlProtocol.HTTP, + validators.UrlProtocol.HTTPS, + ] + ), + ), + ), + ), + "vhm_id": DictElement( + required=True, + parameter_form=String( + title=Title("Numerical ID of the VHM, e.g. 102"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "api_token": DictElement( + required=True, + parameter_form=String( + title=Title("API access token"), + field_size=FieldSize.LARGE, + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "client_id": DictElement( + required=True, + parameter_form=String( + title=Title("Client ID"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "client_secret": DictElement( + required=True, + parameter_form=Password( + title=Title("Client secret"), + migrate=migrate_to_password, + ), + ), + "redirect_url": DictElement( + required=True, + parameter_form=String( + title=Title("Redirect URL (has to be https)"), + custom_validate=( + validators.Url( + protocols=[ + validators.UrlProtocol.HTTP, + validators.UrlProtocol.HTTPS, + ] + ), + ), + ), + ), + }, + ) + + +rule_spec_special_agent_hivemanager_ng = SpecialAgent( + name="hivemanager_ng", + title=Title("Aerohive HiveManager NG"), + topic=Topic.SERVER_HARDWARE, + parameter_form=_parameter_form, +) diff --git a/cmk/plugins/hivemanager_ng/server_side_calls/special_agent.py b/cmk/plugins/hivemanager_ng/server_side_calls/special_agent.py new file mode 100644 index 00000000000..87b0563a63a --- /dev/null +++ b/cmk/plugins/hivemanager_ng/server_side_calls/special_agent.py @@ -0,0 +1,42 @@ +#!/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 Iterable + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, Secret, SpecialAgentCommand, SpecialAgentConfig + + +class _Params(BaseModel, frozen=True): + url: str + vhm_id: str + api_token: str + client_id: str + client_secret: Secret + redirect_url: str + + +def _commands_function( + params: _Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + yield SpecialAgentCommand( + command_arguments=[ + params.url, + params.vhm_id, + params.api_token, + params.client_id, + params.client_secret.unsafe(), + params.redirect_url, + ] + ) + + +special_agent_hivemanager_ng = SpecialAgentConfig( + name="hivemanager_ng", + parameter_parser=_Params.model_validate, + commands_function=_commands_function, +) diff --git a/cmk/plugins/hp_msa/rulesets/special_agent.py b/cmk/plugins/hp_msa/rulesets/special_agent.py new file mode 100644 index 00000000000..00ce518dc6d --- /dev/null +++ b/cmk/plugins/hp_msa/rulesets/special_agent.py @@ -0,0 +1,48 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import ( + DictElement, + Dictionary, + migrate_to_password, + Password, + String, + validators, +) +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + help_text=Help( + "This rule selects the Agent HP MSA instead of the normal Checkmk Agent " + "which collects the data through the HP MSA web interface" + ), + elements={ + "username": DictElement( + required=True, + parameter_form=String( + title=Title("Username"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "password": DictElement( + required=True, + parameter_form=Password( + title=Title("Password"), + migrate=migrate_to_password, + ), + ), + }, + ) + + +rule_spec_special_agent_hp_msa = SpecialAgent( + name="hp_msa", + title=Title("HP MSA via Web Interface"), + topic=Topic.STORAGE, + parameter_form=_parameter_form, +) diff --git a/cmk/plugins/hp_msa/server_side_calls/special_agent.py b/cmk/plugins/hp_msa/server_side_calls/special_agent.py new file mode 100644 index 00000000000..49ec566b952 --- /dev/null +++ b/cmk/plugins/hp_msa/server_side_calls/special_agent.py @@ -0,0 +1,37 @@ +#!/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 + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, Secret, SpecialAgentCommand, SpecialAgentConfig + + +class _Params(BaseModel, frozen=True): + username: str + password: Secret + + +def _commands_function( + params: _Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + yield SpecialAgentCommand( + command_arguments=[ + "-u", + params.username, + "-p", + params.password.unsafe(), + host_config.primary_ip_config.address, + ] + ) + + +special_agent_hp_msa = SpecialAgentConfig( + name="hp_msa", + parameter_parser=_Params.model_validate, + commands_function=_commands_function, +) 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/plugins/innovaphone/rulesets/special_agent.py b/cmk/plugins/innovaphone/rulesets/special_agent.py new file mode 100644 index 00000000000..0c707200f8b --- /dev/null +++ b/cmk/plugins/innovaphone/rulesets/special_agent.py @@ -0,0 +1,85 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import ( + BooleanChoice, + DefaultValue, + DictElement, + Dictionary, + migrate_to_password, + Password, + SingleChoice, + SingleChoiceElement, + String, + validators, +) +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + migrate=_migrate, + help_text=Help("Please specify the user and password needed to access the xml interface"), + elements={ + "protocol": DictElement( + parameter_form=SingleChoice( + title=Title("Protocol"), + elements=[ + SingleChoiceElement("http", Title("HTTP")), + SingleChoiceElement("https", Title("HTTPS")), + ], + ), + ), + "cert_verification": DictElement( + required=True, + parameter_form=BooleanChoice( + title=Title("TLS certificate verification"), + help_text=Help("Verify TLS certificate (not verifying is insecure)"), + prefill=DefaultValue(True), + ), + ), + "auth_basic": DictElement( + required=True, + parameter_form=Dictionary( + title=Title("Basic authentication"), + elements={ + "username": DictElement( + required=True, + parameter_form=String( + title=Title("Login username"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "password": DictElement( + required=True, + parameter_form=Password( + title=Title("Password"), + migrate=migrate_to_password, + ), + ), + }, + ), + ), + }, + ) + + +rule_spec_special_agent_innovaphone = SpecialAgent( + name="innovaphone", + title=Title("Innovaphone Gateways"), + topic=Topic.SERVER_HARDWARE, + parameter_form=_parameter_form, +) + + +def _migrate(value: object) -> dict[str, object]: + if not isinstance(value, dict): + raise TypeError(value) + if "cert_verification" in value: + return value + return {k: v for k, v in value.items() if k != "no-cert-check"} | { + "cert_verification": not value.get("no-cert-check", False) + } diff --git a/cmk/plugins/innovaphone/server_side_calls/special_agent.py b/cmk/plugins/innovaphone/server_side_calls/special_agent.py new file mode 100644 index 00000000000..925d5d2c392 --- /dev/null +++ b/cmk/plugins/innovaphone/server_side_calls/special_agent.py @@ -0,0 +1,44 @@ +#!/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 + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, Secret, SpecialAgentCommand, SpecialAgentConfig + + +class _AuthBasic(BaseModel, frozen=True): + username: str + password: Secret + + +class _Params(BaseModel, frozen=True): + protocol: str | None = None + cert_verification: bool + auth_basic: _AuthBasic + + +def _commands_function( + params: _Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + args: list[str | Secret] = [ + host_config.name, + params.auth_basic.username, + params.auth_basic.password.unsafe(), + ] + if params.protocol: + args.extend(["--protocol", params.protocol]) + if not params.cert_verification: + args.append("--no-cert-check") + yield SpecialAgentCommand(command_arguments=args) + + +special_agent_innovaphone = SpecialAgentConfig( + name="innovaphone", + parameter_parser=_Params.model_validate, + commands_function=_commands_function, +) diff --git a/cmk/plugins/jolokia/rulesets/special_agent.py b/cmk/plugins/jolokia/rulesets/special_agent.py new file mode 100644 index 00000000000..2656e1f6867 --- /dev/null +++ b/cmk/plugins/jolokia/rulesets/special_agent.py @@ -0,0 +1,124 @@ +#!/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 + +from cmk.rulesets.v1 import Help, Title +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + DictElement, + Dictionary, + Integer, + migrate_to_password, + Password, + SingleChoice, + SingleChoiceElement, + String, + validators, +) +from cmk.rulesets.v1.form_specs._basic import FieldSize +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def parameter_form() -> Dictionary: + return Dictionary( + title=Title("Jolokia"), + help_text=Help("This rule allows querying the Jolokia web API."), + elements={ + "port": DictElement( + required=False, + parameter_form=Integer( + title=Title("TCP port for connection"), + prefill=DefaultValue(8080), + custom_validate=(validators.NetworkPort(),), + ), + ), + "login": DictElement( + required=False, + parameter_form=Dictionary( + title=Title("Optional login (if required)"), + elements={ + "user": DictElement( + required=True, + parameter_form=String( + title=Title("User ID for web login (if login required)"), + prefill=DefaultValue("monitoring"), + ), + ), + "password": DictElement( + required=True, + parameter_form=Password( + title=Title("Password for this user"), + migrate=migrate_to_password, + ), + ), + "mode": DictElement( + required=True, + parameter_form=SingleChoice( + title=Title("Login mode"), + elements=[ + SingleChoiceElement( + name="basic", title=Title("HTTP Basic Authentication") + ), + SingleChoiceElement(name="digest", title=Title("HTTP Digest")), + ], + ), + ), + }, + migrate=_migrate_tuple_to_dict, + ), + ), + "suburi": DictElement( + required=False, + parameter_form=String( + title=Title("relative URI under which Jolokia is visible"), + prefill=DefaultValue("jolokia"), + field_size=FieldSize.MEDIUM, + ), + ), + "instance": DictElement( + required=False, + parameter_form=String( + title=Title("Name of the instance in the monitoring"), + help_text=Help( + "If you do not specify a name here, " + "then the TCP port number will be used as an instance name." + ), + ), + ), + "protocol": DictElement( + required=False, + parameter_form=SingleChoice( + title=Title("Protocol"), + elements=[ + SingleChoiceElement(name="http", title=Title("HTTP")), + SingleChoiceElement(name="https", title=Title("HTTPS")), + ], + ), + ), + }, + ) + + +def _migrate_tuple_to_dict(param: object) -> Mapping[str, object]: + match param: + case (user_id, password, login_mode): + return { + "user": user_id, + "password": password, + "mode": login_mode, + } + case dict() as already_migrated: + return already_migrated + raise ValueError(param) + + +rule_spec_special_agent_jolokia = SpecialAgent( + name="jolokia", + title=Title("Jolokia"), + topic=Topic.APPLICATIONS, + parameter_form=parameter_form, +) diff --git a/cmk/plugins/jolokia/server_side_calls/special_agent.py b/cmk/plugins/jolokia/server_side_calls/special_agent.py new file mode 100644 index 00000000000..eeb396ab140 --- /dev/null +++ b/cmk/plugins/jolokia/server_side_calls/special_agent.py @@ -0,0 +1,57 @@ +#!/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. + + +# mypy: disable-error-code="list-item" + +from collections.abc import Iterable, Mapping + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand, SpecialAgentConfig +from cmk.server_side_calls.v1._utils import Secret + + +class Params(BaseModel): + port: int | None = None + suburi: str | None = None + instance: str | None = None + protocol: str | None = None + login: Mapping[str, str | Secret] | None = None + + +def commands_function(params: Params, host_config: HostConfig) -> Iterable[SpecialAgentCommand]: + command_arguments = ["--server", host_config.primary_ip_config.address] + + command_arguments += ["--%s" % "port", "%s" % params.port] if params.port else [] + command_arguments += ["--%s" % "suburi", "%s" % params.suburi] if params.suburi else [] + command_arguments += ["--%s" % "instance", "%s" % params.instance] if params.instance else [] + command_arguments += ["--%s" % "protocol", "%s" % params.protocol] if params.protocol else [] + + if not params.login: + yield SpecialAgentCommand(command_arguments=command_arguments) + return + + user = params.login["user"] + password = params.login["password"] + assert isinstance(password, Secret) + mode = params.login["mode"] + + command_arguments += [ + "--user", + user, + f"--password {password.unsafe()}", + "--mode", + mode, + ] + + yield SpecialAgentCommand(command_arguments=command_arguments) + + +special_agent_jolokia = SpecialAgentConfig( + name="jolokia", + parameter_parser=Params.model_validate, + commands_function=commands_function, +) diff --git a/cmk/plugins/lib/fortinet.py b/cmk/plugins/lib/fortinet.py index 08a6da18108..49f18165f2e 100644 --- a/cmk/plugins/lib/fortinet.py +++ b/cmk/plugins/lib/fortinet.py @@ -5,7 +5,7 @@ from cmk.agent_based.v2 import any_of, equals, startswith -DETECT_FORTISANDBOX = equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.118.1.30006") +DETECT_FORTISANDBOX = startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.118.1.") DETECT_FORTIAUTHENTICATOR = any_of( equals(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"), startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.12356.113."), diff --git a/cmk/plugins/lib/interfaces.py b/cmk/plugins/lib/interfaces.py index 3ccd3ee1a15..be9519b8728 100644 --- a/cmk/plugins/lib/interfaces.py +++ b/cmk/plugins/lib/interfaces.py @@ -43,9 +43,11 @@ ServiceLabels = dict[str, str] +_ItemAppearance = Literal["index", "descr", "alias"] + class SingleInterfaceDiscoveryParams(TypedDict, total=False): - item_appearance: str + item_appearance: _ItemAppearance pad_portnumbers: bool labels: ServiceLabels @@ -95,6 +97,13 @@ class DiscoveryDefaultParams(TypedDict, total=False): } +def _to_item_appearance(value: str) -> _ItemAppearance: + match value: + case "index" | "descr" | "alias": + return value + raise ValueError(f"Invalid item appearance: {value}") + + class IndependentMapping(pydantic.BaseModel, frozen=True): map_operstates: Sequence[tuple[Sequence[str], Literal[0, 1, 2, 3]]] = [] map_admin_states: Sequence[tuple[Sequence[str], Literal[0, 1, 2, 3]]] = [] @@ -739,21 +748,23 @@ def render_mac_address(phys_address: Iterable[int] | str) -> str: def matching_interfaces_for_item( item: str, section: Section[TInterfaceType], + appearance: _ItemAppearance | None = None, ) -> Iterator[TInterfaceType]: if not section: return if section[0].attributes.node: - yield from _matching_clustered_interfaces_for_item(item, section) + yield from _matching_clustered_interfaces_for_item(item, section, appearance) return - if match := _matching_unclustered_interface_for_item(item, section): + if match := _matching_unclustered_interface_for_item(item, section, appearance): yield match def _matching_clustered_interfaces_for_item( item: str, section: Section[TInterfaceType], + appearance: _ItemAppearance | None, ) -> Iterator[TInterfaceType]: for _node, node_interfaces in itertools.groupby( # itertools.groupby needs the input to be sorted accordingly. This is most likely already @@ -765,32 +776,45 @@ def _matching_clustered_interfaces_for_item( ), key=lambda iface: iface.attributes.node, ): - if match := _matching_unclustered_interface_for_item(item, list(node_interfaces)): + if match := _matching_unclustered_interface_for_item( + item, list(node_interfaces), appearance + ): yield match def _matching_unclustered_interface_for_item( item: str, section: Section[TInterfaceType], + appearance: _ItemAppearance | None, ) -> TInterfaceType | None: return ( simple_match - if (simple_match := _matching_interface_for_simple_item(item, section)) - else _matching_interface_for_compound_item(item, section) + if (simple_match := _matching_interface_for_simple_item(item, section, appearance)) + else _matching_interface_for_compound_item(item, section, appearance) ) def _matching_interface_for_simple_item( item: str, ifaces: Iterable[TInterfaceType], + appearance: _ItemAppearance | None, ) -> TInterfaceType | None: + # Use old matching logic if service has not been rediscovered + # and appearance is missing from discovered params + use_old_matching = appearance is None return next( ( interface for interface in ifaces - if item.lstrip("0") == interface.attributes.index - or (item == "0" * len(item) and saveint(interface.attributes.index) == 0) - or item in (interface.attributes.alias, interface.attributes.descr) + if ( + (appearance == "index" or use_old_matching) + and ( + (item.lstrip("0") == interface.attributes.index) + or (item == "0" * len(item) and saveint(interface.attributes.index) == 0) + ) + ) + or ((appearance == "alias" or use_old_matching) and item == interface.attributes.alias) + or ((appearance == "descr" or use_old_matching) and item == interface.attributes.descr) ), None, ) @@ -799,15 +823,22 @@ def _matching_interface_for_simple_item( def _matching_interface_for_compound_item( item: str, ifaces: Iterable[TInterfaceType], + appearance: _ItemAppearance | None, ) -> TInterfaceType | None: + # Use old matching logic if service has not been rediscovered + # and appearance is missing from discovered params + use_old_matching = appearance is None return next( ( interface for interface in ifaces - if item - in ( - f"{interface.attributes.alias} {interface.attributes.index}", - f"{interface.attributes.descr} {interface.attributes.index}", + if ( + (appearance == "alias" or use_old_matching) + and item == f"{interface.attributes.alias} {interface.attributes.index}" + ) + or ( + (appearance == "descr" or use_old_matching) + and item == f"{interface.attributes.descr} {interface.attributes.index}" ) ), None, @@ -966,28 +997,36 @@ def none_levels() -> dict[str, dict[str, Any | None]]: return levels_per_type["abs"], levels_per_type["perc"] -def _uses_description_and_alias(item_appearance: str) -> tuple[bool, bool]: - if item_appearance == "descr": - return True, False - if item_appearance == "alias": - return False, True - return False, False +@dataclass(frozen=True) +class ItemInfo: + used_appearance: _ItemAppearance + item: str def _compute_item( - item_appearance: str, + configured_item_appearance: _ItemAppearance, attributes: Attributes, section: Section[TInterfaceType], pad_portnumbers: bool, -) -> str: - uses_description, uses_alias = _uses_description_and_alias(item_appearance) - if uses_description and attributes.descr: - item = attributes.descr - elif uses_alias and attributes.alias: - item = attributes.alias - else: - item = _pad_with_zeroes(section, attributes.index, pad_portnumbers) - return item +) -> ItemInfo: + match configured_item_appearance: + case "descr": + if attributes.descr: + return ItemInfo( + used_appearance="descr", + item=attributes.descr, + ) + case "alias": + if attributes.alias: + return ItemInfo( + used_appearance="alias", + item=attributes.alias, + ) + + return ItemInfo( + used_appearance="index", + item=_pad_with_zeroes(section, attributes.index, pad_portnumbers), + ) def check_regex_match_conditions( @@ -1031,7 +1070,7 @@ def _check_single_matching_conditions( class GroupConfiguration(TypedDict, total=False): - member_appearance: str + member_appearance: _ItemAppearance inclusion_condition: MatchingConditions exclusion_conditions: Iterable[MatchingConditions] labels: ServiceLabels @@ -1131,34 +1170,35 @@ def discover_interfaces( # pylint: disable=too-many-branches DISCOVERY_DEFAULT_PARAMETERS["discovery_single"][1]["pad_portnumbers"], ) - for item_appearance in ( + for appearance in ( ["index", "descr", "alias"] if interface.attributes.descr != interface.attributes.alias else ["index", "descr"] ): n_times_item_seen[ _compute_item( - item_appearance, + _to_item_appearance(appearance), interface.attributes, section, pad_portnumbers, - ) + ).item ] += 1 # compute actual item name - item = _compute_item( - single_interface_settings.get( - "item_appearance", - DISCOVERY_DEFAULT_PARAMETERS["discovery_single"][1]["item_appearance"], - ), + item_info = _compute_item( + _to_item_appearance(single_interface_settings["item_appearance"]) + if "item_appearance" in single_interface_settings + else (DISCOVERY_DEFAULT_PARAMETERS["discovery_single"][1]["item_appearance"]), interface.attributes, section, pad_portnumbers, ) + item = item_info.item # discover single interface if discover_single_interface and interface.attributes.index not in seen_indices: - discovered_params_single = { + discovered_params_single: dict[str, object] = { + "item_appearance": item_info.used_appearance, "discovered_oper_status": [interface.attributes.oper_status], "discovered_speed": interface.attributes.speed, } @@ -1190,9 +1230,10 @@ def discover_interfaces( # pylint: disable=too-many-branches interface_groups.setdefault( interface.attributes.group, { - "member_appearance": single_interface_settings.get( - "item_appearance", - "index", + "member_appearance": ( + _to_item_appearance(single_interface_settings["item_appearance"]) + if "item_appearance" in single_interface_settings + else "index" ), }, ) @@ -1256,7 +1297,7 @@ def _check_ungrouped_ifs( item: str, params: Mapping[str, Any], section: Section[TInterfaceType], - timestamp: float, + timestamps: Sequence[float], value_store: MutableMapping[str, Any], ) -> CheckResult: """ @@ -1268,8 +1309,12 @@ def _check_ungrouped_ifs( last_results = None results_from_fastest_interface = None max_out_traffic = -1.0 - - for interface in matching_interfaces_for_item(item, section): + item_appearance = ( + _to_item_appearance(params["item_appearance"]) if "item_appearance" in params else None + ) + for timestamp, interface in zip( + timestamps, matching_interfaces_for_item(item, section, item_appearance) + ): last_results = list( check_single_interface( item, @@ -1305,23 +1350,6 @@ def _check_ungrouped_ifs( return -def _filter_matching_interfaces( - *, - item: str, - group_config: GroupConfiguration, - section: Section[TInterfaceType], -) -> Iterable[InterfaceWithCounters | InterfaceWithRates]: - yield from ( - interface - for interface in section - if _check_group_matching_conditions( - interface.attributes, - item, - group_config, - ) - ) - - def _accumulate_attributes( *, matching_attributes: Collection[Attributes], @@ -1417,24 +1445,25 @@ def _group_members( groups_node = group_members.setdefault(attributes.node, []) member_info = MemberInfo( name=_compute_item( - group_config.get( - "member_appearance", - # This happens when someones upgrades from v1.6 to v2,0, where the structure of the - # discovered parameters changed. Interface groups defined by the user will stop - # working, users have to do a re-discovery in that case, as we wrote in werk #11361. - # However, we can still support groups defined already in the agent output, since - # these work purley by the group name. + # This happens when someones upgrades from v1.6 to v2,0, where the structure of the + # discovered parameters changed. Interface groups defined by the user will stop + # working, users have to do a re-discovery in that case, as we wrote in werk #11361. + # However, we can still support groups defined already in the agent output, since + # these work purley by the group name. + group_config["member_appearance"] + if "member_appearance" in group_config + else _to_item_appearance( str( group_config.get( "item_type", DISCOVERY_DEFAULT_PARAMETERS["discovery_single"][1]["item_appearance"], ) - ), + ) ), attributes, section, item[0] == "0", - ), + ).item, oper_status_name=attributes.oper_status_name, admin_status_name=( None @@ -1451,7 +1480,7 @@ def _check_grouped_ifs( params: Mapping[str, Any], section: Section[TInterfaceType], group_name: str, - timestamp: float, + timestamps: Sequence[float], value_store: MutableMapping[str, Any], ) -> CheckResult: """ @@ -1465,10 +1494,11 @@ def _check_grouped_ifs( value_store=value_store, params=params, ) - for iface in _filter_matching_interfaces( - item=item, - group_config=params["aggregate"], - section=section, + for timestamp, iface in zip(timestamps, section) + if _check_group_matching_conditions( + iface.attributes, + item, + params["aggregate"], ) ] yield from check_single_interface( @@ -1502,11 +1532,14 @@ def check_multiple_interfaces( section: Section[TInterfaceType], *, group_name: str = "Interface group", - timestamp: float | None = None, + timestamps: Sequence[float] | None = None, value_store: MutableMapping[str, Any] | None = None, ) -> CheckResult: - if timestamp is None: - timestamp = time.time() + if timestamps is not None: + timestamps_f = timestamps + else: + now = time.time() + timestamps_f = [now] * len(section) if value_store is None: value_store = get_value_store() @@ -1516,7 +1549,7 @@ def check_multiple_interfaces( params, section, group_name, - timestamp, + timestamps_f, value_store, ) else: @@ -1524,7 +1557,7 @@ def check_multiple_interfaces( item, params, section, - timestamp, + timestamps_f, value_store, ) diff --git a/cmk/plugins/memory/agent_based/mem_win.py b/cmk/plugins/memory/agent_based/mem_win.py index 0d3331465a7..7c5d404f19b 100644 --- a/cmk/plugins/memory/agent_based/mem_win.py +++ b/cmk/plugins/memory/agent_based/mem_win.py @@ -66,7 +66,7 @@ def check_mem_windows_static( value_store: MutableMapping[str, object], now: float, ) -> CheckResult: - average = params.get("average") + averaging_horizon_seconds = params.get("average") for title, prefix, metric_prefix, levels in ( ("RAM", "Mem", "mem", params["memory"]), @@ -87,13 +87,19 @@ def check_mem_windows_static( yield from memory.check_element(label=title, used=used_raw, total=total) # Do averaging, if configured, just for matching the levels - if average is None: + if averaging_horizon_seconds is None: used = used_raw avg_text = "" avg_suffix = "" else: - used = get_average(value_store, metric_prefix, now, used_raw, average) - avg_text = f" (averaged over {int(average)} min)" + used = get_average( + value_store, + metric_prefix, + now, + used_raw, + averaging_horizon_seconds / 60, + ) + avg_text = f" (averaged over {render.timespan(averaging_horizon_seconds)})" avg_suffix = "_avg" yield Metric( f"{metric_prefix}_used_percent", used_raw / total * 100.0, boundaries=(0.0, 100.0) diff --git a/cmk/plugins/memory/rulesets/mem_win.py b/cmk/plugins/memory/rulesets/mem_win.py index 1ac899f9f88..e526fc59939 100644 --- a/cmk/plugins/memory/rulesets/mem_win.py +++ b/cmk/plugins/memory/rulesets/mem_win.py @@ -238,7 +238,11 @@ def _parameters_memory_pagefile_win() -> Dictionary: "average": DictElement[float]( parameter_form=TimeSpan( title=Title("Averaging"), - displayed_magnitudes=[TimeMagnitude.MINUTE], + displayed_magnitudes=[ + TimeMagnitude.HOUR, + TimeMagnitude.MINUTE, + TimeMagnitude.SECOND, + ], help_text=Help( "If this parameter is set, all measured values will be averaged " "over the specified time interval before levels are being applied. " diff --git a/cmk/plugins/random/rulesets/special_agent.py b/cmk/plugins/random/rulesets/special_agent.py new file mode 100644 index 00000000000..c300ae8c32b --- /dev/null +++ b/cmk/plugins/random/rulesets/special_agent.py @@ -0,0 +1,44 @@ +#!/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, Title +from cmk.rulesets.v1.form_specs import FixedValue +from cmk.rulesets.v1.form_specs._composed import DictElement, Dictionary +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def _parameter_form() -> Dictionary: + return Dictionary( + title=Title("Create random monitoring data"), + help_text=Help( + "By configuring this rule for a host - instead of the normal " + "Check_MK agent random monitoring data will be created." + ), + elements={ + "random": DictElement( + required=True, + parameter_form=FixedValue(value=None, title=Title("Create random monitoring data")), + ) + }, + migrate=_migrate, + ) + + +def _migrate(params: object) -> dict[str, object]: + match params: + case {"random": random_value}: + return {"random": random_value} + case {}: + return {"random": None} + raise ValueError(f"Invalid parameters: {params!r}") + + +rule_spec_special_agent_random = SpecialAgent( + name="random", + title=Title("Create random monitoring data"), + topic=Topic.APPLICATIONS, + parameter_form=_parameter_form, +) diff --git a/cmk/plugins/random/server_side_calls/special_agent.py b/cmk/plugins/random/server_side_calls/special_agent.py new file mode 100644 index 00000000000..0aef84f4575 --- /dev/null +++ b/cmk/plugins/random/server_side_calls/special_agent.py @@ -0,0 +1,25 @@ +#!/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 Iterable + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand, SpecialAgentConfig + + +class Params(BaseModel): + random: None + + +def command_function(params: Params, host_config: HostConfig) -> Iterable[SpecialAgentCommand]: + yield SpecialAgentCommand(command_arguments=[host_config.name]) + + +special_agent_random = SpecialAgentConfig( + name="random", + parameter_parser=Params.model_validate, + commands_function=command_function, +) diff --git a/cmk/plugins/storeonce4x/rulesets/special_agent.py b/cmk/plugins/storeonce4x/rulesets/special_agent.py new file mode 100644 index 00000000000..ee50ed8b9bd --- /dev/null +++ b/cmk/plugins/storeonce4x/rulesets/special_agent.py @@ -0,0 +1,71 @@ +#!/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 typing import Mapping + +from cmk.rulesets.v1 import Label, Title +from cmk.rulesets.v1.form_specs import ( + BooleanChoice, + DictElement, + Dictionary, + migrate_to_password, + Password, + String, + validators, +) +from cmk.rulesets.v1.form_specs._base import DefaultValue +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def parameter_form() -> Dictionary: + return Dictionary( + title=Title("HPE StoreOnce via REST API 4.x"), + elements={ + "user": DictElement( + required=True, + parameter_form=String( + title=Title("Username"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "password": DictElement( + required=True, + parameter_form=Password( + title=Title("Password"), + custom_validate=(validators.LengthInRange(min_value=1),), + migrate=migrate_to_password, + ), + ), + "ignore_tls": DictElement( + parameter_form=BooleanChoice( + label=Label("Ignore TLS certificate"), + prefill=DefaultValue(False), + ), + required=True, + ), + }, + migrate=_migrate_cert, + ) + + +def _migrate_cert(params: object) -> Mapping[str, object]: + match params: + case {"cert": cert_value, **rest}: + return { + "ignore_tls": not cert_value, + **{str(k): v for k, v in rest.items()}, + } + case dict(): + return {**params, "ignore_tls": False} + raise TypeError(f"Invalid parameters: {params!r}") + + +rule_spec_special_agent_storeonce4x = SpecialAgent( + name="storeonce4x", + title=Title("HPE StoreOnce via REST API 4.x"), + topic=Topic.GENERAL, + parameter_form=parameter_form, +) diff --git a/cmk/plugins/storeonce4x/server_side_calls/special_agent.py b/cmk/plugins/storeonce4x/server_side_calls/special_agent.py new file mode 100644 index 00000000000..a9bd831918f --- /dev/null +++ b/cmk/plugins/storeonce4x/server_side_calls/special_agent.py @@ -0,0 +1,41 @@ +#!/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 + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand, SpecialAgentConfig +from cmk.server_side_calls.v1._utils import Secret + + +class Params(BaseModel): + user: str + password: Secret + ignore_tls: bool + + +def commands_function( + params: Params, + host_config: HostConfig, +) -> Iterable[SpecialAgentCommand]: + command_arguments: list[str | Secret] = [ + params.user, + params.password.unsafe(), + host_config.name, + ] + + if params.ignore_tls is False: + command_arguments.append("--verify_ssl") + + yield SpecialAgentCommand(command_arguments=command_arguments) + + +special_agent_storeonce = SpecialAgentConfig( + name="storeonce4x", + parameter_parser=Params.model_validate, + commands_function=commands_function, +) diff --git a/cmk/plugins/vsphere/rulesets/special_agent.py b/cmk/plugins/vsphere/rulesets/special_agent.py new file mode 100644 index 00000000000..fcc0fbd05a7 --- /dev/null +++ b/cmk/plugins/vsphere/rulesets/special_agent.py @@ -0,0 +1,249 @@ +#!/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, + CascadingSingleChoice, + CascadingSingleChoiceElement, + DefaultValue, + DictElement, + Dictionary, + FixedValue, + Integer, + migrate_to_password, + MultipleChoice, + MultipleChoiceElement, + Password, + SingleChoice, + String, + validators, +) +from cmk.rulesets.v1.form_specs._basic import SingleChoiceElement +from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic + + +def parameter_form() -> Dictionary: + return Dictionary( + title=Title("VMware ESX via vSphere"), + help_text=Help( + "This rule allows monitoring of VMware ESX via the vSphere API. " + "You can configure your connection settings here.", + ), + elements={ + "user": DictElement( + required=True, + parameter_form=String( + title=Title("vSphere User name"), + custom_validate=(validators.LengthInRange(min_value=1),), + ), + ), + "secret": DictElement( + required=True, + parameter_form=Password( + title=Title("vSphere secret"), + custom_validate=(validators.LengthInRange(min_value=1),), + migrate=migrate_to_password, + ), + ), + "direct": DictElement( + required=True, + parameter_form=SingleChoice( + migrate=_migrate_direct, + title=Title("Type of query"), + elements=[ + SingleChoiceElement( + name="host_system", + title=Title("Queried host is a host system"), + ), + SingleChoiceElement( + name="vcenter", + title=Title("Queried host is the vCenter"), + ), + ], + ), + ), + "tcp_port": DictElement( + required=False, + parameter_form=Integer( + title=Title("TCP Port number"), + help_text=Help("Port number for HTTPS connection to vSphere"), + prefill=DefaultValue(443), + custom_validate=(validators.NetworkPort(),), + ), + ), + "ssl": DictElement( + parameter_form=CascadingSingleChoice( + title=Title("SSL certificate checking"), + elements=[ + CascadingSingleChoiceElement( + name="deactivated", + title=Title("Deactivated"), + parameter_form=FixedValue(value=False), + ), + CascadingSingleChoiceElement( + name="hostname", + title=Title("Use host name"), + parameter_form=FixedValue(value=True), + ), + CascadingSingleChoiceElement( + name="custom_hostname", + title=Title("Use other host name"), + parameter_form=String( + help_text=Help( + "Use a custom name for the SSL certificate validation" + ), + macro_support=True, + ), + ), + ], + prefill=DefaultValue("hostname"), + ), + required=True, + ), + "timeout": DictElement( + required=False, + parameter_form=Integer( + title=Title("Connect timeout"), + help_text=Help( + "The network timeout in seconds when communicating with vSphere or " + "to the Checkmk Agent. The default is 60 seconds. Please note that this " + "is not a total timeout but is applied to each individual network transation." + ), + prefill=DefaultValue(60), + custom_validate=(validators.NumberInRange(min_value=1),), + unit_symbol="seconds", + ), + ), + "infos": DictElement( + required=True, + parameter_form=MultipleChoice( + title=Title("Retrieve information about..."), + elements=[ + MultipleChoiceElement(name="hostsystem", title=Title("Host Systems")), + MultipleChoiceElement( + name="virtualmachine", title=Title("Virtual Machines") + ), + MultipleChoiceElement(name="datastore", title=Title("Datastores")), + MultipleChoiceElement(name="counters", title=Title("Performance counters")), + MultipleChoiceElement(name="licenses", title=Title("License Usage")), + ], + prefill=DefaultValue(["hostsystem", "virtualmachine", "datastore", "counters"]), + ), + ), + "skip_placeholder_vms": DictElement( + required=True, + parameter_form=BooleanChoice( + title=Title("Placeholder VMs"), + label=Label("Do not monitor placeholder VMs"), + prefill=DefaultValue(True), + help_text=Help( + "Placeholder VMs are created by the Site Recovery Manager (SRM) and act as backup " + "virtual machines in case the default VM is unable to start. This option tells the " + "vSphere agent to exclude placeholder VMs in its output." + ), + ), + ), + "host_pwr_display": DictElement( + required=False, + parameter_form=SingleChoice( + migrate=_migrate_pwr_display, + title=Title("Display ESX Host power state on"), + elements=[ + SingleChoiceElement( + "host", Title("The queried ESX system (vCenter / Host)") + ), + SingleChoiceElement("esxhost", Title("The ESX Host")), + SingleChoiceElement("vm", Title("The virtual machine")), + ], + prefill=DefaultValue("host"), + ), + ), + "vm_pwr_display": DictElement( + required=False, + parameter_form=SingleChoice( + migrate=_migrate_pwr_display, + title=Title("Display VM power state additionally on"), + help_text=Help( + "The power state can be displayed additionally either " + "on the ESX host or the VM. This will result in services " + "for both the queried system and the ESX host / VM. " + "By disabling the unwanted services it is then possible " + "to configure where the services are displayed." + ), + elements=[ + SingleChoiceElement( + "host", Title("The queried ESX system (vCenter / Host)") + ), + SingleChoiceElement("esxhost", Title("The ESX Host")), + SingleChoiceElement("vm", Title("The virtual machine")), + ], + prefill=DefaultValue("host"), + ), + ), + "snapshots_on_host": DictElement( + required=True, + parameter_form=BooleanChoice( + title=Title("VM snapshot summary"), + label=Label("Display snapshot summary on ESX hosts"), + prefill=DefaultValue(False), + help_text=Help( + "By default the snapshot summary service is displayed on the vCenter. " + "Users who run an ESX host on its own or do not include their vCenter in the " + "monitoring can choose to display the snapshot summary on the ESX host itself." + ), + ), + ), + "vm_piggyname": DictElement( + required=False, + parameter_form=SingleChoice( + title=Title("Piggyback name of virtual machines"), + elements=[ + SingleChoiceElement( + "alias", Title("Use the name specified in the ESX system") + ), + SingleChoiceElement( + "hostname", + Title("Use the VMs host name if set, otherwise fall back to ESX name"), + ), + ], + prefill=DefaultValue("alias"), + ), + ), + "spaces": DictElement( + required=True, + parameter_form=SingleChoice( + title=Title("Spaces in host names"), + elements=[ + SingleChoiceElement("cut", Title("Cut everything after first space")), + SingleChoiceElement("underscore", Title("Replace with underscores")), + ], + prefill=DefaultValue("underscore"), + ), + ), + }, + ) + + +def _migrate_direct(value: object) -> str: + if value is True: + return "host_system" + return "vcenter" + + +def _migrate_pwr_display(value: object) -> str: + if value is None: + return "host" + return str(value) + + +rule_spec_special_agent_vsphere = SpecialAgent( + name="vsphere", + title=Title("VMware ESX via vSphere"), + topic=Topic.CLOUD, + parameter_form=parameter_form, + help_text=Help("Monitoring VMWare ESXi"), +) diff --git a/cmk/plugins/vsphere/server_side_calls/special_agent.py b/cmk/plugins/vsphere/server_side_calls/special_agent.py new file mode 100644 index 00000000000..c9cc49f46f7 --- /dev/null +++ b/cmk/plugins/vsphere/server_side_calls/special_agent.py @@ -0,0 +1,94 @@ +#!/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. + +# { +# 'tcp_port': 443, +# 'secret': 'wef', +# 'infos': ['hostsystem', 'virtualmachine'], +# 'user': 'wefwef' +# } + + +# mypy: disable-error-code="list-item" + +from collections.abc import Iterable, Sequence + +from pydantic import BaseModel + +from cmk.server_side_calls.v1 import HostConfig, SpecialAgentCommand, SpecialAgentConfig +from cmk.server_side_calls.v1._utils import Secret + + +class Params(BaseModel): + user: str + secret: Secret + direct: str + tcp_port: int | None = None + ssl: bool | str + timeout: int | None = None + infos: Sequence[str] + skip_placeholder_vms: bool + host_pwr_display: str | None = None + vm_pwr_display: str | None = None + snapshots_on_host: bool + vm_piggyname: str | None = None + spaces: str + + +def commands_function( # pylint: disable=too-many-branches + params: Params, host_config: HostConfig +) -> Iterable[SpecialAgentCommand]: + command_arguments: list[str | Secret] = [] + if params.tcp_port is not None: + command_arguments += ["-p", "%d" % params.tcp_port] + + command_arguments += ["-u", params.user] + command_arguments += [f"-s={params.secret.unsafe()}"] + command_arguments += ["-i", ",".join(params.infos)] + + # host_system: Queried host is a host system + # vcenter: Queried host is the vCenter + if params.direct == "host_system": + command_arguments += ["--direct", "--hostname", host_config.name] + + if params.skip_placeholder_vms: + command_arguments.append("-P") + + if params.spaces: + command_arguments += ["--spaces", params.spaces] + + if params.timeout: + command_arguments += ["--timeout", params.timeout] + + if params.vm_pwr_display: + command_arguments += ["--vm_pwr_display", params.vm_pwr_display] + + if params.vm_piggyname: + command_arguments += ["--vm_piggyname", params.vm_piggyname] + + if params.host_pwr_display: + command_arguments += ["--host_pwr_display", params.host_pwr_display] + + if params.snapshots_on_host: + command_arguments += ["--snapshots-on-host"] + + cert_verify = params.ssl + if cert_verify is False: + command_arguments += ["--no-cert-check"] + elif cert_verify is True: + command_arguments += ["--cert-server-name", host_config.name] + else: + command_arguments += ["--cert-server-name", cert_verify] + + command_arguments.append(host_config.primary_ip_config.address) + + yield SpecialAgentCommand(command_arguments=command_arguments) + + +special_agent_vsphere = SpecialAgentConfig( + name="vsphere", + parameter_parser=Params.model_validate, + commands_function=commands_function, +) diff --git a/cmk/post_rename_site/plugins/actions/hosts_and_folders.py b/cmk/post_rename_site/plugins/actions/hosts_and_folders.py index 8c12485a0d6..2a7de9bf8aa 100644 --- a/cmk/post_rename_site/plugins/actions/hosts_and_folders.py +++ b/cmk/post_rename_site/plugins/actions/hosts_and_folders.py @@ -37,7 +37,6 @@ def update_hosts_and_folders(old_site_id: SiteId, new_site_id: SiteId, logger: L # config logger.debug("Folder %s: Saving config", folder.alias_path()) folder.save() - folder.save_hosts() rename_action_registry.register( diff --git a/cmk/special_agents/agent_azure.py b/cmk/special_agents/agent_azure.py index db4e8fd1674..1586a7d706a 100644 --- a/cmk/special_agents/agent_azure.py +++ b/cmk/special_agents/agent_azure.py @@ -979,8 +979,10 @@ def write(self, write_empty: bool = False) -> None: class AzureSection(Section): - def __init__(self, name: str, piggytargets: Iterable[str] = ("",)) -> None: - super().__init__("azure_%s" % name, piggytargets, separator=124, options=[]) + def __init__( + self, name: str, piggytargets: Iterable[str] = ("",), separator: int = 124 + ) -> None: + super().__init__("azure_%s" % name, piggytargets, separator=separator, options=[]) class LabelsSection(Section): @@ -1461,7 +1463,7 @@ def write_section_app_registrations(graph_client: GraphApiClient, args: argparse if "app_registrations" not in args.services: return - section = AzureSection("app_registration") + section = AzureSection("app_registration", separator=0) # app registration with client secrets apps = graph_client.applications() diff --git a/cmk/special_agents/agent_hivemanager.py b/cmk/special_agents/agent_hivemanager.py index 9e679f38e14..db506e3a2df 100644 --- a/cmk/special_agents/agent_hivemanager.py +++ b/cmk/special_agents/agent_hivemanager.py @@ -3,36 +3,56 @@ # 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 argparse import base64 import json import sys +from collections.abc import Sequence import requests -from cmk.utils.password_store import replace_passwords +from cmk.special_agents.v0_unstable.agent_common import special_agent_main +from cmk.special_agents.v0_unstable.request_helper import HostnameValidationAdapter -def main(sys_argv=None): - if sys_argv is None: - replace_passwords() - sys_argv = sys.argv[1:] +def main() -> int: + return special_agent_main(_parse_arguments, _main) + + +def _parse_arguments(argv: Sequence[str] | None) -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument( + "server", + help="Hivemanager server address", + ) + parser.add_argument( + "user", + help="Hivemanager API username", + ) + parser.add_argument( + "password", + help="Hivemanager API password", + ) + parser.add_argument( + "--cert-server-name", + metavar="CERT-SERVER-NAME", + help="Use this server name for TLS certificate validation", + ) + return parser.parse_args(argv) - try: - ip = sys_argv[0] - user = sys_argv[1] - password = sys_argv[2] - except IndexError: - sys.stderr.write("Usage: agent_hivemanager \n") - return 2 - auth = f"{user}:{password}" - auth_encoded = base64.encodebytes(auth.encode("utf-8")).decode("utf-8").replace("\n", "") - headers = { - "Authorization": "Basic %s" % auth_encoded, - "Content-Type": "application/json", - } +def _main(args: argparse.Namespace) -> int: + session = _session( + server=args.server, + username=args.user, + password=args.password, + cert_server_name=args.cert_server_name, + ) + try: - data = requests.get("https://%s/hm/api/v1/devices" % ip, headers=headers).text # nosec B113 # BNS:0b0eac + data = session.get( # nosec B113 # BNS:0b0eac + f"https://{args.server}/hm/api/v1/devices", + ).text except Exception as e: sys.stderr.write("Connection error: %s" % e) return 2 @@ -59,4 +79,31 @@ def main(sys_argv=None): if line["upTime"] == "": line["upTime"] = "down" print("|".join(map(str, [f"{x}::{y}" for x, y in line.items() if x in informations]))) - return None + return 0 + + +def _session( + *, + server: str, + username: str, + password: str, + cert_server_name: str | None, +) -> requests.Session: + session = requests.session() + session.headers.update( + { + "Authorization": "Basic %s" + % ( + base64.encodebytes(f"{username}:{password}".encode("utf-8")) + .decode("utf-8") + .replace("\n", "") + ), + "Content-Type": "application/json", + } + ) + if cert_server_name: + session.mount( + f"https://{server}", + HostnameValidationAdapter(cert_server_name), + ) + return session diff --git a/cmk/special_agents/agent_vsphere.py b/cmk/special_agents/agent_vsphere.py index 8c99ba6bc0e..fa33dced0a0 100644 --- a/cmk/special_agents/agent_vsphere.py +++ b/cmk/special_agents/agent_vsphere.py @@ -1708,6 +1708,10 @@ def get_section_snapshot_summary( ] +def _make_unix_time(raw_time: str) -> int: + return int(dateutil.parser.isoparse(raw_time).timestamp()) + + def get_systemtime(connection: ESXConnection, debug: bool) -> int | None: try: response = connection.query_server("systemtime") @@ -1717,7 +1721,7 @@ def get_systemtime(connection: ESXConnection, debug: bool) -> int | None: raise return None - return int(dateutil.parser.isoparse(raw_systime).timestamp()) + return _make_unix_time(raw_systime) def is_placeholder_vm(devices: str) -> bool: @@ -1759,7 +1763,7 @@ def eval_snapshot_list(info: str, _datastores: Mapping[str, Mapping[str, str]]) for entry in snapshot_info: try: # 2013-11-06T15:39:39.347543Z - creation_time = int(time.mktime(time.strptime(entry[2][:19], "%Y-%m-%dT%H:%M:%S"))) + creation_time = _make_unix_time(entry[2]) except ValueError: creation_time = 0 response.append( diff --git a/cmk/special_agents/v0_unstable/request_helper.py b/cmk/special_agents/v0_unstable/request_helper.py index 809d0377f17..40130a25fb1 100644 --- a/cmk/special_agents/v0_unstable/request_helper.py +++ b/cmk/special_agents/v0_unstable/request_helper.py @@ -147,11 +147,28 @@ def __init__( else: self.verify = tls_cert_verification - def request(self, method: str, url: str, **kwargs: object) -> Response: - return self._session.request(method, urljoin(self._base_url, url, **kwargs)) + def request( + self, + method: str, + url: str, + params: Mapping[str, str] | None = None, + ) -> Response: + return self._session.request( + method, + urljoin(self._base_url, url), + params=params, + ) - def get(self, url: str, **kwargs: object) -> Response: - return self.request("get", url, **kwargs) + def get( + self, + url: str, + params: Mapping[str, str] | None = None, + ) -> Response: + return self.request( + "get", + url, + params=params, + ) def parse_api_url( diff --git a/cmk/update_config/plugins/actions/audit_log.py b/cmk/update_config/plugins/actions/audit_log.py new file mode 100644 index 00000000000..c5183fb633d --- /dev/null +++ b/cmk/update_config/plugins/actions/audit_log.py @@ -0,0 +1,44 @@ +#!/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 logging import Logger +from pathlib import Path + +from cmk.gui.exceptions import MKUserError +from cmk.gui.watolib.audit_log import AuditLogStore +from cmk.gui.watolib.paths import wato_var_dir + +from cmk.update_config.registry import update_action_registry, UpdateAction + + +class WatoAuditLogConversion(UpdateAction): + def __call__(self, logger: Logger) -> None: + for file_ in (wato_var_dir() / "log").glob("wato_audit.*"): + if self.needs_conversion(file_): + self.convert_file(file_) + + @staticmethod + def needs_conversion(file_: Path) -> bool: + try: + AuditLogStore(file_).read() + except MKUserError: + return True + return False + + @staticmethod + def convert_file(file_: Path) -> None: + with file_.open("rb") as f: + data = f.read() + with file_.open("wb") as f: + f.write(data.replace(b"\0", b"\n")) + + +update_action_registry.register( + WatoAuditLogConversion( + name="wato_audit_log_converter", + title="Convert WATO audit log to be newline separated", + sort_index=50, + ) +) diff --git a/cmk/update_config/plugins/actions/create_precompiled_files.py b/cmk/update_config/plugins/actions/create_precompiled_files.py index 959b7493cea..2bd60a0d83b 100644 --- a/cmk/update_config/plugins/actions/create_precompiled_files.py +++ b/cmk/update_config/plugins/actions/create_precompiled_files.py @@ -19,7 +19,6 @@ class CreatePrecompiledFiles(UpdateAction): def __call__(self, _logger: Logger) -> None: for folder in folder_tree().root_folder().subfolders_recursively(): folder.save() - folder.save_hosts() update_action_registry.register( diff --git a/cmk/utils/ip_lookup.py b/cmk/utils/ip_lookup.py index 335acd90cfe..00afd2ac856 100644 --- a/cmk/utils/ip_lookup.py +++ b/cmk/utils/ip_lookup.py @@ -27,6 +27,9 @@ _fake_dns: HostAddress | None = None _enforce_localhost = False +_FALLBACK_V4 = HostAddress("0.0.0.0") +_FALLBACK_V6 = HostAddress("::") + @enum.unique class IPStackConfig(enum.IntFlag): @@ -51,13 +54,17 @@ def fallback_ip_for( ) -> HostAddress: match family: case socket.AddressFamily.AF_INET: - return HostAddress("0.0.0.0") + return _FALLBACK_V4 case socket.AddressFamily.AF_INET6: - return HostAddress("::") + return _FALLBACK_V6 case other: assert_never(other) +def is_fallback_ip(ip: HostAddress | str) -> bool: + return HostAddress(ip) in (_FALLBACK_V4, _FALLBACK_V6) + + def _local_ip_for( family: Literal[socket.AddressFamily.AF_INET, socket.AddressFamily.AF_INET6], ) -> HostAddress: diff --git a/cmk/utils/legacy_check_api.py b/cmk/utils/legacy_check_api.py index 79c938c51ec..b3da6d6f9db 100644 --- a/cmk/utils/legacy_check_api.py +++ b/cmk/utils/legacy_check_api.py @@ -42,6 +42,7 @@ @dataclass(frozen=True, kw_only=True) class LegacyCheckDefinition: + name: str detect: SNMPDetectSpecification | None = None fetch: list[SNMPTree] | SNMPTree | None = None sections: list[str] | None = None diff --git a/cmk/utils/man_pages.py b/cmk/utils/man_pages.py index 1d77bfad0a6..819cda29f1e 100644 --- a/cmk/utils/man_pages.py +++ b/cmk/utils/man_pages.py @@ -212,6 +212,7 @@ def fallback(cls, path: Path, name: str, msg: str, content: str) -> "ManPage": "elasticsearch": "Elasticsearch", "entersekt": "Entersekt", "exchange": "Microsoft Exchange", + "gerrit": "Gerrit", "graylog": "Graylog", "haproxy": "HAProxy Loadbalancer", "iis": "Microsoft Internet Information Service", diff --git a/cmk/utils/notify_types.py b/cmk/utils/notify_types.py index c2f548ad41f..dfbc1beb2a8 100644 --- a/cmk/utils/notify_types.py +++ b/cmk/utils/notify_types.py @@ -43,10 +43,16 @@ "UUIDs", "NotifyBulk", "NotifyBulks", + "NotificationParameterID", + "NotificationParameterMethod", + "NotificationParameterSpec", + "NotificationParameterSpecs", # Classes "EventRule", "DisabledNotificationsOptions", "Contact", + "NotificationParameterGeneralInfos", + "NotificationParameterItem", ] ContactName = str @@ -914,3 +920,20 @@ class Contact(TypedDict, total=False): notifications_enabled: bool host_notification_options: str service_notification_options: str + + +class NotificationParameterGeneralInfos(TypedDict): + description: str + comment: str + docu_url: str + + +class NotificationParameterItem(TypedDict): + general: NotificationParameterGeneralInfos + parameter_properties: dict[str, Any] + + +NotificationParameterID = NewType("NotificationParameterID", str) +NotificationParameterMethod = str +NotificationParameterSpec = dict[NotificationParameterID, NotificationParameterItem] +NotificationParameterSpecs = dict[NotificationParameterMethod, NotificationParameterSpec] diff --git a/cmk/utils/password_store/hack.py b/cmk/utils/password_store/hack.py index b584b8be91d..af04cc57f29 100644 --- a/cmk/utils/password_store/hack.py +++ b/cmk/utils/password_store/hack.py @@ -34,6 +34,7 @@ "elasticsearch": True, "fritzbox": False, # needs no secret "gcp": True, + "gerrit": False, "jenkins": True, "mobileiron": True, "netapp_ontap": True, @@ -57,6 +58,15 @@ "appdynamics": True, "ddn_s2a": True, "gcp_status": False, # needs no secret + "hivemanager_ng": True, + "hivemanager": True, + "hp_msa": True, + "ibmsvc": False, # needs no secret + "innovaphone": True, + "storeonce4x": True, + "vsphere": True, + "jolokia": True, + "random": False, # needs no secret } diff --git a/cmk/utils/paths.py b/cmk/utils/paths.py index 4141cbbcb09..b68d211f751 100644 --- a/cmk/utils/paths.py +++ b/cmk/utils/paths.py @@ -103,6 +103,7 @@ def _local_path(global_path: str | Path) -> Path: inventory_dir = _omd_path_str("share/check_mk/inventory") legacy_check_manpages_dir = _omd_path_str("share/check_mk/checkman") agents_dir = _omd_path_str("share/check_mk/agents") +special_agents_dir = _omd_path("share/check_mk/agents/special") web_dir = _omd_path_str("share/check_mk/web") pnp_templates_dir = _omd_path("share/check_mk/pnp-templates") doc_dir = _omd_path("share/doc/check_mk") @@ -120,6 +121,7 @@ def _local_path(global_path: str | Path) -> Path: agent_based_plugins_dir = _base_plugins_dir / "agent_based" gui_plugins_dir = Path(lib_dir, "check_mk", "gui", "plugins") +nagios_plugins_dir = Path(lib_dir, "nagios", "plugins") local_root = _local_path(omd_root) local_share_dir = _local_path(share_dir) @@ -129,12 +131,14 @@ def _local_path(global_path: str | Path) -> Path: local_inventory_dir = _local_path(inventory_dir) local_legacy_check_manpages_dir = _local_path(legacy_check_manpages_dir) local_agents_dir = _local_path(agents_dir) +local_special_agents_dir = _local_path(special_agents_dir) local_web_dir = _local_path(web_dir) local_pnp_templates_dir = _local_path(pnp_templates_dir) local_doc_dir = _local_path(doc_dir) local_locale_dir = _local_path(locale_dir) local_bin_dir = _local_path(bin_dir) local_lib_dir = _local_path(lib_dir) +local_nagios_plugins_dir = _local_path(nagios_plugins_dir) local_mib_dir = _local_path(mib_dir) local_alert_handlers_dir = _local_path(alert_handlers_dir) local_optional_packages_dir = _omd_path("var/check_mk/packages_local") diff --git a/cmk/utils/redis.py b/cmk/utils/redis.py index e1fc40846b1..66dd6565d56 100644 --- a/cmk/utils/redis.py +++ b/cmk/utils/redis.py @@ -90,7 +90,7 @@ def query_redis( except MKTimeout: raise except Exception as e: - raise DataUnavailableException(e) + raise DataUnavailableException(e) from e finally: if query_lock.owned(): query_lock.release() diff --git a/cmk/utils/rulesets/ruleset_matcher.py b/cmk/utils/rulesets/ruleset_matcher.py index 2659053f96b..fe4c2ce4b0d 100644 --- a/cmk/utils/rulesets/ruleset_matcher.py +++ b/cmk/utils/rulesets/ruleset_matcher.py @@ -11,9 +11,11 @@ from typing import ( Any, cast, + FrozenSet, Generic, NamedTuple, NotRequired, + Set, TypeAlias, TypedDict, TypeGuard, @@ -182,7 +184,7 @@ def __init__( host_tags: TagsOfHosts, host_paths: Mapping[HostName, str], label_manager: LabelManager, - all_configured_hosts: Sequence[HostName], + all_configured_hosts: FrozenSet[HostName], clusters_of: Mapping[HostName, Sequence[HostName]], nodes_of: Mapping[HostName, Sequence[HostName]], builtin_host_labels_store: BuiltinHostLabelsStore, @@ -503,7 +505,7 @@ def __init__( host_tags: TagsOfHosts, host_paths: Mapping[HostName, str], label_manager: LabelManager, - all_configured_hosts: Sequence[HostName], + all_configured_hosts: FrozenSet[HostName], clusters_of: Mapping[HostName, Sequence[HostName]], nodes_of: Mapping[HostName, Sequence[HostName]], builtin_host_labels_store: BuiltinHostLabelsStore, @@ -564,11 +566,11 @@ def clear_caches(self) -> None: self.__host_ruleset_cache.clear() self._all_matching_hosts_match_cache.clear() - def all_processed_hosts(self) -> Sequence[HostName]: + def all_processed_hosts(self) -> FrozenSet[HostName]: """Returns a set of all processed hosts""" return self._all_processed_hosts - def set_all_processed_hosts(self, all_processed_hosts: Iterable[HostName]) -> None: + def set_all_processed_hosts(self, all_processed_hosts: Set[HostName]) -> None: involved_clusters: set[HostName] = set() involved_nodes: set[HostName] = set() for hostname in self._all_processed_hosts: @@ -579,11 +581,11 @@ def set_all_processed_hosts(self, all_processed_hosts: Iterable[HostName]) -> No for hostname in involved_clusters: involved_nodes.update(self._nodes_of.get(hostname, [])) - nodes_and_clusters = involved_clusters | involved_nodes | set(all_processed_hosts) + nodes_and_clusters = involved_clusters | involved_nodes | all_processed_hosts # Only add references to configured hosts nodes_and_clusters.intersection_update(self._all_configured_hosts) - self._all_processed_hosts = list(nodes_and_clusters) + self._all_processed_hosts = frozenset(nodes_and_clusters) # The folder host lookup includes a list of all -processed- hosts within a given # folder. Any update with set_all_processed hosts invalidates this cache, because diff --git a/cmk/utils/semantic_version.py b/cmk/utils/semantic_version.py new file mode 100644 index 00000000000..c30331eac04 --- /dev/null +++ b/cmk/utils/semantic_version.py @@ -0,0 +1,40 @@ +#!/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. + +import dataclasses +import re +from typing import Self + + +@dataclasses.dataclass(frozen=True, slots=True, order=True) +class SemanticVersion: + """Container that represents a semantic version (https://semver.org).""" + + major: int + """Major release with incompatible API changes.""" + minor: int + """Minor release with backwards compatible features.""" + patch: int + """Patch release with backwards compatible bug fixes.""" + + def __str__(self) -> str: + """Format the semantic version into a string.""" + return f"{self.major}.{self.minor}.{self.patch}" + + @classmethod + def from_string(cls, string: str) -> Self: + """ + Build semantic version from raw string via regex pattern matching. + + >>> SemanticVersion.from_string("2.0.1") + SemanticVersion(major=2, minor=0, patch=1) + + """ + if not (match := re.compile(r"\d+.\d+.\d+").search(string)): + raise ValueError(f"No semantic version detected in string: {string!r}.") + + major, minor, patch = match.group().split(".") + + return cls(int(major), int(minor), int(patch)) diff --git a/cmk/utils/structured_data.py b/cmk/utils/structured_data.py index 16baeddc440..732d4aa702d 100644 --- a/cmk/utils/structured_data.py +++ b/cmk/utils/structured_data.py @@ -16,7 +16,7 @@ from collections.abc import Callable, Iterable, Mapping, Sequence from dataclasses import dataclass, field from pathlib import Path -from typing import Generic, Literal, NamedTuple, NewType, Self, TypedDict, TypeVar +from typing import Generic, Literal, NewType, Self, TypedDict, TypeVar from cmk.ccc import store @@ -89,24 +89,12 @@ class SDBareTree(TypedDict): Nodes: Mapping[SDNodeName, SDBareTree] -class SDDeltaValue(NamedTuple): - old: SDValue - new: SDValue - - @classmethod - def deserialize(cls, raw_delta_value: tuple[SDValue, SDValue]) -> Self: - return cls(*raw_delta_value) - - def serialize(self) -> tuple[SDValue, SDValue]: - return (self.old, self.new) - - class SDRawDeltaAttributes(TypedDict, total=False): Pairs: Mapping[SDKey, tuple[SDValue, SDValue]] class SDBareDeltaAttributes(TypedDict): - Pairs: Mapping[SDKey, SDDeltaValue] + Pairs: Mapping[SDKey, tuple[SDValue, SDValue]] class SDRawDeltaTable(TypedDict, total=False): @@ -116,7 +104,7 @@ class SDRawDeltaTable(TypedDict, total=False): class SDBareDeltaTable(TypedDict, total=False): KeyColumns: Sequence[SDKey] - Rows: Sequence[Mapping[SDKey, SDDeltaValue]] + Rows: Sequence[Mapping[SDKey, tuple[SDValue, SDValue]]] class SDRawDeltaTree(TypedDict): @@ -150,8 +138,10 @@ class RetentionInterval: source: Literal["previous", "current"] @classmethod - def from_previous(cls, other: RetentionInterval) -> RetentionInterval: - return cls(other.cached_at, other.cache_interval, other.retention_interval, "previous") + def from_previous(cls, previous: RetentionInterval) -> RetentionInterval: + return cls( + previous.cached_at, previous.cache_interval, previous.retention_interval, "previous" + ) @classmethod def from_config( @@ -163,22 +153,6 @@ def from_config( def keep_until(self) -> int: return self.cached_at + self.cache_interval + self.retention_interval - @classmethod - def deserialize( - cls, - raw_retention_interval: ( - tuple[int, int, int] | tuple[int, int, int, Literal["previous", "current"]] - ), - ) -> RetentionInterval: - return ( - cls(*raw_retention_interval) - if len(raw_retention_interval) == 4 - else cls(*raw_retention_interval[:3], "current") - ) - - def serialize(self) -> tuple[int, int, int, Literal["previous", "current"]]: - return self.cached_at, self.cache_interval, self.retention_interval, self.source - @dataclass(frozen=True) class UpdateResult: @@ -264,14 +238,16 @@ def compare(cls, *, left: set[_T], right: set[_T]) -> Self: # '----------------------------------------------------------------------' -class SDFilterChoice(NamedTuple): +@dataclass(frozen=True) +class SDFilterChoice: path: SDPath pairs: Literal["nothing", "all"] | Sequence[SDKey] columns: Literal["nothing", "all"] | Sequence[SDKey] nodes: Literal["nothing", "all"] | Sequence[SDNodeName] -class _SDRetentionFilterChoice(NamedTuple): +@dataclass(frozen=True) +class _SDRetentionFilterChoice: choice: Literal["nothing", "all"] | Sequence[SDKey] cache_info: tuple[int, int] @@ -397,6 +373,308 @@ def _make_retentions_filter_func( ) +# . +# .--serialization-------------------------------------------------------. +# | _ _ _ _ _ | +# | ___ ___ _ __(_) __ _| (_)______ _| |_(_) ___ _ __ | +# | / __|/ _ \ '__| |/ _` | | |_ / _` | __| |/ _ \| '_ \ | +# | \__ \ __/ | | | (_| | | |/ / (_| | |_| | (_) | | | | | +# | |___/\___|_| |_|\__,_|_|_/___\__,_|\__|_|\___/|_| |_| | +# | | +# '----------------------------------------------------------------------' + + +def _serialize_retention_interval( + retention_interval: RetentionInterval, +) -> tuple[int, int, int, Literal["previous", "current"]]: + return ( + retention_interval.cached_at, + retention_interval.cache_interval, + retention_interval.retention_interval, + retention_interval.source, + ) + + +def _serialize_attributes(attributes: _MutableAttributes | ImmutableAttributes) -> SDRawAttributes: + raw_attributes: SDRawAttributes = {} + if attributes.pairs: + raw_attributes["Pairs"] = attributes.pairs + if attributes.retentions: + raw_attributes["Retentions"] = { + k: _serialize_retention_interval(v) for k, v in attributes.retentions.items() + } + return raw_attributes + + +def _serialize_table(table: _MutableTable | ImmutableTable) -> SDRawTable: + raw_table: SDRawTable = {} + if table.rows_by_ident: + raw_table.update( + { + "KeyColumns": table.key_columns, + "Rows": list(table.rows_by_ident.values()), + } + ) + if table.retentions: + raw_table["Retentions"] = { + i: {k: _serialize_retention_interval(v) for k, v in ri.items()} + for i, ri in table.retentions.items() + } + return raw_table + + +def serialize_tree(tree: MutableTree | ImmutableTree) -> SDRawTree: + return { + "Attributes": _serialize_attributes(tree.attributes), + "Table": _serialize_table(tree.table), + "Nodes": {name: serialize_tree(node) for name, node in tree.nodes_by_name.items() if node}, + } + + +def _deserialize_legacy_attributes(raw_pairs: Mapping[SDKey, SDValue]) -> ImmutableAttributes: + return ImmutableAttributes(pairs=raw_pairs) + + +def _deserialize_legacy_table(raw_rows: Sequence[Mapping[SDKey, SDValue]]) -> ImmutableTable: + key_columns = sorted({k for r in raw_rows for k in r}) + rows_by_ident: dict[SDRowIdent, dict[SDKey, SDValue]] = {} + for row in raw_rows: + rows_by_ident.setdefault(_make_row_ident(key_columns, row), {}).update(row) + + return ImmutableTable(key_columns=key_columns, rows_by_ident=rows_by_ident) + + +def _deserialize_legacy_tree( # pylint: disable=too-many-branches + path: SDPath, + raw_tree: Mapping[str, object], + raw_rows: Sequence[Mapping] | None = None, +) -> ImmutableTree: + raw_pairs: dict[SDKey, SDValue] = {} + raw_tables: dict[SDNodeName, list[dict]] = {} + raw_nodes: dict[SDNodeName, dict] = {} + + for key, value in raw_tree.items(): + if isinstance(value, dict): + if not value: + continue + raw_nodes.setdefault(SDNodeName(key), value) + + elif isinstance(value, list): + if not value: + continue + + if all(isinstance(v, (int, float, str, bool)) or v is None for v in value): + if w := ", ".join(str(v) for v in value if v): + raw_pairs.setdefault(SDKey(key), w) + continue + + if all(not isinstance(v, (list, dict)) for row in value for v in row.values()): + # Either we get: + # [ + # {"column1": "value 11", "column2": "value 12",...}, + # {"column1": "value 11", "column2": "value 12",...}, + # ... + # ] + # Or: + # [ + # {"attr": "attr1", "table": [...], "node": {...}, "idx-node": [...]}, + # ... + # ] + raw_tables.setdefault(SDNodeName(key), value) + continue + + for idx, entry in enumerate(value): + raw_nodes.setdefault(SDNodeName(key), {}).setdefault(str(idx), entry) + + elif isinstance(value, (int, float, str, bool)) or value is None: + raw_pairs.setdefault(SDKey(key), value) + + else: + raise TypeError(value) + + return ImmutableTree( + path=path, + attributes=_deserialize_legacy_attributes(raw_pairs), + table=_deserialize_legacy_table(raw_rows) if raw_rows else ImmutableTable(), + nodes_by_name={ + **{ + name: _deserialize_legacy_tree( + path + (name,), + raw_node, + raw_tables.get(name), + ) + for name, raw_node in raw_nodes.items() + }, + **{ + name: ImmutableTree( + path=path + (name,), + table=_deserialize_legacy_table(raw_rows), + ) + for name in set(raw_tables) - set(raw_nodes) + if (raw_rows := raw_tables[name]) + }, + }, + ) + + +def _deserialize_retention_interval( + raw_retention_interval: tuple[int, int, int] + | tuple[int, int, int, Literal["previous", "current"]], +) -> RetentionInterval: + return ( + RetentionInterval(*raw_retention_interval) + if len(raw_retention_interval) == 4 + else RetentionInterval(*raw_retention_interval[:3], "current") + ) + + +def _deserialize_attributes(raw_attributes: SDRawAttributes) -> ImmutableAttributes: + return ImmutableAttributes( + pairs=raw_attributes.get("Pairs", {}), + retentions={ + key: _deserialize_retention_interval(raw_retention_interval) + for key, raw_retention_interval in raw_attributes.get("Retentions", {}).items() + }, + ) + + +def _deserialize_table(raw_table: SDRawTable) -> ImmutableTable: + rows = raw_table.get("Rows", []) + key_columns = raw_table.get("KeyColumns", []) + + rows_by_ident: dict[SDRowIdent, dict[SDKey, SDValue]] = {} + for row in rows: + rows_by_ident.setdefault(_make_row_ident(key_columns, row), {}).update(row) + + return ImmutableTable( + key_columns=key_columns, + rows_by_ident=rows_by_ident, + retentions={ + ident: { + key: _deserialize_retention_interval(raw_retention_interval) + for key, raw_retention_interval in raw_intervals_by_key.items() + } + for ident, raw_intervals_by_key in raw_table.get("Retentions", {}).items() + }, + ) + + +def _deserialize_tree( + *, + path: SDPath, + raw_attributes: SDRawAttributes, + raw_table: SDRawTable, + raw_nodes: Mapping[SDNodeName, SDRawTree], +) -> ImmutableTree: + return ImmutableTree( + path=path, + attributes=_deserialize_attributes(raw_attributes), + table=_deserialize_table(raw_table), + nodes_by_name={ + name: _deserialize_tree( + path=path + (name,), + raw_attributes=raw_node["Attributes"], + raw_table=raw_node["Table"], + raw_nodes=raw_node["Nodes"], + ) + for name, raw_node in raw_nodes.items() + }, + ) + + +def deserialize_tree(raw_tree: object) -> ImmutableTree: + if not isinstance(raw_tree, dict): + raise TypeError(raw_tree) + try: + raw_attributes = raw_tree["Attributes"] + raw_table = raw_tree["Table"] + raw_nodes = raw_tree["Nodes"] + except KeyError: + return _deserialize_legacy_tree(path=(), raw_tree=raw_tree) + return _deserialize_tree( + path=(), + raw_attributes=raw_attributes, + raw_table=raw_table, + raw_nodes=raw_nodes, + ) + + +def _serialize_delta_value(delta_value: SDDeltaValue) -> tuple[SDValue, SDValue]: + return (delta_value.old, delta_value.new) + + +def _serialize_delta_attributes(delta_attributes: ImmutableDeltaAttributes) -> SDRawDeltaAttributes: + return ( + {"Pairs": {k: _serialize_delta_value(v) for k, v in delta_attributes.pairs.items()}} + if delta_attributes.pairs + else {} + ) + + +def _serialize_delta_table(delta_table: ImmutableDeltaTable) -> SDRawDeltaTable: + return ( + { + "KeyColumns": delta_table.key_columns, + "Rows": [ + {k: _serialize_delta_value(v) for k, v in r.items()} for r in delta_table.rows + ], + } + if delta_table.rows + else {} + ) + + +def serialize_delta_tree(delta_tree: ImmutableDeltaTree) -> SDRawDeltaTree: + return { + "Attributes": _serialize_delta_attributes(delta_tree.attributes), + "Table": _serialize_delta_table(delta_tree.table), + "Nodes": { + edge: serialize_delta_tree(node) + for edge, node in delta_tree.nodes_by_name.items() + if node + }, + } + + +def _deserialize_delta_value(raw_delta_value: tuple[SDValue, SDValue]) -> SDDeltaValue: + return SDDeltaValue(raw_delta_value[0], raw_delta_value[1]) + + +def _deserialize_delta_attributes(raw_attributes: SDRawDeltaAttributes) -> ImmutableDeltaAttributes: + return ImmutableDeltaAttributes( + pairs={k: _deserialize_delta_value(v) for k, v in raw_attributes.get("Pairs", {}).items()} + ) + + +def _deserialize_delta_table(raw_table: SDRawDeltaTable) -> ImmutableDeltaTable: + return ImmutableDeltaTable( + key_columns=raw_table.get("KeyColumns", []), + rows=[ + {k: _deserialize_delta_value(v) for k, v in r.items()} + for r in raw_table.get("Rows", []) + ], + ) + + +def _deserialize_delta_tree(*, path: SDPath, raw_tree: SDRawDeltaTree) -> ImmutableDeltaTree: + return ImmutableDeltaTree( + path=path, + attributes=_deserialize_delta_attributes(raw_attributes=raw_tree["Attributes"]), + table=_deserialize_delta_table(raw_table=raw_tree["Table"]), + nodes_by_name={ + raw_node_name: _deserialize_delta_tree( + path=path + (raw_node_name,), + raw_tree=raw_node, + ) + for raw_node_name, raw_node in raw_tree["Nodes"].items() + }, + ) + + +def deserialize_delta_tree(raw_tree: SDRawDeltaTree) -> ImmutableDeltaTree: + return _deserialize_delta_tree(path=(), raw_tree=raw_tree) + + # . # .--mutable tree--------------------------------------------------------. # | _ _ _ _ | @@ -429,7 +707,7 @@ def add(self, pairs: Mapping[SDKey, SDValue]) -> None: def update( self, now: int, - other: ImmutableAttributes, + previous: ImmutableAttributes, path: SDPath, interval: int, choice: _SDRetentionFilterChoice, @@ -440,10 +718,10 @@ def update( compared_keys = _DictKeys.compare( left=set( _get_filtered_dict( - other.pairs, + previous.pairs, _make_retentions_filter_func( filter_func=filter_func, - intervals_by_key=other.retentions, + intervals_by_key=previous.retentions, now=now, ), ) @@ -454,8 +732,8 @@ def update( pairs: dict[SDKey, SDValue] = {} retentions: dict[SDKey, RetentionInterval] = {} for key in compared_keys.only_left: - pairs.setdefault(key, other.pairs[key]) - retentions[key] = RetentionInterval.from_previous(other.retentions[key]) + pairs.setdefault(key, previous.pairs[key]) + retentions[key] = RetentionInterval.from_previous(previous.retentions[key]) for key in compared_keys.both.union(compared_keys.only_right): retentions[key] = retention_interval @@ -470,20 +748,12 @@ def update( path, "Keep until", [f"{k} ({v.keep_until})" for k, v in retentions.items()] ) - def serialize(self) -> SDRawAttributes: - raw_attributes: SDRawAttributes = {} - if self.pairs: - raw_attributes["Pairs"] = self.pairs - if self.retentions: - raw_attributes["Retentions"] = {k: v.serialize() for k, v in self.retentions.items()} - return raw_attributes - @property def bare(self) -> SDBareAttributes: # Useful for debugging; no restrictions return { "Pairs": self.pairs, - "Retentions": {k: v.serialize() for k, v in self.retentions.items()}, + "Retentions": {k: _serialize_retention_interval(v) for k, v in self.retentions.items()}, } @@ -520,19 +790,19 @@ def __eq__(self, other: object) -> bool: def _add_key_columns(self, key_columns: Iterable[SDKey]) -> None: self.key_columns = sorted(set(self.key_columns).union(key_columns)) + def _add_row(self, ident: SDRowIdent, row: Mapping[SDKey, SDValue]) -> None: + if row: + self.rows_by_ident.setdefault(ident, {}).update(row) + def add(self, key_columns: Iterable[SDKey], rows: Sequence[Mapping[SDKey, SDValue]]) -> None: self._add_key_columns(key_columns) for row in rows: self._add_row(_make_row_ident(self.key_columns, row), row) - def _add_row(self, ident: SDRowIdent, row: Mapping[SDKey, SDValue]) -> None: - if row: - self.rows_by_ident.setdefault(ident, {}).update(row) - def update( # pylint: disable=too-many-branches self, now: int, - other: ImmutableTable, + previous: ImmutableTable, path: SDPath, interval: int, choice: _SDRetentionFilterChoice, @@ -540,56 +810,56 @@ def update( # pylint: disable=too-many-branches ) -> None: filter_func = _make_filter_func(choice.choice) retention_interval = RetentionInterval.from_config(*choice.cache_info, interval) - self._add_key_columns(other.key_columns) - old_filtered_rows = { + self._add_key_columns(previous.key_columns) + previous_filtered_rows = { ident: filtered_row - for ident, row in other.rows_by_ident.items() + for ident, row in previous.rows_by_ident.items() if ( filtered_row := _get_filtered_dict( row, _make_retentions_filter_func( filter_func=filter_func, - intervals_by_key=other.retentions.get(ident), + intervals_by_key=previous.retentions.get(ident), now=now, ), ) ) } - self_filtered_rows = { + current_filtered_rows = { ident: filtered_row for ident, row in self.rows_by_ident.items() if (filtered_row := _get_filtered_dict(row, filter_func)) } compared_row_idents = _DictKeys.compare( - left=set(old_filtered_rows), - right=set(self_filtered_rows), + left=set(previous_filtered_rows), + right=set(current_filtered_rows), ) retentions: dict[SDRowIdent, dict[SDKey, RetentionInterval]] = {} for ident in compared_row_idents.only_left: - old_row: dict[SDKey, SDValue] = {} - for key, value in old_filtered_rows[ident].items(): - old_row.setdefault(key, value) + previous_row: dict[SDKey, SDValue] = {} + for key, value in previous_filtered_rows[ident].items(): + previous_row.setdefault(key, value) retentions.setdefault(ident, {})[key] = RetentionInterval.from_previous( - other.retentions[ident][key] + previous.retentions[ident][key] ) - if old_row: + if previous_row: # Update row with key column entries - old_row |= {k: other.rows_by_ident[ident][k] for k in other.key_columns} - self._add_row(ident, old_row) - update_result.add_row_reason(path, ident, "Added row", old_row) + previous_row |= {k: previous.rows_by_ident[ident][k] for k in previous.key_columns} + self._add_row(ident, previous_row) + update_result.add_row_reason(path, ident, "Added row", previous_row) for ident in compared_row_idents.both: compared_keys = _DictKeys.compare( - left=set(old_filtered_rows[ident]), - right=set(self_filtered_rows[ident]), + left=set(previous_filtered_rows[ident]), + right=set(current_filtered_rows[ident]), ) row: dict[SDKey, SDValue] = {} for key in compared_keys.only_left: - row.setdefault(key, other.rows_by_ident[ident][key]) + row.setdefault(key, previous.rows_by_ident[ident][key]) retentions.setdefault(ident, {})[key] = RetentionInterval.from_previous( - other.retentions[ident][key] + previous.retentions[ident][key] ) for key in compared_keys.both.union(compared_keys.only_right): @@ -599,7 +869,7 @@ def update( # pylint: disable=too-many-branches # Update row with key column entries row.update( { - **{k: other.rows_by_ident[ident][k] for k in other.key_columns}, + **{k: previous.rows_by_ident[ident][k] for k in previous.key_columns}, **{k: self.rows_by_ident[ident][k] for k in self.key_columns}, } ) @@ -607,7 +877,7 @@ def update( # pylint: disable=too-many-branches update_result.add_row_reason(path, ident, "Added row", row) for ident in compared_row_idents.only_right: - for key in self_filtered_rows[ident]: + for key in current_filtered_rows[ident]: retentions.setdefault(ident, {})[key] = retention_interval if retentions: @@ -620,21 +890,6 @@ def update( # pylint: disable=too-many-branches [f"{k} ({v.keep_until})" for k, v in intervals_by_key.items()], ) - def serialize(self) -> SDRawTable: - raw_table: SDRawTable = {} - if self.rows_by_ident: - raw_table.update( - { - "KeyColumns": self.key_columns, - "Rows": list(self.rows_by_ident.values()), - } - ) - if self.retentions: - raw_table["Retentions"] = { - i: {k: v.serialize() for k, v in ri.items()} for i, ri in self.retentions.items() - } - return raw_table - @property def bare(self) -> SDBareTable: # Useful for debugging; no restrictions @@ -642,7 +897,8 @@ def bare(self) -> SDBareTable: "KeyColumns": self.key_columns, "RowsByIdent": self.rows_by_ident, "Retentions": { - i: {k: v.serialize() for k, v in ri.items()} for i, ri in self.retentions.items() + i: {k: _serialize_retention_interval(v) for k, v in ri.items()} + for i, ri in self.retentions.items() }, } @@ -753,13 +1009,6 @@ def get_tree(self, path: SDPath) -> MutableTree: def has_table(self, path: SDPath) -> bool: return len(self.get_tree(path).table) > 0 - def serialize(self) -> SDRawTree: - return { - "Attributes": self.attributes.serialize(), - "Table": self.table.serialize(), - "Nodes": {name: node.serialize() for name, node in self.nodes_by_name.items() if node}, - } - @property def bare(self) -> SDBareTree: # Useful for debugging; no restrictions @@ -791,92 +1040,6 @@ def __str__(self) -> str: # '----------------------------------------------------------------------' -def _deserialize_legacy_attributes(raw_pairs: Mapping[SDKey, SDValue]) -> ImmutableAttributes: - return ImmutableAttributes(pairs=raw_pairs) - - -def _deserialize_legacy_table(raw_rows: Sequence[Mapping[SDKey, SDValue]]) -> ImmutableTable: - key_columns = sorted({k for r in raw_rows for k in r}) - rows_by_ident: dict[SDRowIdent, dict[SDKey, SDValue]] = {} - for row in raw_rows: - rows_by_ident.setdefault(_make_row_ident(key_columns, row), {}).update(row) - - return ImmutableTable(key_columns=key_columns, rows_by_ident=rows_by_ident) - - -def _deserialize_legacy_node( # pylint: disable=too-many-branches - path: SDPath, - raw_tree: Mapping[str, object], - raw_rows: Sequence[Mapping] | None = None, -) -> ImmutableTree: - raw_pairs: dict[SDKey, SDValue] = {} - raw_tables: dict[SDNodeName, list[dict]] = {} - raw_nodes: dict[SDNodeName, dict] = {} - - for key, value in raw_tree.items(): - if isinstance(value, dict): - if not value: - continue - raw_nodes.setdefault(SDNodeName(key), value) - - elif isinstance(value, list): - if not value: - continue - - if all(isinstance(v, (int, float, str, bool)) or v is None for v in value): - if w := ", ".join(str(v) for v in value if v): - raw_pairs.setdefault(SDKey(key), w) - continue - - if all(not isinstance(v, (list, dict)) for row in value for v in row.values()): - # Either we get: - # [ - # {"column1": "value 11", "column2": "value 12",...}, - # {"column1": "value 11", "column2": "value 12",...}, - # ... - # ] - # Or: - # [ - # {"attr": "attr1", "table": [...], "node": {...}, "idx-node": [...]}, - # ... - # ] - raw_tables.setdefault(SDNodeName(key), value) - continue - - for idx, entry in enumerate(value): - raw_nodes.setdefault(SDNodeName(key), {}).setdefault(str(idx), entry) - - elif isinstance(value, (int, float, str, bool)) or value is None: - raw_pairs.setdefault(SDKey(key), value) - - else: - raise TypeError(value) - - return ImmutableTree( - path=path, - attributes=_deserialize_legacy_attributes(raw_pairs), - table=_deserialize_legacy_table(raw_rows) if raw_rows else ImmutableTable(), - nodes_by_name={ - **{ - name: _deserialize_legacy_node( - path + (name,), - raw_node, - raw_tables.get(name), - ) - for name, raw_node in raw_nodes.items() - }, - **{ - name: ImmutableTree( - path=path + (name,), - table=_deserialize_legacy_table(raw_rows), - ) - for name in set(raw_tables) - set(raw_nodes) - if (raw_rows := raw_tables[name]) - }, - }, - ) - - def _filter_attributes( attributes: ImmutableAttributes, filter_tree: _FilterTree ) -> ImmutableAttributes: @@ -1003,6 +1166,12 @@ def _merge_nodes(left: ImmutableTree, right: ImmutableTree) -> ImmutableTree: ) +@dataclass(frozen=True) +class SDDeltaValue: + old: SDValue + new: SDValue + + def _encode_as_new(value: SDValue) -> SDDeltaValue: return SDDeltaValue(None, value) @@ -1032,11 +1201,11 @@ def compare( has_changes = False for key in compared_keys.both: - if (new_value := right[key]) != (old_value := left[key]): - compared_dict.setdefault(key, SDDeltaValue(old_value, new_value)) + if (left_value := left[key]) != (right_value := right[key]): + compared_dict.setdefault(key, SDDeltaValue(left_value, right_value)) has_changes = True elif keep_identical: - compared_dict.setdefault(key, SDDeltaValue(old_value, old_value)) + compared_dict.setdefault(key, SDDeltaValue(left_value, left_value)) compared_dict |= {k: _encode_as_removed(right[k]) for k in compared_keys.only_right} compared_dict |= {k: _encode_as_new(left[k]) for k in compared_keys.only_left} @@ -1145,30 +1314,12 @@ def __eq__(self, other: object) -> bool: return NotImplemented return self.pairs == other.pairs - @classmethod - def deserialize(cls, raw_attributes: SDRawAttributes) -> ImmutableAttributes: - return ImmutableAttributes( - pairs=raw_attributes.get("Pairs", {}), - retentions={ - key: RetentionInterval.deserialize(raw_retention_interval) - for key, raw_retention_interval in raw_attributes.get("Retentions", {}).items() - }, - ) - - def serialize(self) -> SDRawAttributes: - raw_attributes: SDRawAttributes = {} - if self.pairs: - raw_attributes["Pairs"] = self.pairs - if self.retentions: - raw_attributes["Retentions"] = {k: v.serialize() for k, v in self.retentions.items()} - return raw_attributes - @property def bare(self) -> SDBareAttributes: # Useful for debugging; no restrictions return { "Pairs": self.pairs, - "Retentions": {k: v.serialize() for k, v in self.retentions.items()}, + "Retentions": {k: _serialize_retention_interval(v) for k, v in self.retentions.items()}, } @@ -1215,42 +1366,6 @@ def rows_with_retentions( for ident, row in self.rows_by_ident.items() ] - @classmethod - def deserialize(cls, raw_table: SDRawTable) -> ImmutableTable: - rows = raw_table.get("Rows", []) - key_columns = raw_table.get("KeyColumns", []) - - rows_by_ident: dict[SDRowIdent, dict[SDKey, SDValue]] = {} - for row in rows: - rows_by_ident.setdefault(_make_row_ident(key_columns, row), {}).update(row) - - return ImmutableTable( - key_columns=key_columns, - rows_by_ident=rows_by_ident, - retentions={ - ident: { - key: RetentionInterval.deserialize(raw_retention_interval) - for key, raw_retention_interval in raw_intervals_by_key.items() - } - for ident, raw_intervals_by_key in raw_table.get("Retentions", {}).items() - }, - ) - - def serialize(self) -> SDRawTable: - raw_table: SDRawTable = {} - if self.rows_by_ident: - raw_table.update( - { - "KeyColumns": self.key_columns, - "Rows": list(self.rows_by_ident.values()), - } - ) - if self.retentions: - raw_table["Retentions"] = { - i: {k: v.serialize() for k, v in ri.items()} for i, ri in self.retentions.items() - } - return raw_table - @property def bare(self) -> SDBareTable: # Useful for debugging; no restrictions @@ -1258,7 +1373,8 @@ def bare(self) -> SDBareTable: "KeyColumns": self.key_columns, "RowsByIdent": self.rows_by_ident, "Retentions": { - i: {k: v.serialize() for k, v in ri.items()} for i, ri in self.retentions.items() + i: {k: _serialize_retention_interval(v) for k, v in ri.items()} + for i, ri in self.retentions.items() }, } @@ -1322,53 +1438,6 @@ def get_tree(self, path: SDPath) -> ImmutableTree: else node.get_tree(path[1:]) ) - @classmethod - def deserialize(cls, raw_tree: Mapping) -> ImmutableTree: - try: - raw_attributes = raw_tree["Attributes"] - raw_table = raw_tree["Table"] - raw_nodes = raw_tree["Nodes"] - except KeyError: - return _deserialize_legacy_node(path=(), raw_tree=raw_tree) - - return ImmutableTree._deserialize( - path=(), - raw_attributes=raw_attributes, - raw_table=raw_table, - raw_nodes=raw_nodes, - ) - - @classmethod - def _deserialize( - cls, - *, - path: SDPath, - raw_attributes: SDRawAttributes, - raw_table: SDRawTable, - raw_nodes: Mapping[SDNodeName, SDRawTree], - ) -> ImmutableTree: - return cls( - path=path, - attributes=ImmutableAttributes.deserialize(raw_attributes), - table=ImmutableTable.deserialize(raw_table), - nodes_by_name={ - name: cls._deserialize( - path=path + (name,), - raw_attributes=raw_node["Attributes"], - raw_table=raw_node["Table"], - raw_nodes=raw_node["Nodes"], - ) - for name, raw_node in raw_nodes.items() - }, - ) - - def serialize(self) -> SDRawTree: - return { - "Attributes": self.attributes.serialize(), - "Table": self.table.serialize(), - "Nodes": {name: node.serialize() for name, node in self.nodes_by_name.items() if node}, - } - @property def bare(self) -> SDBareTree: # Useful for debugging; no restrictions @@ -1439,13 +1508,13 @@ def _filter_delta_tree(tree: ImmutableDeltaTree, filter_tree: _FilterTree) -> Im def _compute_delta_stats(dict_: Mapping[SDKey, SDDeltaValue]) -> SDDeltaCounter: counter: SDDeltaCounter = Counter() - for left, right in dict_.values(): - match [left is None, right is None]: + for delta_value in dict_.values(): + match [delta_value.old is None, delta_value.new is None]: case [True, False]: counter["new"] += 1 case [False, True]: counter["removed"] += 1 - case [False, False] if left != right: + case [False, False] if delta_value.old != delta_value.new: counter["changed"] += 1 return counter @@ -1466,21 +1535,10 @@ def from_attributes( def get_stats(self) -> SDDeltaCounter: return _compute_delta_stats(self.pairs) - @classmethod - def deserialize(cls, raw_attributes: SDRawDeltaAttributes) -> ImmutableDeltaAttributes: - return cls( - pairs={ - k: SDDeltaValue.deserialize(v) for k, v in raw_attributes.get("Pairs", {}).items() - } - ) - - def serialize(self) -> SDRawDeltaAttributes: - return {"Pairs": {k: v.serialize() for k, v in self.pairs.items()}} if self.pairs else {} - @property def bare(self) -> SDBareDeltaAttributes: # Useful for debugging; no restrictions - return {"Pairs": self.pairs} + return {"Pairs": {k: _serialize_delta_value(v) for k, v in self.pairs.items()}} @dataclass(frozen=True, kw_only=True) @@ -1504,30 +1562,13 @@ def get_stats(self) -> SDDeltaCounter: counter.update(_compute_delta_stats(row)) return counter - @classmethod - def deserialize(cls, raw_table: SDRawDeltaTable) -> ImmutableDeltaTable: - return cls( - key_columns=raw_table.get("KeyColumns", []), - rows=[ - {k: SDDeltaValue.deserialize(v) for k, v in r.items()} - for r in raw_table.get("Rows", []) - ], - ) - - def serialize(self) -> SDRawDeltaTable: - return ( - { - "KeyColumns": self.key_columns, - "Rows": [{k: v.serialize() for k, v in r.items()} for r in self.rows], - } - if self.rows - else {} - ) - @property def bare(self) -> SDBareDeltaTable: # Useful for debugging; no restrictions - return {"KeyColumns": self.key_columns, "Rows": self.rows} + return { + "KeyColumns": self.key_columns, + "Rows": [{k: _serialize_delta_value(v) for k, v in r.items()} for r in self.rows], + } @dataclass(frozen=True, kw_only=True) @@ -1584,32 +1625,6 @@ def get_stats(self) -> SDDeltaCounter: counter.update(node.get_stats()) return counter - @classmethod - def deserialize(cls, raw_tree: SDRawDeltaTree) -> ImmutableDeltaTree: - return cls._deserialize(path=(), raw_tree=raw_tree) - - @classmethod - def _deserialize(cls, *, path: SDPath, raw_tree: SDRawDeltaTree) -> ImmutableDeltaTree: - return cls( - path=path, - attributes=ImmutableDeltaAttributes.deserialize(raw_attributes=raw_tree["Attributes"]), - table=ImmutableDeltaTable.deserialize(raw_table=raw_tree["Table"]), - nodes_by_name={ - raw_node_name: cls._deserialize( - path=path + (raw_node_name,), - raw_tree=raw_node, - ) - for raw_node_name, raw_node in raw_tree["Nodes"].items() - }, - ) - - def serialize(self) -> SDRawDeltaTree: - return { - "Attributes": self.attributes.serialize(), - "Table": self.table.serialize(), - "Nodes": {edge: node.serialize() for edge, node in self.nodes_by_name.items() if node}, - } - @property def bare(self) -> SDBareDeltaTree: # Useful for debugging; no restrictions @@ -1637,10 +1652,77 @@ def __str__(self) -> str: def load_tree(filepath: Path) -> ImmutableTree: if raw_tree := store.load_object_from_file(filepath, default=None): - return ImmutableTree.deserialize(raw_tree) + return deserialize_tree(raw_tree) return ImmutableTree() +class SDMeta(TypedDict): + version: Literal["1"] + do_archive: bool + + +def make_meta(*, do_archive: bool) -> SDMeta: + return SDMeta(version="1", do_archive=do_archive) + + +class SDMetaAndRawTree(TypedDict): + meta: SDMeta + raw_tree: SDRawTree + + +def _parse_raw_meta(raw_meta: object) -> SDMeta: + if not isinstance(raw_meta, dict): + raise TypeError(raw_meta) + if not isinstance(version := raw_meta.get("version"), str): + raise TypeError(version) + if not isinstance(do_archive := raw_meta.get("do_archive"), bool): + raise TypeError(do_archive) + match version: + case "1": + return SDMeta(version=version, do_archive=do_archive) + case _: + raise ValueError(version) + + +def _parse_raw_tree(raw_tree: object) -> SDRawTree: + if not isinstance(raw_tree, dict): + raise TypeError(raw_tree) + return SDRawTree( + Attributes=raw_tree.get("Attributes", {}), + Table=raw_tree.get("Table", {}), + Nodes=raw_tree.get("Nodes", {}), + ) + + +def parse_from_unzipped(raw: object) -> SDMetaAndRawTree: + # Note: Since Checkmk 2.1 we explicitly extract "Attributes", "Table" or "Nodes" while + # deserialization. This means that "meta_*" are not taken into account and we stay + # compatible. + if not isinstance(raw, dict): + raise TypeError(raw) + if set(raw) == set(["meta", "raw_tree"]): + # Handle future versions + return SDMetaAndRawTree( + meta=_parse_raw_meta(raw.get("meta")), + raw_tree=_parse_raw_tree(raw.get("raw_tree")), + ) + return SDMetaAndRawTree( + meta=SDMeta( + version="1", + do_archive=raw.get("meta_do_archive", True), + ), + raw_tree=SDRawTree( + Attributes=raw.get("Attributes", {}), + Table=raw.get("Table", {}), + Nodes=raw.get("Nodes", {}), + ), + ) + + +def _make_meta_and_raw_tree(meta: SDMeta, raw_tree: SDRawTree) -> SDMetaAndRawTree: + return SDMetaAndRawTree(meta=meta, raw_tree=raw_tree) + + class TreeStore: def __init__(self, tree_dir: Path | str) -> None: self._tree_dir = Path(tree_dir) @@ -1649,17 +1731,19 @@ def __init__(self, tree_dir: Path | str) -> None: def load(self, *, host_name: HostName) -> ImmutableTree: return load_tree(self._tree_file(host_name)) - def save(self, *, host_name: HostName, tree: MutableTree, pretty: bool = False) -> None: + def save( + self, *, host_name: HostName, tree: MutableTree, meta: SDMeta, pretty: bool = False + ) -> None: self._tree_dir.mkdir(parents=True, exist_ok=True) tree_file = self._tree_file(host_name) - output = tree.serialize() - store.save_object_to_file(tree_file, output, pretty=pretty) + raw_tree = serialize_tree(tree) + store.save_object_to_file(tree_file, raw_tree, pretty=pretty) buf = io.BytesIO() with gzip.GzipFile(fileobj=buf, mode="wb") as f: - f.write((repr(output) + "\n").encode("utf-8")) + f.write((repr(_make_meta_and_raw_tree(meta, raw_tree)) + "\n").encode("utf-8")) store.save_bytes_to_file(self._gz_file(host_name), buf.getvalue()) # Inform Livestatus about the latest inventory update diff --git a/cmk/utils/werks/collect.py b/cmk/utils/werks/collect.py index 30248183b41..2f711443f9e 100644 --- a/cmk/utils/werks/collect.py +++ b/cmk/utils/werks/collect.py @@ -3,56 +3,18 @@ # 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 import logging import re -from collections import defaultdict -from collections.abc import Iterable, Iterator, Mapping +from collections.abc import Iterator, Mapping from pathlib import Path -from typing import Literal, NamedTuple +from typing import Literal -from git.objects.commit import Commit -from git.repo import Repo - -from cmk.werks import load_werk, parse_werk - -from .werk import WebsiteWerk +from cmk.werks.collect import Config +from cmk.werks.collect import main as collect_main logger = logging.getLogger(__name__) -class Config: - """ - We read werks from different git repositories, and each repo has its own - quirks. This config tries to hold all repo specific configuration. - """ - - # only branches matching this regex will be considered for searching for - # werk files. - branch_regex: str - - def cleanup_branch_name(self, branch_name: str) -> str: - # in previous releases of cmk there were branches called 1.2.7i3 - # but we want to store the werks in 1.2.7, we use this function to - # adapt this. - return branch_name - - def adapt_werk_string(self, werk_string: str, werk_id: int) -> str: - # there is one faulty werk in cmk repo, but in many branches - # its easier to fix here... - return werk_string - - @classmethod - def from_flavor(cls, flavor: str) -> "Config": - if flavor == "cma": - return CmaConfig() - if flavor == "checkmk_kube_agent": - return KubeConfig() - if flavor == "cmk": - return CmkConfig() - raise NotImplementedError() - - class CmaConfig(Config): branch_regex = r"^(master$|\d+\.\d+$)" @@ -62,13 +24,13 @@ class CmkConfig(Config): def cleanup_branch_name(self, branch_name: str) -> str: """ - >>> CmkConfig().cleanup_branch_name("1.5.0i3") + >>> CmkConfig("cmk").cleanup_branch_name("1.5.0i3") '1.5.0' - >>> CmkConfig().cleanup_branch_name("1.5.0") + >>> CmkConfig("cmk").cleanup_branch_name("1.5.0") '1.5.0' - >>> [CmkConfig().cleanup_branch_name(v) for v in [ "1.2.5", "1.2.6", "1.2.7", "1.2.8"]] + >>> [CmkConfig("cmk").cleanup_branch_name(v) for v in [ "1.2.5", "1.2.6", "1.2.7", "1.2.8"]] ['1.2.0', '1.2.0', '1.2.0', '1.2.0'] """ if branch_name.startswith("1.2."): @@ -116,47 +78,14 @@ class KubeConfig(Config): branch_regex = r"^(main$|\d+\.\d+\.\d+)" -def branch_name_to_sort(branch_name: str) -> tuple[str | int, ...]: - """ - >>> sorted(["master", "2.1.0", "main", "2.1.0i1"], key=branch_name_to_sort) - ['2.1.0i1', '2.1.0', 'main', 'master'] - - """ - if branch_name in {"master", "main"}: - return (99, 99, 99, 99, branch_name) - result = re.match(r"(\d+)\.(\d+)\.(\d+)(i(\d))?$", branch_name) - if not result: - logger.info("can not sort branch %s", branch_name) - return (0, 0, 0, 0, branch_name) - major, minor, patch, _, innovation = result.groups() - if innovation is None: - innovation = 99 - return (int(major), int(minor), int(patch), int(innovation), branch_name) - - -class WerkFile(NamedTuple): - file_name: str - file_content: bytes - - -def _get_branches( - r: Repo, c: Config, branch_replacement: Mapping[str, str] -) -> Iterable[tuple[str, Commit]]: - if branch_replacement: - for branch, ref in branch_replacement.items(): - yield branch, r.commit(ref) - return - - for ref in r.remote().refs: - if not ref.name.startswith("origin/"): - logger.info("ignoring ref %s (only considering one from remote origin)", ref) - continue - - branch_name = ref.name.removeprefix("origin/") - if not re.match(c.branch_regex, branch_name): - logger.info("ignoring branch %s (does not match regex)", branch_name) - continue - yield branch_name, ref +def config_from_flavor(flavor: Literal["cma", "cmk", "checkmk_kube_agent"]) -> "Config": + if flavor == "cma": + return CmaConfig(flavor) + if flavor == "checkmk_kube_agent": + return KubeConfig(flavor) + if flavor == "cmk": + return CmkConfig(flavor) + raise NotImplementedError() def main( @@ -164,68 +93,4 @@ def main( repo_path: Path, branches: Mapping[str, str], ) -> None: - logging.basicConfig() - - c = Config.from_flavor(flavor) - - werk_files_by_id_and_branch: dict[int, dict[str, WerkFile]] = defaultdict(dict) - r = Repo(repo_path) - for branch_name, ref in _get_branches(r, c, branches): - tree = r.tree(ref) - try: - werks = tree[".werks"] - except KeyError: - logger.warning("no .werks folder in branch %s", branch_name) - continue - - for werk_file in werks.blobs: - werk_id_str = werk_file.name.removesuffix(".md") - try: - werk_id = int(werk_id_str) - except ValueError: - if werk_file.name in {"config", "config.json", "first_free", ".f12", ".gitignore"}: - continue - raise RuntimeError( - f"Found unexpected file {werk_file.name!r} in branch {branch_name!r}" - ) - werk_files_by_id_and_branch[werk_id][branch_name] = WerkFile( - file_name=werk_file.name, file_content=werk_file.data_stream.read() - ) - - all_werks_by_id: dict[str, dict] = {} - for werk_id, werk_by_branch in werk_files_by_id_and_branch.items(): - versions: dict[str, str] = {} - # werks are defined multiple times, the werk that is defined in the "latest" branch wins. - # that's why we sort here by branch name... - for branch, werk_file in sorted( - werk_by_branch.items(), key=lambda i: branch_name_to_sort(i[0]) - ): - werk_string = werk_file.file_content.decode("utf-8") - werk_string = c.adapt_werk_string(werk_string, werk_id) - - try: - parsed = parse_werk(werk_string, werk_file.file_name) - except Exception as e: - raise RuntimeError( - f"could not parse werk {werk_file.file_name} from branch {branch} of flavor {flavor}" - ) from e - versions[c.cleanup_branch_name(branch)] = parsed.metadata["version"] - - try: - # and here we simply access variables of the latest werk iteration above. - werk = load_werk( - file_content=werk_string, file_name=werk_file.file_name - ) # this could be optimized, as we now parse the werk twice. - except Exception as e: - raise RuntimeError(f"could not load werk {werk_id} from flavor {flavor}") from e - - werk_dict = {k: v for k, v in werk.to_json_dict().items() if v is not None} - werk_dict.pop("version") - # WebsiteWerk is not really needed here, but we want to make sure we comply to the WebsiteWerk schema. - all_werks_by_id[str(werk_id)] = WebsiteWerk( - versions=versions, - product=flavor, - **werk_dict, # type: ignore[arg-type] - ).model_dump(by_alias=True, mode="json") - - print(json.dumps(all_werks_by_id)) + collect_main(config_from_flavor(flavor), repo_path, branches) diff --git a/cmk/utils/werks/werk.py b/cmk/utils/werks/werk.py index fe5831a6dac..c6e37715df6 100644 --- a/cmk/utils/werks/werk.py +++ b/cmk/utils/werks/werk.py @@ -6,12 +6,11 @@ from collections.abc import Iterable from functools import partial -from typing import Literal from cmk.ccc.i18n import _ from cmk.ccc.version import parse_check_mk_version -from cmk.werks.models import Class, Compatibility, Werk, WerkV2Base +from cmk.werks.models import Class, Compatibility, Werk _CLASS_SORTING_VALUE = { Class.FEATURE: 1, @@ -25,18 +24,6 @@ } -class WebsiteWerk(WerkV2Base): - # ATTENTION! If you change this model, you have to inform - # the website team first! They rely on those fields. - """ - This Model is used to built up a file containing all werks. - The file is called all_werks.json or all_werks_v2.json - """ - - versions: dict[str, str] - product: Literal["cmk", "cma", "checkmk_kube_agent"] - - def get_sort_key_by_version_and_component( translator: "WerkTranslator", werk: Werk ) -> tuple[str | int, ...]: diff --git a/cmk/validate_plugins.py b/cmk/validate_plugins.py index a4e5c20bb72..6923f5d0c27 100644 --- a/cmk/validate_plugins.py +++ b/cmk/validate_plugins.py @@ -31,7 +31,6 @@ iter_all_inventory_plugins, ) from cmk.base.config import ( # pylint: disable=cmk-module-layer-violation - check_info, load_all_plugins, ) @@ -274,20 +273,11 @@ def _validate_check_parameters_usage() -> Sequence[str]: raise_errors=False, ) - agent_based_api_referenced_ruleset_names = [ + referenced_ruleset_names = { str(plugin.check_ruleset_name) for plugin in iter_all_check_plugins() if plugin.check_ruleset_name is not None - ] - legacy_checks_referenced_ruleset_names = [ - str(check.check_ruleset_name) - for check in check_info.values() - if hasattr(check, "check_ruleset_name") - ] - - referenced_ruleset_names = set( - agent_based_api_referenced_ruleset_names + legacy_checks_referenced_ruleset_names - ) + } return _check_if_referenced(discovered_check_parameters, referenced_ruleset_names) diff --git a/defines/dev-images/reference/Dockerfile b/defines/dev-images/reference/Dockerfile index e0fb4a0fae5..147c0a2afa0 100644 --- a/defines/dev-images/reference/Dockerfile +++ b/defines/dev-images/reference/Dockerfile @@ -1,4 +1,4 @@ -ARG BASE_BUILD_IMAGE +ARG BASE_BUILD_IMAGE=you_forgot_to_set:base_build_image FROM ${BASE_BUILD_IMAGE} diff --git a/doc/helpers/add-icon-category b/doc/helpers/add-icon-category deleted file mode 100755 index 0c14831c05b..00000000000 --- a/doc/helpers/add-icon-category +++ /dev/null @@ -1,26 +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. - -import sys - -from PIL import Image, PngImagePlugin # pylint: disable=pillow-module-import - -if len(sys.argv) < 3: - sys.stderr.write("So gehts:\n") - sys.stderr.write(" add-icon-category category_name pfad/zu/den/bildern*.png\n") - sys.exit(1) - -category = sys.argv[1] -images = sys.argv[2:] - -for image in images: - im = Image.open(image) - im.info["Comment"] = category - - meta = PngImagePlugin.PngInfo() - for k, v in im.info.items(): - if k not in ("interlace", "gamma", "dpi", "transparency", "aspect"): - meta.add_text(k, v, False) - im.save(image, "PNG", pnginfo=meta) diff --git a/doc/plugin-api/Makefile b/doc/plugin-api/Makefile index 8ee41c36138..c9032ef82ff 100644 --- a/doc/plugin-api/Makefile +++ b/doc/plugin-api/Makefile @@ -11,7 +11,7 @@ PIPENV := $(REPO_PATH)/omd/run-pipenv # You can set these variables from the command line, and also # from the environment for the first one. -SPHINXOPTS ?= +SPHINXOPTS ?= --fail-on-warning SPHINXBUILD := $(PIPENV) run sphinx-build BASEDIR = $(REPO_PATH)/doc/plugin-api SOURCEDIR = $(BASEDIR)/source diff --git a/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/index.rst b/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/index.rst index eade16c0f3f..f2313cdc9b6 100644 --- a/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/index.rst +++ b/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/index.rst @@ -2,13 +2,6 @@ Dynamic configuration connector =============================== -.. automodule:: cmk.cee.dcd.plugins.connectors.connectors_api +.. automodule:: cmk.cee.dcd.connector_api :members: :show-inheritance: - -Version 1 -========= - -.. toctree:: - - v1 diff --git a/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/v1.rst b/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/v1.rst deleted file mode 100644 index 8952758fded..00000000000 --- a/doc/plugin-api/source/cmk.cee.dcd.plugins.connectors.connectors_api/v1.rst +++ /dev/null @@ -1,7 +0,0 @@ -================= -connectors_api.v1 -================= - -.. automodule:: cmk.cee.dcd.plugins.connectors.connectors_api.v1 - :members: - :show-inheritance: diff --git a/doc/plugin-api/source/index.rst b/doc/plugin-api/source/index.rst index be4685e6062..5303fdd7aaf 100644 --- a/doc/plugin-api/source/index.rst +++ b/doc/plugin-api/source/index.rst @@ -53,13 +53,9 @@ Each plugin expects a different prefix in the variable name: - graphs the ``graph_`` prefix .. toctree:: + :glob: - cmk.agent_based/index - cmk.base.plugins.bakery.bakery_api/index - cmk.server_side_calls/index - cmk.graphing/index - cmk.rulesets/index - cmk.cee.dcd.plugins.connectors.connectors_api/index + cmk.*/index Indices and tables ================== diff --git a/doc/skeleton_check b/doc/skeleton_check index 9c730e115fb..d3e2e8e0659 100644 --- a/doc/skeleton_check +++ b/doc/skeleton_check @@ -4,20 +4,18 @@ # conditions defined in the file COPYING, which is part of this source code package. from collections.abc import Mapping -from typing import Any -from .agent_based_api.v1 import ( # type: ignore[import-untyped] # pylint: disable=import-error +from cmk.agent_based.v2 import ( + AgentSection, + CheckPlugin, + CheckResult, + DiscoveryResult, HostLabel, - register, + HostLabelGenerator, Result, RuleSetType, Service, State, -) -from .agent_based_api.v1.type_defs import ( # type: ignore[import-untyped] # pylint: disable=import-error - CheckResult, - DiscoveryResult, - HostLabelGenerator, StringTable, ) @@ -39,23 +37,23 @@ def parse_norris(string_table: StringTable) -> Section: def host_labels_norris(section: Section) -> HostLabelGenerator: - yield HostLabel(...) + yield HostLabel("name", "value") -register.snmp_section( +agent_section_norris = AgentSection( name="norris", # Don't use this unless you known what you're doing! - # parsed_section_name="mr_pickle", # you can' rename norris, norris renames you! + # parsed_section_name="mr_pickle", # you can't rename norris, norris renames you! parse_function=parse_norris, host_label_function=host_labels_norris, ) -def discover_norris(params: Mapping[str, Any], section: Section) -> DiscoveryResult: - yield Service(...) +def discover_norris(params: Mapping[str, object], section: Section) -> DiscoveryResult: + yield Service(item="Chuck") -def check_norris(item: str, params: Mapping[str, Any], section: Section) -> CheckResult: +def check_norris(item: str, params: Mapping[str, object], section: Section) -> CheckResult: yield Result( state=State.UNKNOWN, summary="Check not implemented", @@ -69,7 +67,7 @@ def check_norris(item: str, params: Mapping[str, Any], section: Section) -> Chec def cluster_check_norris( - item: str, params: Mapping[str, Any], section: Mapping[str, Section] + item: str, params: Mapping[str, object], section: Mapping[str, Section] ) -> CheckResult: """This is just an example.""" aggregated_data = Section() @@ -80,9 +78,9 @@ def cluster_check_norris( yield from check_norris(item, params, aggregated_data) -register.check_plugin( +check_plugin_norris = CheckPlugin( name="norris", - service_description="Check Norris %s", + service_name="Check Norris %s", discovery_function=discover_norris, discovery_default_parameters={}, discovery_ruleset_name="norris_discovery_rule", diff --git a/locale/de/LC_MESSAGES/multisite.po b/locale/de/LC_MESSAGES/multisite.po index e36c1fd07ac..ec92321bbf8 100644 --- a/locale/de/LC_MESSAGES/multisite.po +++ b/locale/de/LC_MESSAGES/multisite.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: Checkmk user interface translation 0.1\n" "Report-Msgid-Bugs-To: feedback@checkmk.com\n" "POT-Creation-Date: 2011-05-13 09:42+0200\n" -"PO-Revision-Date: 2024-09-20 02:18+0000\n" +"PO-Revision-Date: 2024-10-10 05:00+0000\n" "Language-Team: German \n" "Language: de\n" @@ -407,6 +407,10 @@ msgstr "%d Tage" msgid "%d days ago" msgstr "vor %d Tagen" +#, python-format +msgid "%d defined parameter properties" +msgstr "%d definierte Parametereigenschaften" + #, python-format msgid "%d errors occured:" msgstr "%d aufgetretene Fehler:" @@ -570,6 +574,10 @@ msgstr "%s pro Host" msgid "%s can only be deleted via Quick setup" msgstr "%s kann nur durch Quick Setup gelöscht werden" +#, python-format +msgid "%s cannot be empty" +msgstr "%s darf nicht leer sein" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -691,6 +699,10 @@ msgstr "%s-Rate" msgid "%s resulting notifications" msgstr "%s resultierende Benachrichtigungen" +#, python-format +msgid "%s rules" +msgstr "%s Regeln" + #, python-format msgid "%s running for %s" msgstr "%s läuft seit %s" @@ -809,9 +821,16 @@ msgstr "" "Versionierung der Konfiguration benötigt. git' muss entweder installiert " "oder die Verfolgung der Git-Konfiguration im Setup deaktiviert werden." +#, python-format +msgid "(%s more entries)" +msgstr "(%s weitere Einträge)" + msgid "(0 is current period)" msgstr "(0 entspricht aktuelle Periode)" +msgid "(1 more entry)" +msgstr "(1 weiterer Eintrag)" + msgid "(Edit presets)" msgstr "(Voreinstellungen bearbeiten)" @@ -887,9 +906,6 @@ msgstr "(kein Titel)" msgid "(none)" msgstr "(keine)" -msgid "(not supported)" -msgstr "(nicht unterstützt)" - msgid "(nothing selected)" msgstr "(nicht ausgewählt)" @@ -1001,6 +1017,9 @@ msgstr "1 Änderung" msgid "1 row" msgstr "1 Zeile" +msgid "1 rule" +msgstr "1 Regel" + msgid "1 year" msgstr "1 Jahr" @@ -1188,6 +1207,27 @@ msgstr "95. Perzentil" msgid "99th percentile" msgstr "99. Perzentil" +msgid "< Remove" +msgstr "< Entfernen" + +msgid "<< Remove all" +msgstr "<< Alle entfernen" + +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Piggyback-" +"Übersetzungen werden durchgeführt, bevor der Piggyback-Connector Hosts " +"erstellt. Verwenden Sie dies z.B. in einem Setup mit mehreren Docker-Knoten, " +"um Containern den Namen des entsprechenden Docker-Knotens voranzustellen. " +"Andernfalls kann es zu Namenskollisionen kommen, wenn Container mit " +"demselben Namen auf mehr als einem Docker-Knoten vorhanden sind." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Hinweis3: Um dieses Plugin auf Solaris zu verteilen, ist " -"eine Python 3.4-Installation (oder neuer) mit installierten Python-Paketen " -"\"pyOpenSSL\", \"requests\" und \"PySocks\" auf den Zielhosts erforderlich." +"eine Python 3.7-Installation (oder neuer) mit installierten Python-Paketen " +"\"pyOpenSSL\", \"requests\" und \"PySocks\" auf den Ziel-Hosts erforderlich." #, python-format msgid "" @@ -1358,6 +1398,16 @@ msgstr "Warnung: Es gibt %d unquittierte Werks:" msgid "You do not have any roles." msgstr "Sie haben keine Rollen." +msgid "" +"

Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" +"

Wichtiger Hinweis: Wenn Sie diese Option ändern, müssen " +"die Services entfernt und neu erkannt werden, um die Änderungen zu " +"übernehmen. Andernfalls besteht die Gefahr, dass die ermittelten und die " +"geprüften Services nicht übereinstimmen." + msgid "" "
HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1936,14 +1986,15 @@ msgstr "" "Zu nutzender TNS_ADMIN für sqlnet.ora und tnsnames." "ora %s" +#, fuzzy msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" "robot.yaml ist die Haupt-RCC-Konfigurationsdatei. Sie wird relativ " -"zum Basisverzeichnis der Robot Framework-Projekte angegeben. Diese Datei " +"zum Basisverzeichnis der Robot Framework Projekte angegeben. Diese Datei " "verweist auch auf die Datei conda.yaml, in der alle " "Umgebungsabhängigkeiten aufgeführt sind. " @@ -2121,6 +2172,14 @@ msgstr "Eine Überschrift für die Graphen" msgid "A heading for the view" msgstr "Eine Überschrift für die Ansicht" +#, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Ein Host mit dem Namen %s existiert bereits im Ordner %s. Bitte wählen Sie " +"einen anderen Host-Namen." + #, python-format msgid "" "A host with the name %s already exists in the folder
" +msgstr "Hinzufügen >" + msgid "Add Aggregation" msgstr "Aggregation hinzufügen" @@ -3572,10 +3648,6 @@ msgstr "Ausnahme ergänzen" msgid "Add Group" msgstr "Gruppe hinzufügen" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"HTML-Abschnitt über der Tabelle hinzufügen (z. B. Titel, Beschreibung...)" - msgid "Add LDAP connection" msgstr "LDAP-Verbindung hinzufügen" @@ -3621,6 +3693,9 @@ msgstr "Aggregation hinzufügen" msgid "Add alert handler rule" msgstr "Ereignisbehandlungsregel hinzufügen" +msgid "Add all >>" +msgstr "Alle hinzufügen >>" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Alle erkannten, aber noch nicht überwachten Services dem Monitoring " @@ -3722,6 +3797,9 @@ msgstr "Element hinzufügen: %s" msgid "Add elements to your sidebar" msgstr "Elemente zur Ihrer Seitenleiste hinzufügen" +msgid "Add event" +msgstr "Ereignis hinzufügen" + msgid "Add exception" msgstr "Ausnahme hinzufügen" @@ -3909,6 +3987,10 @@ msgstr "Neue Knoten-Bedingung hinzufügen" msgid "Add new pattern" msgstr "Neues Muster hinzufügen" +#, fuzzy +msgid "Add new plan" +msgstr "Neues Muster hinzufügen" + msgid "Add new project" msgstr "Neues Projekt hinzufügen" @@ -3924,9 +4006,16 @@ msgstr "Neue Regel hinzufügen" msgid "Add new scalar" msgstr "Neue Konstante hinzufügen" +#, fuzzy +msgid "Add new sequence" +msgstr "Neuen Service hinzufügen" + msgid "Add new service" msgstr "Neuen Service hinzufügen" +msgid "Add new smarthost" +msgstr "Neuen Smarthost hinzufügen" + msgid "Add new status" msgstr "Neuen Status hinzufügen" @@ -3967,6 +4056,9 @@ msgstr "Ausführbare Befehle ergänzen oder ändern" msgid "Add page element" msgstr "Seitenelement hinzufügen" +msgid "Add parameter" +msgstr "Parameter hinzufügen" + msgid "Add pattern" msgstr "Muster hinzufügen" @@ -3989,6 +4081,9 @@ msgstr "Prä- oder Postfix zu TNSALIASes %s hinzufügen" msgid "Add random hosts" msgstr "Zufälligen Hosts hinzufügen" +msgid "Add recipient" +msgstr "Empfänger hinzufügen" + msgid "Add remote instance" msgstr "Remote-Instanz hinzufügen" @@ -4233,6 +4328,9 @@ msgid "Additional agent labels to send during registration" msgstr "" "Zusätzliche Agenten-Labels, die bei der Registrierung zu versenden sind" +msgid "Additional details" +msgstr "Zusätzliche Details" + msgid "Additional header lines" msgstr "Zusätzliche Headerzeilen" @@ -4352,8 +4450,8 @@ msgstr "Admin-Status" msgid "Admin states to discover" msgstr "Admin-Status, die erkannt werden sollen" -msgid "Administrate managed robots" -msgstr "Administriere verwaltete Roboter" +msgid "Administrate robots" +msgstr "Roboter verwalten" msgid "Administrative port states to discover" msgstr "Administrative Port-Status, die erkannt werden sollen" @@ -5008,6 +5106,9 @@ msgstr "" msgid "Alert handler configuration" msgstr "Alert Handler-Konfiguration" +msgid "Alert handler execution" +msgstr "Alert Handler-Ausführung" + msgid "Alert handler execution, failed" msgstr "Alert Handler-Ausführung, gescheitert" @@ -5114,6 +5215,15 @@ msgstr "Alarmstatistik: Anzahl von unbekannten Alarmen" msgid "Alert statistics: Number of warnings" msgstr "Alarmstatistik: Anzahl von Warnungen" +msgid "Alert when a major version release is available" +msgstr "Alert, wenn eine neue Hauptversion verfügbar ist" + +msgid "Alert when a minor version release is available" +msgstr "Alert, wenn eine neue Unterversion verfügbar ist" + +msgid "Alert when a patch version release is available" +msgstr "Alert, wenn eine neue Patch-Version verfügbar ist" + msgid "Alerted" msgstr "Alarmiert" @@ -5218,6 +5328,9 @@ msgstr "Alle Sammlungen" msgid "All components" msgstr "Alle Komponenten" +msgid "All contacts of the affected object" +msgstr "Alle Kontakte des betroffenen Objektes" + msgid "All contacts of the notified object" msgstr "Alle Kontakte des alarmierten Objektes" @@ -5642,6 +5755,9 @@ msgstr "Erlaubt die Anzeige des Symbols %s in der Host- und Service-Ansicht" msgid "Allow unencrypted legacy communication" msgstr "Unverschlüsselte Legacy-Kommunikation zulassen" +msgid "Allow users to deactivate this notification" +msgstr "Benutzern erlauben, diese Benachrichtigung zu deaktivieren" + msgid "Allowed Ciphers" msgstr "Erlaubte Ciphern" @@ -6237,6 +6353,9 @@ msgstr "Eine andere Usersynchronisation läuft gerade: %s" msgid "AntiVirus last update age" msgstr "Alter des letzten AntiVirus-Updates" +msgid "Any" +msgstr "Beliebig" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6413,9 +6532,18 @@ msgstr "Anwendungsübersicht" msgid "Applications, Processes & Services" msgstr "Anwendungen, Prozesse & Services" +msgid "Applied to" +msgstr "Angewendet auf" + msgid "Apply" msgstr "Anwenden" +msgid "Apply & create another rule" +msgstr "Anwenden & weitere Regel erstellen" + +msgid "Apply & test notification rule" +msgstr "Anwenden & Benachrichtigungsregel testen" + msgid "Apply Latency" msgstr "Latenz anwenden" @@ -6437,6 +6565,13 @@ msgstr "Bedingungen anwenden" msgid "Apply filters" msgstr "Filter anwenden" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" +"Nutzen Sie Filter, um festzulegen, welche Hosts und Services von dieser " +"Benachrichtigungsregel betroffen sind." + msgid "Apply finish time" msgstr "Endzeit der Anwendung" @@ -6510,7 +6645,7 @@ msgstr "" msgid "Apply this rule only to interfaces whose port state is listed below." msgstr "" -"Wende diese Regel nur bei Interfaces an, deren Port Status unten gelistet " +"Wende diese Regel nur bei Schnittstellen an, deren Portstatus unten gelistet " "ist." msgid "Apply this rule only to interfaces whose port type is listed below." @@ -6563,6 +6698,9 @@ msgstr "Aktuelles Audit-Log archivieren" msgid "Archive event" msgstr "Ereignis archivieren" +msgid "Archive event?" +msgstr "Ereignis archivieren?" + msgid "Archive events" msgstr "Ereignisse archivieren" @@ -6703,6 +6841,13 @@ msgstr "" "Erstellte Ausgaben einem definierten Benutzer zuordnen. Dies ist der " "Benutzername des Benutzers (keine E-Mail)." +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" +"Weisen Sie der App Berechtigungen zu: Erteilen Sie die erforderlichen " +"Zugriffsrechte, indem Sie die Rolle \"Leser\" zuweisen." + msgid "Assign plan/test result to piggyback host" msgstr "Plan-/Test-Ergebnis einem Piggyback-Host zuweisen" @@ -7052,7 +7197,7 @@ msgid "Author: " msgstr "Autor: " msgid "Authority" -msgstr "Behörde" +msgstr "Einrichtung" msgid "Authorization" msgstr "Authorisation" @@ -7130,10 +7275,10 @@ msgstr "Automatisch erweiterbar" msgid "Automated environment setup (via RCC)" msgstr "Automatisierte Einrichtung der Umgebung (über RCC)" -#, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "" "Automatisierte Einrichtung der Umgebung (über RCC, %s, da Robotmk-Kern-MKP " "installiert ist)" @@ -8106,7 +8251,7 @@ msgid "BI Pack Properties" msgstr "BI Paketeingenschaften" msgid "BI Visualization" -msgstr "BI Visualisierung" +msgstr "BI-Visualisierung" msgid "BI aggregation groups" msgstr "BI Aggregationsgruppen" @@ -8336,6 +8481,9 @@ msgstr "Gebackene Agenten" msgid "Baked host specific agent" msgstr "Gebackener Host-spezifischer Agent" +msgid "Bakery rules" +msgstr "Bäckereiregeln" + msgid "Baking Agents..." msgstr "Backe Agenten..." @@ -8403,7 +8551,7 @@ msgid "Base directory for variable data (caches, state files)" msgstr "Basisverzeichnis für variable Daten (Caches, Zustandsdateien)" msgid "Base directory of Robot Framework projects" -msgstr "Basisverzeichnis des Robot Framework Projektes" +msgstr "Basisverzeichnis der Robot Framework Projekte" msgid "Base layout" msgstr "Grundlayout" @@ -8651,7 +8799,7 @@ msgid "Bold" msgstr "Fett" msgid "Bonding interfaces" -msgstr "Bonding-Schnittstelle" +msgstr "Bonding-Schnittstellen" msgid "Bookmark list" msgstr "Lesezeichenliste" @@ -8711,7 +8859,7 @@ msgid "Broadcast/Multicast" msgstr "Broadcast/Multicast" msgid "Broadcom bonding network interface on Windows" -msgstr "Broadcom Bonding-Netwerkgeräte unter Windows" +msgstr "Broadcom Bonding-Netzwerkschnittstelle unter Windows" msgid "Brocade FibreChannel ports" msgstr "Brocade FC FibreChannel Ports" @@ -8853,8 +9001,8 @@ msgstr "Host Sammel-Import" msgid "Bulk move" msgstr "Sammelverschiebung" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Sammelbenachrichtigungen mit Graphen (Standard: 5)" +msgid "Bulk notifications" +msgstr "Sammelbenachrichtigungen" msgid "Bulk removal of explicit attributes" msgstr "Massenentfernung von expliziten Attributen" @@ -9208,14 +9356,6 @@ msgstr "" "Anmeldeinformationen anzupassen, die bei der Kontaktaufnahme mit Hosts über " "SNMP verwendet werden." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Normalerweise werden mehrfach-Graphen in Emails ja nach Platz nebeneinander " -"oder untereinander dargestellt. Mit dieser Option können Sie eine " -"Darstellung untereinander erzwingen." - msgid "By default all of the sections will be executed." msgstr "Standardmäßig werden alle Sektionen ausgeführt." @@ -9400,6 +9540,7 @@ msgstr "" "erzwingen.
Zusätzlich können Sie einen Befehl angeben, der für die " "Ausführung des Python-Plugins verwendet wird." +#, fuzzy msgid "" "By default, Robot Framework will execute every test.
But sometimes " "tests are interdependent - in the event of a failed login, for example, it " @@ -9407,14 +9548,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

" -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
See also \"
How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
See also " +"\"How to stop a suite when the first test fails\". " msgstr "" "Standardmäßig führt Robot Framework jeden Test aus.
Aber manchmal " "sind Tests voneinander abhängig - im Falle eines fehlgeschlagenen Login ist " @@ -9433,13 +9574,14 @@ msgstr "" "target=\"_blank\">Anhalten einer Suite, wenn der erste Test fehlschlägt" "\". " +#, fuzzy msgid "" "By default, Robotmk executes all plans in the user context of the Checkmk " "agent, which does not have access to the desktop of the Windows computer. To " "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" "Standardmäßig führt Robotmk alle Pläne im Benutzerkontext des Checkmk-" "Agenten aus, der keinen Zugriff auf den Desktop des Windows-Computers hat. " @@ -9712,10 +9854,11 @@ msgstr "" msgid "Bypass Proxy for certain hosts" msgstr "Umgehung des Proxys für bestimmte Hosts" +#, fuzzy msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -10940,6 +11083,9 @@ msgstr "LDAP-Verbindung %s geändert" msgid "Changed alert handler rule %d" msgstr "Alert Handler-Regel %d geändert" +msgid "Changed by" +msgstr "Geändert durch" + msgid "Changed entries" msgstr "Geänderte Einträge" @@ -10955,6 +11101,14 @@ msgstr[1] "Geänderte Host-Label: " msgid "Changed host selection has been saved." msgstr "Geänderte Host-Auswahl wurde gespeichert." +#, python-format +msgid "Changed notification parameter %d" +msgstr "Benachrichtigungsparameter %d geändert" + +#, python-format +msgid "Changed notification parameter %s" +msgstr "Parameter für Benachrichtigung %s geändert" + #, python-format msgid "Changed notification rule %d" msgstr "Benachrichtigungsregel %d geändert" @@ -10974,6 +11128,10 @@ msgstr "Position von %s auf %d gesetzt" msgid "Changed position of connection %s to %d" msgstr "Position der Verbindung %s auf %d gesetzt" +#, python-format +msgid "Changed position of notification parameter %d" +msgstr "Position des Parameters für Benachrichtigung %d geändert" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "Position von Benachrichtigungsregel %d von Benutzer %s geändert" @@ -11028,6 +11186,9 @@ msgstr "Instanzspezifische Konfigurationsvariable %s nach %s geändert." msgid "Changes" msgstr "Änderung(en)" +msgid "Changes activated" +msgstr "Änderungen aktiviert" + msgid "Changes since last dump" msgstr "Anzahl der Änderungen seit dem letzten Dump" @@ -11849,10 +12010,10 @@ msgstr "" "Element)" msgid "Child time in system space" -msgstr "CPU-Zeit von Kindprozessen im Kernel" +msgstr "Child-Zeit im Systembereich" msgid "Child time in user space" -msgstr "CPU-Zeit von Kindprozessen im Userspace" +msgstr "Child-Zeit im Benutzerbereich" msgid "China" msgstr "China" @@ -11953,8 +12114,8 @@ msgid "" "the check netapp_api_if." msgstr "" "Wählen Sie das Verhalten für unterschiedliche " -"Schnittstellengeschwindigkeiten in Interface-Gruppen. Die Voreinstellung ist " -"\"Check and WARN\". Diese Funktion wird derzeit nur von dem Check " +"Schnittstellengeschwindigkeiten in Schnittstellengruppen. Die Voreinstellung " +"ist \"Check and WARN\". Diese Funktion wird derzeit nur von dem Check " "netapp_api_if unterstützt." msgid "" @@ -11963,8 +12124,8 @@ msgid "" "currently only supported by the check netapp_api_if." msgstr "" "Wählen Sie das Verhalten für unterschiedliche " -"Schnittstellengeschwindigkeiten in Interface-Gruppen. Die Voreinstellung ist " -"\"Check and Display\". Diese Funktion wird derzeit nur von dem Check " +"Schnittstellengeschwindigkeiten in Schnittstellengruppen. Die Voreinstellung " +"ist \"Check and Display\". Diese Funktion wird derzeit nur von dem Check " "netapp_api_if unterstützt." msgid "Choose the connector, the user(s) should be migrated to." @@ -12284,6 +12445,13 @@ msgstr "" "Klicken Sie auf 'Registriere %s' um die Zwei-Faktor-Authentifizierung über " "%s zu aktivieren." +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" +"Klicken Sie auf die Schaltfläche \"Konfiguration hinzufügen\", um mit dem " +"Einrichten Ihrer ersten Konfiguration zu beginnen." + msgid "Click to toggle this setting" msgstr "Klicken, um Einstellung sofort umzuschalten" @@ -12299,7 +12467,7 @@ msgid "Client" msgstr "Kunde" msgid "Client Contacted Services" -msgstr "Client Contacted Services" +msgstr "Services, die vom Client kontaktiert wurden" msgid "Client ID" msgstr "Kunden ID" @@ -12329,7 +12497,7 @@ msgid "Client connects for 5 Ghz band" msgstr "5 Ghz-Band Client-Verbindungen" msgid "Client name" -msgstr "" +msgstr "Name des Kunden" msgid "Client requests received" msgstr "Client-Anfrage erhalten" @@ -12441,6 +12609,9 @@ msgstr "Klonen Sie diese Verbindung, um eine neue Verbindung zu erstellen" msgid "Clone this element" msgstr "Dieses Element klonen" +msgid "Clone this managed robot" +msgstr "Diesen verwalteten Roboter klonen" + msgid "Clone this metric" msgstr "Diese Metrik klonen" @@ -12979,6 +13150,9 @@ msgstr "Wiederherstellung fertigstellen" msgid "Complete tree" msgstr "Vollständiger Baum" +msgid "Complete variable list" +msgstr "Vollständige Variablenliste" + msgid "Complete variable list (for testing)" msgstr "Vollständige Variablenliste (für Tests)" @@ -13122,6 +13296,9 @@ msgstr "Konfigurationsdateien ('*.mk' oder '*.conf') aus etc/checkmk: %s" msgid "Configuration generation" msgstr "Konfigurationserzeugung" +msgid "Configuration name" +msgstr "Konfigurationsname" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Konfiguration von Checkmk's Business Intelligence Modul" @@ -13188,6 +13365,9 @@ msgstr "Konfiguriere" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Amazon Web Service (AWS) Monitoring in Checkmk konfigurieren" +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Microsoft Azure Monitoring in Checkmk konfigurieren" + msgid "Configure SNMP related settings using rulesets" msgstr "Konfigurieren Sie SNMP-bezogene Einstellungen mithilfe von Regelsätzen" @@ -13239,7 +13419,7 @@ msgid "Configure custom agent file deployments" msgstr "Benutzerdefinierte Agentendatei-Verteilung konfigurieren" msgid "Configure discovery of single interfaces" -msgstr "Konfiguriere die Erkennung von Einzel-Interfaces" +msgstr "Konfiguriere die Erkennung von Einzel-Schnittstellen" msgid "Configure enforced checks without using service discovery" msgstr "Konfiguriere forcierte Checks, ohne die Service-Erkennung zu benutzen" @@ -13248,7 +13428,10 @@ msgid "Configure fallback email address" msgstr "Fallback-E-Mail-Adresse konfigurieren" msgid "Configure grouping of interfaces" -msgstr "Konfiguriere die Gruppierung von Interfaces" +msgstr "Konfiguriere die Gruppierung von Schnittstellen" + +msgid "Configure host and authority" +msgstr "Host und Einrichtung konfigurieren" msgid "Configure host and regions" msgstr "Host und Regionen konfigurieren" @@ -13470,6 +13653,9 @@ msgstr "" "Konfigurieren Sie den Namen der HTTP-Request-Header-Variablen, die aus den " "eingehenden HTTP-Requests gelesen werden soll" +msgid "Configure the number of expected interfaces" +msgstr "Konfiguriere die Anzahl erwarteter Schnittstellen" + #, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13500,19 +13686,6 @@ msgstr "" "erhalten soll, indem Sie hier den Benutzer- oder Gruppenschlüssel eintragen. " "Der Schlüssel ist von der Pushover-Website erhältlich." -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Aktivieren Sie dies damit das Benachrichtigungs-Plugin sich direkt mit dem " -"SMTP-Server verbindet. Dies hat den Vorteil, dass im Fehlerfall bessere " -"Fehlermeldungen ausgegeben werden, erfordert aber mehr Konfiguration und ist " -"streng synchron. Wir raten daher, diese Option nur bei Enterprise-" -"Installationen zu verwenden, die den Benachrichtigungs-Spooler nutzen." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -13914,6 +14087,9 @@ msgstr "Kontakt" msgid "Contact Name" msgstr "Kontaktname" +msgid "Contact group" +msgstr "Kontaktgruppe" + msgid "Contact group (effective)" msgstr "Kontakgruppe (effektiv)" @@ -14064,6 +14240,9 @@ msgstr "Kontextinformation" msgid "Context information about this connection" msgstr "Kontextinformation zu dieser Verbindung" +msgid "Context information about this parameter" +msgstr "Kontextinformationen zu diesem Parameter" + msgid "Context information about this rule" msgstr "Kontext zu dieser Regel" @@ -14310,6 +14489,13 @@ msgstr "Couchbase-vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase-Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" +"Der Zugriff auf Ihr AWS-Konto war nicht möglich. Bitte überprüfen Sie Ihren " +"Zugangs- und Geheimschlüssel und versuchen Sie es erneut." + #, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -14349,6 +14535,8 @@ msgstr "Aktuelles Theme konnte nicht festgelegt werden." msgid "" "Could not find a running service discovery for host %s on remote site %s" msgstr "" +"Es konnte keine laufende Service-Erkennung für den Host %s auf der Remote-" +"Instanz %s gefunden werden" #, python-format msgid "Could not find an entry matching %r in choices" @@ -14599,6 +14787,9 @@ msgstr "Diese Verbindung kopieren" msgid "Create a copy of this group" msgstr "Kopiere diese Gruppe" +msgid "Create a copy of this notification parameter" +msgstr "Eine Kopie dieses Benachrichtigungsparameters erstellen" + msgid "Create a copy of this notification rule" msgstr "Eine Kopie dieser Benachrichtigungsregel erstellen" @@ -14679,6 +14870,13 @@ msgstr "Zusätzlichen Service für IO-Stats-Anfragen erstellen" msgid "Create additional service for system wait" msgstr "Zusätzlichen Service für System Wait erstellen" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" +"Erstellen Sie eine Azure-App für Checkmk: Registrieren Sie die App im Azure " +"Active Directory und merken Sie sich die Anwendungs-ID." + msgid "Create an annotation for this period" msgstr "Eine Anmerkung für diese Zeitspanne erzeugen" @@ -14788,6 +14986,9 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Für diesen Bericht einen Eintrag im Berichtsplaner erstellen" +msgid "Create robot" +msgstr "Roboter erstellen" + msgid "Create separate notification bulks based on" msgstr "Separate Sammelbenachrichtigungen erzeugen basierend auf" @@ -14887,6 +15088,9 @@ msgstr "Neuen Host %s erzeugt." msgid "Created new host tag group '%s'" msgstr "Neue Hostmerkmal-Gruppe '%s' erzeugt" +msgid "Created new notification parameter" +msgstr "Neuer Benachrichtigungsparameter wurde erstellt" + msgid "Created new notification rule" msgstr "Neue Benachrichtigungsregel wurde erstellt" @@ -15323,6 +15527,9 @@ msgstr "Benutzerdefiniertes GUI-Design von %s" msgid "Custom Graph" msgstr "Benutzerdefinierter Graph" +msgid "Custom HTML section (e.g. title, description…)" +msgstr "Benutzerdefinierte HTML-Sektion (z. B. Titel, Beschreibung...)" + msgid "Custom Icons" msgstr "Benutzericons" @@ -15425,6 +15632,12 @@ msgstr "Angepasste Lokalisierungen" msgid "Custom logos" msgstr "Benutzerdefinierte Logos" +msgid "Custom macro" +msgstr "Benutzerdefiniertes Makro" + +msgid "Custom macros" +msgstr "Benutzerdefinierte Makros" + #, python-format msgid "Custom notification table for user %s" msgstr "Benutzerdefinierte Benachrichtigungstabelle von Benutzer %s" @@ -15438,9 +15651,15 @@ msgstr "Individueller Zustand der Messung" msgid "Custom profile" msgstr "Benutzerdefiniertes Profil" +msgid "Custom recipient of \"Reply to\"" +msgstr "Benutzerdefinierter Empfänger von \"Antworten an\"" + msgid "Custom search query" msgstr "Benutzerdefinierte Suchabfrage" +msgid "Custom sender (\"From\")" +msgstr "Benutzerdefinierter Absender (\"Von\")" + msgid "Custom service attributes" msgstr "Benutzerdefinierte Serviceattribute" @@ -15853,13 +16072,13 @@ msgstr "" "Daemon Zustand und Zusammenfassung der Containeranzahl und ihrer Zustände" msgid "Daemon threads" -msgstr "Daemon-Threads" +msgstr "Daemon Threads" msgid "DaemonSet" msgstr "DaemonSet" msgid "DaemonSet problems" -msgstr "DaemonSet-Probleme" +msgstr "DaemonSet Probleme" msgid "DaemonSets" msgstr "DaemonSets" @@ -16183,7 +16402,7 @@ msgid "Datastore name" msgstr "Name des Datenspeichers" msgid "Datastores" -msgstr "Datastores" +msgstr "Datenspeicher" msgid "Datatype" msgstr "Datentyp" @@ -16249,9 +16468,6 @@ msgstr "Tagesrate" msgid "Days" msgstr "Tage" -msgid "Deactivate" -msgstr "Deaktiviert" - msgid "Deactivated" msgstr "Deaktiviert" @@ -16423,7 +16639,7 @@ msgid "Default credentials" msgstr "Standard-Zugangsdaten" msgid "Default dynamic visuals permission" -msgstr "" +msgstr "Standard-Berechtigung für dynamische Anzeigeobjekte" msgid "Default expiration time (relative)" msgstr "Standard-Verfallsdatum (relativ)" @@ -16478,6 +16694,12 @@ msgid "" "dynamic visuals by default. Note: Applying this setting will cause a reload " "of apache." msgstr "" +"Standardberechtigung für dynamische Anzeigeobjekte (Dashboards, " +"Tabellenansichten usw.). Bei der Einstellung \"ja\" haben alle Rollen " +"(einschließlich mitgelieferter Rollen) standardmäßig die Berechtigung zum " +"Ansehen von dynamischen Anzeigeobjekten. Bei der Einstellung \"nein\" kann " +"nur die Administratorrolle standardmäßig dynamische Grafiken ansehen. " +"Hinweis: Das Anwenden dieser Einstellung führt zu einem Neuladen von Apache." msgid "Default profile" msgstr "Standard-Profil" @@ -16534,6 +16756,9 @@ msgstr "Standard Benutzerprofil" msgid "Default value" msgstr "Standardwert" +msgid "Defaults to 'https' when not provided." +msgstr "Standardmäßig wird 'https' verwendet, wenn nicht angegeben." + msgid "Deferred files age" msgstr "Alter der aufgeschobenen Dateien" @@ -16588,6 +16813,9 @@ msgstr "" "Zuständen, sprich in das Ergebnis des Checks. Damit überschreiben Sie die " "von Check standardmäßig verwendete Zuordnung." +msgid "Define any events you want to be notified about." +msgstr "" + msgid "Define host assignment" msgstr "Host-Zuweisung festlegen" @@ -16626,6 +16854,9 @@ msgstr "Definieren Sie die Untergrenzen für die Anzahl der wartenden Container" msgid "Define name of NetBIOS server" msgstr "Name des NetBIOS-Servers festlegen" +msgid "Define parameters for HTML mail" +msgstr "Parameter für HTML-E-Mails definieren" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -16868,6 +17099,9 @@ msgstr "Backup-Schlüssel #%d löschen" msgid "Delete comments" msgstr "Kommentare löschen" +msgid "Delete comments?" +msgstr "Kommentare löschen?" + #, python-format msgid "Delete configuration %s" msgstr "entferne Konfiguration %s" @@ -16936,6 +17170,13 @@ msgstr "Prozess #%d löschen" msgid "Delete last alert handler rule" msgstr "Letzte Alert Handler-Regel löschen" +msgid "Delete managed robot" +msgstr "Verwalteten Roboter löschen" + +#, python-format +msgid "Delete notification parameter #%d" +msgstr "Benachrichtigungsparameter #%d löschen" + #, python-format msgid "Delete notification rule #%d" msgstr "Benachrichtigungsregel #%d löschen" @@ -17087,9 +17328,15 @@ msgstr "Diesen Schlüssel löschen" msgid "Delete this logo" msgstr "Dieses Logo löschen" +msgid "Delete this managed robot" +msgstr "Lösche diesen verwalteten Roboter" + msgid "Delete this metric" msgstr "Diese Metrik löschen" +msgid "Delete this notification parameter" +msgstr "Diesen Benachrichtigungsparameter löschen" + msgid "Delete this notification rule" msgstr "Diese Benachrichtigungsregel löschen" @@ -17187,6 +17434,10 @@ msgstr "Ordner %s gelöscht" msgid "Deleted host %s" msgstr "Host %s gelöscht" +#, python-format +msgid "Deleted notification parameter %d" +msgstr "Benachrichtigungsparameter #%d wurde gelöscht" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Benachrichtigungsregel %d von Benutzer %s gelöscht" @@ -17708,7 +17959,7 @@ msgid "Detect instances" msgstr "Instanzen erkennen" msgid "Detect network parent hosts" -msgstr "Erkenne Netzwerk-Parent-Hosts" +msgstr "Erkenne Netzwerk-Parent Hosts" msgid "Detect network parents" msgstr "Netzwerk-Parents erkennen" @@ -17723,8 +17974,9 @@ msgid "" "Determine whether the group interface is created as an separate service or " "not. In second case the choosen interface services disapear." msgstr "" -"Bestimme hier, ob das Gruppeninterface als separater Service erstellt werden " -"soll oder nicht. Im zweiten Fall verschwinden die Interfaceservices." +"Bestimme hier, ob die Gruppenschnittstelle als separater Service erstellt " +"werden soll oder nicht. Im zweiten Fall verschwinden die " +"Schnittstellenservices." #, python-format msgid "" @@ -18045,6 +18297,9 @@ msgstr "Proxy-Unterstützung deaktivieren" msgid "Disable remote configuration" msgstr "Remote-Konfiguration deaktivieren" +msgid "Disable rule" +msgstr "Regel deaktivieren" + msgid "Disable service notifications" msgstr "Schalte Service-Benachrichtigungen ab" @@ -18166,7 +18421,7 @@ msgid "Discover services during creation" msgstr "Erkennen von Services während der Erstellung" msgid "Discover single interfaces" -msgstr "Erkenne einzelne Interfaces" +msgstr "Erkenne einzelne Schnittstellen" msgid "Discovered host label synchronization" msgstr "Synchronisation entdeckter (Host-) label" @@ -18230,7 +18485,7 @@ msgid "Disk ID" msgstr "Platten-ID" msgid "Disk IO" -msgstr "Disk IO" +msgstr "Festplatten-E/A" msgid "Disk IO discovery" msgstr "Erkennung Disk-IO" @@ -18408,9 +18663,6 @@ msgstr "" "Es wird eine Warung ausgegeben, wenn eine LUN nicht read-only ist. Ohne " "diese Option wird eine Warnung ausgegeben, wenn eine LUN read-only ist." -msgid "Display additional information" -msgstr "Ergänzende Informationen anzeigen" - msgid "Display additional messages" msgstr "Zusätzliche Meldungen anzeigen" @@ -18435,9 +18687,6 @@ msgstr "" msgid "Display dashboard title" msgstr "Dashboard-Titel anzeigen" -msgid "Display graphs among each other" -msgstr "Graphen untereinander darstellen" - msgid "Display historic data since the last" msgstr "Historische Daten anzeigen für die letzten" @@ -18915,7 +19164,7 @@ msgid "Do not deploy plug-in for Windows broadcom bonding" msgstr "Plugin für Windows Broadcom-Bonding nicht verteilen" msgid "Do not deploy plug-in for Windows interfaces" -msgstr "Plugin für Windows Interfaces nicht verteilen" +msgstr "Plugin für Windows Schnittstellen nicht verteilen" msgid "Do not deploy remote desktop licenses plug-in" msgstr "Plugin für Remote-Desktop-Lizenzen nicht verteilen" @@ -19018,7 +19267,7 @@ msgid "Do not discover" msgstr "Nicht suchen" msgid "Do not discover single interfaces" -msgstr "Einzelne Interfaces nicht erkennen" +msgstr "Einzelne Schnittstellen nicht erkennen" msgid "Do not display a date" msgstr "Kein Datum anzeigen" @@ -19081,7 +19330,7 @@ msgid "Do not group indices" msgstr "Indices nicht gruppieren" msgid "Do not group interfaces" -msgstr "Interfaces nicht gruppieren" +msgstr "Schnittstellen nicht gruppieren" msgid "Do not impose levels" msgstr "Keine Level anwenden" @@ -19213,7 +19462,7 @@ msgstr "" "Neustart des Monitoring-Kerns und blockiert %s bis zur nächsten Aktivierung!" msgid "Do you really want to switch the event daemon mode?" -msgstr "Wollen Sie den Modus des Ereignis Daemon wirklich umschalten?" +msgstr "Wollen Sie den Modus des Event Daemon wirklich umschalten?" msgid "Docker containers" msgstr "Docker Container" @@ -19251,6 +19500,9 @@ msgstr "Dokument Count-Delta" msgid "Document count growth per minute" msgstr "Zuwachs der Dokumentenanzahl pro Minute zählen" +msgid "Documentation" +msgstr "Dokumentation" + msgid "Documentation URL" msgstr "URL zur Dokumentation" @@ -20041,6 +20293,10 @@ msgstr "Bearbeiten" msgid "Edit %s" msgstr "%s bearbeiten" +#, python-format +msgid "Edit %s notification parameter %s" +msgstr "%s Parameter für Benachrichtigung %s bearbeiten" + #, python-format msgid "Edit %s: %s" msgstr "Bearbeiten %s: %s" @@ -20188,6 +20444,9 @@ msgstr "Layout bearbeiten" msgid "Edit layout only available if header is enabled" msgstr "Layout bearbeiten ist nur verfügbar, wenn der Header aktiviert ist" +msgid "Edit managed robots" +msgstr "Verwaltete Roboter bearbeiten" + #, python-format msgid "Edit message broker connection %s" msgstr "Message Broker-Verbindung %s bearbeiten" @@ -20345,6 +20604,12 @@ msgstr "Dieses Element bearbeiten" msgid "Edit this host" msgstr "Diesen Host bearbeiten" +msgid "Edit this managed robot" +msgstr "Diesen verwalteten Roboter bearbeiten" + +msgid "Edit this notification parameter" +msgstr "Diesen Benachrichtigungsparameter bearbeiten" + msgid "Edit this notification rule" msgstr "Diese Benachrichtigungsregel bearbeiten" @@ -20416,6 +20681,9 @@ msgstr "Benutzerprofil des Benutzers %s bearbeitet" msgid "Edition" msgstr "Edition" +msgid "Effect" +msgstr "Wirkung" + msgid "Effective State" msgstr "Effektiver Zustand" @@ -20603,6 +20871,12 @@ msgstr "E-Mail-Adresse, die zur Kontoidentifizierung verwendet wird" msgid "Email addresses to mail PDF reports to" msgstr "E-Mail-Adressen, an welche die PDF-Berichte gemailt werden sollen" +msgid "Email body/content" +msgstr "E-Mail-Text/Inhalt" + +msgid "Email header" +msgstr "E-Mail-Kopfzeile" + msgid "Email sent" msgstr "E-Mail gesendet" @@ -20649,7 +20923,7 @@ msgid "Empty response from web service" msgstr "Leere Antwort vom Webdienst" msgid "Empty template for least privilege roles" -msgstr "" +msgstr "Leere Vorlage für Rollen mit geringsten Rechten" msgid "Enable" msgstr "Einschalten" @@ -20960,13 +21234,13 @@ msgid "Enc-Outs" msgstr "Enc-Outs" msgid "Enclosure ID" -msgstr "Enclosure ID" +msgstr "Anhang-ID" msgid "Enclosure Stats" msgstr "Enclosure-Statistiken" msgid "Enclosures" -msgstr "Enclosures" +msgstr "Anhänge" msgid "Encoder utilization" msgstr "Encoder-Auslastung" @@ -21576,7 +21850,7 @@ msgid "Event Console: SNMP traps" msgstr "Event Console: SNMP-Traps" msgid "Event Daemon is running." -msgstr "Ereignis Daemon läuft." +msgstr "Event Daemon läuft." msgid "Event History" msgstr "Ereignishistorie" @@ -21599,6 +21873,9 @@ msgstr "Ereigniskommentar" msgid "Event console" msgstr "Event Console" +msgid "Event console alerts" +msgstr "Alarme der Event Console" + msgid "Event console performance" msgstr "Leistung der Event Console" @@ -22051,7 +22328,7 @@ msgid "Execution time of Checkmk Agent" msgstr "Ausführungszeit des Checkmk-Agenten" msgid "Executive" -msgstr "Executive" +msgstr "Exekutive" msgid "Executors" msgstr "Ausführende" @@ -22775,10 +23052,6 @@ msgstr "Fehler beim Darstellen des Werts:" msgid "Failed to render value: %r" msgstr "Fehler beim Darstellen des Werts: %r" -#, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Broker-Zertifikate konnten nicht gespeichert werden: %s" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -22809,7 +23082,7 @@ msgstr "Entdeckung konnte nicht gestartet werden: %s" #, python-format msgid "Failed to start parent scan: %s" -msgstr "Eltern-Scan konnte nicht gestartet werden: %s" +msgstr "Parent-Scan konnte nicht gestartet werden: %s" #, python-format msgid "Failed to start the job: %s" @@ -22886,6 +23159,9 @@ msgstr "" "geclusterten Services. Es soll jedoch nur ein Knoten Daten senden, die " "Ergebnisse aller weiteren Knoten lösen zumindest einen WARNING-Status aus." +msgid "Failure" +msgstr "Ausfall" + msgid "Failures of the join launcher service" msgstr "Fehler im \"Join Launcher\" Dienst" @@ -23177,6 +23453,9 @@ msgstr "Dateigröße weniger als" msgid "File size levels" msgstr "Level für Dateigrößen" +msgid "File upload" +msgstr "Datei-Upload" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -23302,6 +23581,9 @@ msgstr "" "Nach allen Aggregationen filtern die auf der Statusinformation des Hosts " "basieren. Genaue Übereinstimmung - kein regulärer Ausdruck" +msgid "Filter for hosts/services" +msgstr "Filter für Hosts/Services" + msgid "Filter group (see help)" msgstr "Filtergruppe (siehe Hilfe)" @@ -23395,7 +23677,7 @@ msgid "Fireeye Security Content" msgstr "Fireeye Sicherheit Inhalt" msgid "Firewall Interfaces" -msgstr "Firewall-Netzwerkschnittstellen" +msgstr "Firewall-Schnittstellen" msgid "Firewall connections" msgstr "Firewallverbindungen" @@ -23612,7 +23894,7 @@ msgid "Font size" msgstr "Schriftgröße" msgid "Foobar-Daemon" -msgstr "Beispiel-Service" +msgstr "Foobar Daemon" msgid "" "For check_http to work with a proxy server, you will most likely " @@ -23960,6 +24242,9 @@ msgstr "Gabelungen" msgid "Form factor" msgstr "Formfaktor" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Format" @@ -24138,7 +24423,7 @@ msgid "Fragmentation" msgstr "Fragmentierung" msgid "Frames" -msgstr "Frames" +msgstr "Rahmen" msgid "Free" msgstr "Free" @@ -24578,6 +24863,13 @@ msgstr "Erzeugen" msgid "Generate REST API specification" msgstr "Erzeuge REST-API Spezifikation" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" +"Erzeugen Sie einen Schlüssel für die App: Erstellen Sie einen geheimen " +"Schlüssel in den Einstellungen der App und merken Sie ihn sich." + msgid "Generate backup codes" msgstr "Backup-Codes erzeugen" @@ -24600,7 +24892,7 @@ msgid "Generate service labels for created groups" msgstr "Erzeuge Service-Labels für erstellte Gruppen" msgid "Generate service labels for discovered interfaces" -msgstr "Erzeuge Service-Labels für erkannte Interfaces" +msgstr "Erzeuge Service-Labels für erkannte Schnittstellen" msgid "" "Generate the API token through the Purity user interface (System > Users > " @@ -24641,6 +24933,18 @@ msgstr "Generische Rate" msgid "Generic string" msgstr "Generischer String" +msgid "Gerrit" +msgstr "Gerrit" + +msgid "Gerrit Version" +msgstr "Gerrit-Version" + +msgid "Gerrit connection" +msgstr "Gerrit-Verbindung" + +msgid "Gerrit instance to query." +msgstr "Abzufragende Gerrit-Instanz." + msgid "Get file from SFTP server" msgstr "Datei von SFTP-Server holen" @@ -24698,6 +25002,9 @@ msgstr "Globale Benachrichtigungsregel" msgid "Global notification rules" msgstr "Globale Benachrichtigungsregeln" +msgid "Global services" +msgstr "Globale Services" + msgid "Global services to monitor" msgstr "Globale Dienste zur Überwachung" @@ -24723,6 +25030,9 @@ msgstr "Globbing-Muster für Eingabedateien" msgid "Go critical if all licenses are used" msgstr "Kritisch melden, wenn alle Lizenzen in Verwendung sind" +msgid "Go to \"All hosts\"" +msgstr "Gehe zu \"Alle Hosts\"" + msgid "Go to AWS root account > Services > IAM." msgstr "Gehe zu AWS-Stammkonto > Services > IAM." @@ -24735,6 +25045,15 @@ msgstr "Zur Hauptübersicht" msgid "Go to rules of this InfluxDB connection" msgstr "Zu den Regeln dieser InfluxDB-Verbindung" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" +"Gehen Sie auf die Seite Monitor > Alle Hosts oder klicken Sie auf die " +"Schaltfläche Zu allen Hosts gehen, um das Monitoring Ihrer %s Services zu " +"starten." + msgid "Go to the Saas Admin Panel" msgstr "Gehe zum Saas-Administrationsbereich" @@ -24892,18 +25211,12 @@ msgstr "Grafikkarten" msgid "Graphs" msgstr "Graphen" -msgid "Graphs are shown among each other" -msgstr "Graphen untereinander darstellen" - msgid "Graphs for averaged single-core utilizations" msgstr "Graphen für gemittelte Single-Core-Auslastungen" msgid "Graphs for individual cores" msgstr "Graphen für einzelnen Kerne" -msgid "Graphs per notification (default: 5)" -msgstr "Graphen pro Benachrichtigung (Standard: 5)" - msgid "Graylog" msgstr "Graylog" @@ -24991,9 +25304,6 @@ msgstr "Gruppen Base DN" msgid "Group discovery and activation for up to" msgstr "Gruppenerkennung und aktivierung für bis zu" -msgid "Group execution interval" -msgstr "Ausführungsintervall der Gruppe" - msgid "Group files based on a regular expression pattern." msgstr "Dateien anhand eines regulären Ausdrucks gruppieren." @@ -25176,7 +25486,7 @@ msgid "HP MSA power supply voltage levels" msgstr "HP MSA Netzteilspannungslevel" msgid "HP MSA via Web Interface" -msgstr "HP MSA via Web Interface" +msgstr "HP MSA via Web-Schnittstelle" msgid "HP Switch module state" msgstr "HP-Switch-Module: Status" @@ -25193,6 +25503,9 @@ msgstr "HPE StoreOnce via REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: Belegter Speicher über SNMP" +msgid "HTML Email parameters" +msgstr "Parameter der HTML-E-Mails" + msgid "HTML email" msgstr "HTML E-Mail" @@ -26498,6 +26811,11 @@ msgstr "Namen der Konfigurationsvariablen verstecken" msgid "Hide notification bulks" msgstr "Benachrichtigungs-Bulks ausblenden" +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "" +"Andere Empfänger ausblenden: Sende einzelne Benachrichtigungen an jeden " +"Empfänger" + msgid "Hide response from socket" msgstr "Antwort von Socket verstecken" @@ -26563,6 +26881,9 @@ msgstr "Verlauf" msgid "History Line Number" msgstr "Zeilennummer in der Historie" +msgid "History action type" +msgstr "Aktionsart für Historie" + msgid "History entries of one specific event" msgstr "Historische Einträge eines bestimmten Ereignisses" @@ -27413,7 +27734,7 @@ msgid "Horizontal spacing" msgstr "Waagerechter Abstand" msgid "Host" -msgstr "Hosts" +msgstr "Host" #, python-format msgid "" @@ -27936,10 +28257,7 @@ msgid "Host overview" msgstr "Hostübersicht" msgid "Host parent/child topology" -msgstr "Host Eltern/Kind Topologie" - -msgid "Host path" -msgstr "Host-Pfad" +msgstr "Host Parent/Child Topologie" msgid "Host performance data" msgstr "Leistungsdaten von Host" @@ -28076,7 +28394,7 @@ msgid "Host status" msgstr "Host-Status" msgid "Host's children" -msgstr "Kindknoten des Hosts" +msgstr "Child-Knoten des Hosts" msgid "Host's contact groups have precedence" msgstr "Hostkontaktgruppen haben Priorität" @@ -28428,19 +28746,19 @@ msgid "Hz" msgstr "Hz" msgid "I/O database reads (attached) average latency" -msgstr "I/O Datenbank-Lesezugriffe (Attached), durchschnittliche Latenz" +msgstr "E/A-Datenbank-Lesezugriffe (Attached), durchschnittliche Latenz" msgid "I/O database reads (recovery) average latency" -msgstr "I/O Datenbank-Lesezugriffe (Recovery), durchschnittliche Latenz" +msgstr "E/A-Datenbank-Lesezugriffe (Recovery), durchschnittliche Latenz" msgid "I/O database writes (attached) average latency" -msgstr "I/O Datenbank-Schreibzugriffe (Attached), durchschnittliche Latenz" +msgstr "E/A-Datenbank-Schreibzugriffe (Attached), durchschnittliche Latenz" msgid "I/O log writes average latency" -msgstr "I/O Log-Schreibzugriffe, durchschnittliche Latenz" +msgstr "E/A-Log-Schreibzugriffe, durchschnittliche Latenz" msgid "I/O-wait" -msgstr "I/O-wait" +msgstr "E/A-wait" msgid "IBM MQ" msgstr "IBM MQ" @@ -28619,6 +28937,9 @@ msgstr "IP - Region - Instanz-ID" msgid "IP Address" msgstr "IP-Adresse" +msgid "IP Address of Hosts" +msgstr "IP-Adresse der Hosts" + msgid "IP address" msgstr "IP-Adresse" @@ -29253,12 +29574,12 @@ msgid "" "the PING packet is being sent but from the time the last packet from the " "host was being seen." msgstr "" -"Wenn für eine bestimmte Zeit kein ICMP oder TCP-SYN/RST-Paket von einem Host " -"gesehen wird, dann wird dieser als down angenommen. Diese Zeit kann man hier " -"einstellen. Der Standardwert das 2,5-fache normale Intervall für den Host. " -"Hinweis: Diese Einstellung wird nicht gemessen vom Zeitpunkt, " -"wann das letzte PING-Paket gesendet wurde, sondern von dem Zeitpunkt, zu dem " -"das letzte Paket von dem Host empfangen wurde." +"Wenn für eine bestimmte Zeit kein ICMP oder TCP-SYN/RST-Paket von einem Ziel-" +"Host gesehen wird, dann wird dieser als down angenommen. Diese Zeit kann man " +"hier einstellen. Der Standardwert das 2,5-fache normale Intervall für den " +"Host. Hinweis: Diese Einstellung wird nicht gemessen vom " +"Zeitpunkt, wann das letzte PING-Paket gesendet wurde, sondern von dem " +"Zeitpunkt, zu dem das letzte Paket von dem Host empfangen wurde." msgid "" "If no explicit time range is being provided then the report defaults to this " @@ -29308,6 +29629,10 @@ msgid "" "authentication. 'Enforce two factor authentication' in global settings will " "override this setting." msgstr "" +"Wenn diese Einstellung gesetzt ist, müssen alle Benutzer mit dieser Rolle " +"eine Zwei-Faktor-Authentifizierung einrichten. Die Option „Zwei-Faktor-" +"Authentifizierung erzwingen“ in den globalen Einstellungen setzt diese " +"Einstellung außer Kraft." msgid "" "If set, the plug-in may be called repeately - up to this many times or until " @@ -29816,6 +30141,8 @@ msgid "" "If you are still using %s, we recommend switching to an PAT/API token, as " "the password authentication is deprecated." msgstr "" +"Wenn Sie immer noch %s verwenden, empfehlen wir Ihnen, zu einem PAT/API-" +"Token zu wechseln, da die Passwortauthentifizierung veraltet ist." msgid "" "If you are using rule based notifications with and Bulk Notifications " @@ -30458,8 +30785,8 @@ msgid "" "information. In such cases this setting is used as the assumed speed when it " "comes to traffic monitoring (see below)." msgstr "" -"Wenn Sie diesen Parameter verwenden dann meldet der Check WARN wenn die " -"Schnittstelle nicht mit der erwarteten Geschwindigkeit arbeitet (z.B. " +"Wenn Sie diesen Parameter verwenden, dann geht der Check auf WARNING, wenn " +"die Schnittstelle nicht mit der erwarteten Geschwindigkeit arbeitet (z.B. " "100Mbit/s an Stelle von 1Gbit/s.Achtung: Einige Schnittstellen melden " "keine Geschwindigkeitsinformationen. In solchen Fällen wird eine " "Geschwindigkeit für das Monitoren von Netzwerkverkehr geschätzt (siehe " @@ -30595,18 +30922,6 @@ msgstr "" "Sie, dass dies alles betrifft, was Teil der übereinstimmenden Namespaces " "ist, wie z. B. Pods." -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Wenn Ihr Monitoring eine Benachrichtigung erzeugt, die keiner Ihrer " -"Benachrichtigungsregeln entspricht, wird die Benachrichtigung nicht " -"versendet. Um dies zu verhindern, empfehlen wir Ihnen, entweder die globale " -"Einstellung zu konfigurieren oder die Fallback-Kontaktoption für mindestens " -"einen Ihrer Benutzer zu aktivieren." - msgid "Ignore" msgstr "Ignorieren" @@ -30619,9 +30934,8 @@ msgstr "TCP-RST-Pakete beim Feststellen des Host-Status ignorieren" msgid "Ignore TCP Reset Packets" msgstr "TCP-Reset-Pakete ignorieren" -#, fuzzy msgid "Ignore TLS certificate" -msgstr "Ignoriere SSL Zertifikatfehler" +msgstr "Ignoriere TLS Zertifikat" msgid "Ignore TLS errors" msgstr "TLS-Fehler ignorieren" @@ -31177,7 +31491,7 @@ msgid "" "In order to save resources on the target host and on the update server it is " "recommended to do the update checks not more than once every 10 minutes." msgstr "" -"Um Ressourcen auf dem Zielrechner und auf dem Update-Server zu sparen, wird " +"Um Ressourcen auf dem Ziel-Host und auf dem Update-Server zu sparen, wird " "empfohlen, die Update-Checks nicht öfter als einmal alle 10 Minuten " "durchzuführen." @@ -31310,7 +31624,7 @@ msgid "" "In this interval the event daemon will save its state to disk, so that you " "won't lose your current event state in case of a crash." msgstr "" -"In diesem Intervall speichert der Event-Daemon seinen aktuellen Status auf " +"In diesem Intervall speichert der Event Daemon seinen aktuellen Status auf " "Festplatte, damit Sie im Fall eines Absturzes Ihren aktuellen Ereignisstatus " "nicht verlieren." @@ -31571,6 +31885,15 @@ msgstr "Zu durchsuchende Indexe, Standardwert ist \"*\", d.h. alle Indexe." msgid "Indexspace wasted" msgstr "Ungenutzter Indexbereich" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Ob die letzte Bulk Discovery fehlgeschlagen ist oder nicht. Sie wird auf " +"True gesetzt, wenn sie fehlgeschlagen ist, und nicht gesetzt, wenn eine " +"spätere Discovery erfolgreich war." + msgid "Indices" msgstr "Indizes" @@ -31656,10 +31979,10 @@ msgid "InfluxDB processing" msgstr "InfluxDB-Verarbeitung" msgid "InfluxDB queue usage" -msgstr "InfluxDB queue usage" +msgstr "InfluxDB Warteschlangenauslastung" msgid "InfluxDB queue usage rate" -msgstr "InfluxDB queue usage rate" +msgstr "InfluxDB Rate der Warteschlangenauslastung" msgid "InfluxDB service rules" msgstr "InfluxDB Service-Regeln" @@ -31710,7 +32033,7 @@ msgid "Informix table extents" msgstr "Informix Tabellen-Extent" msgid "Ingress packet drop" -msgstr "Ingress packet drop" +msgstr "Ingress Paketverlust" msgid "Inherit from report time range (Reporting only)" msgstr "Vererben vom Zeitraum des Berichts (nur Reporting)" @@ -31960,9 +32283,9 @@ msgid "" "target event console can be configured for each host in a separate rule." msgstr "" "Anstelle des regulären Logwatch-Checks können alle von Logwatch empfangenen " -"Zeilen zur Verarbeitug an einen Checkmk Event Consolen Daemon weitergeleitet " -"werden. Die Ziel-Event Console kann für jeden Host in einer separaten Regel " -"konfiguriert werden." +"Zeilen zur Verarbeitung an einen Checkmk Event Consolen Daemon " +"weitergeleitet werden. Die Ziel-Event Console kann für jeden Host in einer " +"separaten Regel konfiguriert werden." msgid "Integrate Nagios plug-ins" msgstr "Nagios-Plugins einbinden" @@ -32024,13 +32347,13 @@ msgid "Interface %s" msgstr "Schnittstelle %s" msgid "Interface groups" -msgstr "Netzwerkschnittstellengruppen" +msgstr "Schnittstellengruppen" msgid "Interface id" -msgstr "Schnittstellenbezeichner" +msgstr "Schnittstellen-ID" msgid "Interface settings" -msgstr "Einstellungen der Netzwerkschnittstellen" +msgstr "Einstellungen der Schnittstelle" msgid "Intermission" msgstr "Unterbrechung" @@ -32217,6 +32540,10 @@ msgstr "Ungültiges Zertifikat" msgid "Invalid certificate file: %s" msgstr "Ungültige Zertifikatsdatei: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Ungültiger Parameter %r: %s" + msgid "Invalid check parameter" msgstr "Ungültiger Check-Parameter" @@ -32869,118 +33196,118 @@ msgid "JVM memory levels" msgstr "JVM Speicher-Level" msgid "JVM memory pool G1 Eden Space: available by OS" -msgstr "" +msgstr "JVM-Speicherpool G1 Eden Space: vom Betriebssystem verfügbar" msgid "JVM memory pool G1 Eden Space: initially requested" -msgstr "" +msgstr "JVM-Speicherpool G1 Eden Space: ursprünglich angefordert" msgid "JVM memory pool G1 Eden Space: usage" -msgstr "" +msgstr "JVM-Speicherpool G1 Eden Space: Auslastung" msgid "JVM memory pool G1 Eden Space: used" -msgstr "" +msgstr "JVM-Speicherpool G1 Eden Space: genutzt" msgid "JVM memory pool G1 Eden Space: used after GC" -msgstr "" +msgstr "JVM-Speicherpool G1 Eden Space: verwendet nach GC" msgid "JVM memory pool G1 Old Gen: available by OS" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: vom Betriebssystem verfügbar" msgid "JVM memory pool G1 Old Gen: initially requested" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: ursprünglich angefordert" msgid "JVM memory pool G1 Old Gen: max. allowed" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: maximal erlaubt" msgid "JVM memory pool G1 Old Gen: usage" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: Auslastung" msgid "JVM memory pool G1 Old Gen: used" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: genutzt" msgid "JVM memory pool G1 Old Gen: used after GC" -msgstr "" +msgstr "JVM-Speicherpool G1 Old Gen: verwendet nach GC" msgid "JVM memory pool G1 Survivor Space: available by OS" -msgstr "" +msgstr "JVM-Speicherpool G1 Survivor Space: vom Betriebssystem verfügbar" msgid "JVM memory pool G1 Survivor Space: initially requested" -msgstr "" +msgstr "JVM-Speicherpool G1 Survivor Space: ursprünglich angefordert" msgid "JVM memory pool G1 Survivor Space: usage" -msgstr "" +msgstr "JVM-Speicherpool G1 Survivor Space: Auslastung" msgid "JVM memory pool G1 Survivor Space: used" -msgstr "" +msgstr "JVM-Speicherpool G1 Survivor Space: genutzt" msgid "JVM memory pool G1 Survivor Space: used after GC" -msgstr "" +msgstr "JVM-Speicherpool G1 Survivor Space: verwendet nach GC" msgid "JVM memory pool Metaspace: available by OS" -msgstr "" +msgstr "JVM-Speicherpool Metaspace: vom Betriebssystem verfügbar" msgid "JVM memory pool Metaspace: initially requested" -msgstr "" +msgstr "JVM-Speicherpool Metaspace: ursprünglich angefordert" msgid "JVM memory pool Metaspace: max. allowed" -msgstr "" +msgstr "JVM-Speicherpool Metaspace: maximal erlaubt" msgid "JVM memory pool Metaspace: usage" -msgstr "" +msgstr "JVM-Speicherpool Metaspace: Auslastung" msgid "JVM memory pool Metaspace: used" -msgstr "" +msgstr "JVM-Speicherpool Metaspace: genutzt" msgid "JVM memory pool levels" msgstr "JVM Speicher-Pool Level" msgid "JVM memory total: available by OS" -msgstr "" +msgstr "JVM-Speicher gesamt: vom Betriebssystem verfügbar" msgid "JVM memory total: initially requested" -msgstr "" +msgstr "JVM-Speicher gesamt: ursprünglich angefordert" msgid "JVM memory total: max. allowed" -msgstr "" +msgstr "JVM-Speicher gesamt: maximal erlaubt" msgid "JVM memory total: used" -msgstr "" +msgstr "JVM-Speicher gesamt: genutzt" msgid "JVM memory: heap" -msgstr "" +msgstr "JVM-Speicher: Heap" msgid "JVM memory: heap: available by OS" -msgstr "" +msgstr "JVM-Speicher: Heap: vom Betriebssystem verfügbar" msgid "JVM memory: heap: initially requested" -msgstr "" +msgstr "JVM-Speicher: Heap: ursprünglich angefordert" msgid "JVM memory: heap: max. allowed" -msgstr "" +msgstr "JVM-Speicher: Heap: maximal erlaubt" msgid "JVM memory: heap: usage" -msgstr "" +msgstr "JVM-Speicher: Heap: Auslastung" msgid "JVM memory: heap: used" -msgstr "" +msgstr "JVM-Speicher: Heap: genutzt" msgid "JVM memory: non-heap" -msgstr "" +msgstr "JVM-Speicher: Non Heap" msgid "JVM memory: non-heap: available by OS" -msgstr "" +msgstr "JVM-Speicher: Non Heap: vom Betriebssystem verfügbar" msgid "JVM memory: non-heap: initially requested" -msgstr "" +msgstr "JVM-Speicher: Non Heap: ursprünglich angefordert" msgid "JVM memory: non-heap: max. allowed" -msgstr "" +msgstr "JVM-Speicher: Non Heap: maximal erlaubt" msgid "JVM memory: non-heap: usage" -msgstr "" +msgstr "JVM-Speicher: Non Heap: Auslastung" msgid "JVM memory: non-heap: used" -msgstr "" +msgstr "JVM-Speicher: Non Heap: genutzt" msgid "JVM request count" msgstr "JVM Anfragen" @@ -32998,7 +33325,7 @@ msgid "JVM tomcat threadpool levels" msgstr "JVM Tomcat Threadpool-Level" msgid "JVM total memory" -msgstr "" +msgstr "JVM-Speicher gesamt" msgid "JVM uptime (since last reboot)" msgstr "JVM-Laufzeit (seit letztem Reboot)" @@ -33022,16 +33349,16 @@ msgid "Jenkins jobs" msgstr "Jenkins Jobs" msgid "Jenkins memory pool G1 Eden Space" -msgstr "" +msgstr "Jenkins Speicher-Pool G1 Eden Space" msgid "Jenkins memory pool G1 Old Gen" -msgstr "" +msgstr "Jenkins Speicher-Pool G1 Old Gen" msgid "Jenkins memory pool G1 Survivor Space" -msgstr "" +msgstr "Jenkins Speicher-Pool G1 Survivor Space" msgid "Jenkins memory pool Metaspace" -msgstr "" +msgstr "Jenkins Speicher-Pool Metaspace" msgid "Jenkins nodes" msgstr "Jenkins Knoten" @@ -33040,7 +33367,7 @@ msgid "Jenkins queue" msgstr "Warteschlange in Jenkins" msgid "Jenkins system metrics" -msgstr "" +msgstr "Jenkins Systemmetriken" msgid "Jenkins version" msgstr "Jenkins-Version" @@ -33305,7 +33632,7 @@ msgid "Kubernetes Cluster" msgstr "Kubernetes-Cluster" msgid "Kubernetes Clusters" -msgstr "Kubernetes-Cluster" +msgstr "Kubernetes-Clusters" msgid "Kubernetes Collector Info" msgstr "Kubernetes Collector Info" @@ -33574,7 +33901,7 @@ msgid "Lambda user errors" msgstr "Lambda Benutzer-Fehler" msgid "Lanes" -msgstr "Lanes" +msgstr "Spuren" msgid "Language" msgstr "Sprache" @@ -34656,7 +34983,7 @@ msgid "Lifetime remaining" msgstr "Verbleibende Lebenszeit" msgid "Limit" -msgstr "Limit" +msgstr "Grenzwert" msgid "Limit amount of current events" msgstr "Anzahl aktueller Ereignisse begrenzen" @@ -34914,6 +35241,9 @@ msgstr "Linux Multipath Inventar" msgid "Linux and Solaris Multipath Count" msgstr "Linux und Solaris Multipath-Anzahl" +msgid "Linux bonding" +msgstr "Linux-Kopplung" + msgid "Linux bonding interface status" msgstr "Status der Linux-Bonding-Schnittstelle" @@ -34962,10 +35292,10 @@ msgid "List crash reports of all sites" msgstr "Liste der Absturzberichte aller Instanzen" msgid "List grouped interfaces instead" -msgstr "Liste gruppierte Schnittstellen stattdessen" +msgstr "Stattdessen gruppierte Schnittstellen auflisten" msgid "List grouped interfaces separately" -msgstr "Liste gruppierte Schnittstellen separat" +msgstr "Gruppierte Schnittstellen separat auflisten" msgid "List of all aggregations for simple API calls" msgstr "Liste aller Aggregationen für einfache API-Aufrufe" @@ -35003,7 +35333,7 @@ msgid "Listen for incoming messages via" msgstr "Auf eingehende Ereignisse horchen" msgid "Listen for spans on this local IP address" -msgstr "" +msgstr "An dieser lokalen IP-Adresse nach Zeitspannen suchen" msgid "Listener" msgstr "Listener" @@ -35088,7 +35418,7 @@ msgid "Live search active" msgstr "Livesuche aktiv" msgid "Liveproxy Daemon" -msgstr "Livestatus-Proxy-Daeamon" +msgstr "Liveproxy Daemon" msgid "Liveproxyd" msgstr "Liveproxyd" @@ -35501,6 +35831,9 @@ msgstr "" "Protokollieren Sie den Prozess der Agentenregistrierung bei eingehenden " "Anfragen mit dem Befehl Checkmk agent controller registration." +msgid "Log the automatic host removal process." +msgstr "Protokolliere den automatischen Entfernungsprozess für Hosts." + msgid "Log: Details" msgstr "Log: Details" @@ -35707,7 +36040,7 @@ msgid "Logout" msgstr "Abmeldung" msgid "Logs" -msgstr "Logs" +msgstr "Protokolle" msgid "Logswitches" msgstr "Logswitches" @@ -35974,16 +36307,20 @@ msgid "Lower levels on number of Point-to-site connections" msgstr "Untergrenzen für die Anzahl der Pint-to-Site Verbindungen" msgid "Lower levels on the biggest input buffer" -msgstr "" +msgstr "Untergrenzen für größten Eingabepuffer" msgid "Lower levels on the longest output list" -msgstr "" +msgstr "Untergrenzen für längste Ausgabeliste" msgid "Lower levels on the total number of client connections" -msgstr "" +msgstr "Untergrenzen für Gesamtanzahl der Client-Verbindungen" msgid "Lower levels on the total number of clients pending on a blocking call" msgstr "" +"Untergrenzen für die Gesamtanzahl wartender Clients auf blockierenden Aufruf" + +msgid "Lower limit of expected interfaces" +msgstr "Untergrenze der erwarteten Schnittstellen" msgid "Lowest: No notification, update badge number" msgstr "Am niedrigsten: keine Benachrichtigung, Hinweiszahl erhöhen" @@ -36335,13 +36672,13 @@ msgid "Maintenance" msgstr "Instandhaltung" msgid "Major Page Faults" -msgstr "Major Page Faults" +msgstr "Wesentliche Seitenfehler" msgid "Major change" msgstr "Wichtige Änderungen" msgid "Major page faults" -msgstr "Major page faults" +msgstr "Wesentliche Seitenfehler" #, python-format msgid "Make %s visible and usable for all users." @@ -36542,9 +36879,22 @@ msgstr "Benutzer des Monitoring-Systems verwalten." msgid "Managed Robot" msgstr "Verwalteter Roboter" +msgid "Managed Robots" +msgstr "Verwaltete Roboter" + msgid "Managed objects" msgstr "Verwaltete Objekte" +msgid "Managed robot deleted." +msgstr "Verwalteter Roboter wurde gelöscht." + +msgid "Managed robot not found while attempting to delete it." +msgstr "" +"Beim Versuch, ihn zu löschen, wurde der verwaltete Roboter nicht gefunden." + +msgid "Managed robots" +msgstr "Verwaltete Roboter" + msgid "Management board" msgstr "Management Board" @@ -37940,7 +38290,7 @@ msgid "Metrics" msgstr "Metriken" msgid "Metrics Group" -msgstr "" +msgstr "Gruppe der Metriken" msgid "Metrics graph of a single service" msgstr "Graph eines einzelnen Services" @@ -37989,7 +38339,7 @@ msgid "Migrated %d %s to connector '%s': %s" msgstr "%d %s auf Connector '%s': %s migriert" msgid "Migrated Parents" -msgstr "Parents migrieren" +msgstr "Migrierte Parents" msgid "Migrating" msgstr "Migration" @@ -38062,12 +38412,13 @@ msgstr "Minimale Verbindungen pro Sekunde" msgid "Minimum error count" msgstr "Minimale Fehleranzahl" -msgid "Minimum levels for Voltage" -msgstr "Untergrenzen für die Spannung" - msgid "Minimum levels for load in percent" msgstr "Untergrenzen für die Last in Prozent" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Untergrenzen für die Spannung" + msgid "Minimum levels if using magic factor" msgstr "Minimale Level bei Verwendung von Magic Factor" @@ -38173,6 +38524,9 @@ msgstr "Fehlgeplante Dauer (nur DaemonSet)" msgid "Misscheduled replicas" msgstr "Fehlgeplante Repliken" +msgid "Missing catalog topic." +msgstr "Fehlendes Katalogthema." + #, python-format msgid "Missing config file for agent %s%s" msgstr "Fehlende Konfigurationsdatei für Agent %s%s" @@ -39578,6 +39932,13 @@ msgstr "Namensauflösung" msgid "Name your %s for easy recognition." msgstr "Benennen Sie Ihr %s zur einfachen Wiedererkennung." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" +"Benennen Sie Ihren Host, geben Sie den Pfad an und wählen Sie die " +"Einrichtung, die Sie überwachen wollen" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -39594,25 +39955,26 @@ msgstr "Namen" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" -"Dateien, die zusätzliche Befehlszeilenargumente für Robot Framework " -"enthalten. Die Pfade sind relativ zum Basisverzeichnis der Test-Suiten. Argumentdateien ermöglichen es, alle oder einige Befehlszeilenoptionen " -"und -argumente in einer externen Datei abzulegen, aus der sie dann gelesen " -"werden. Dies ist nützlich für exotischere RF-Parameter, die von Robotmk " -"nicht nativ unterstützt werden, oder für problematische Zeichen. Die hier " -"angegebenen Argumente werden zusammen mit möglichen anderen " -"Befehlszeilenoptionen verwendet. (Siehe auch About argument files)" +"Die Dateinamen, die zusätzliche Befehlszeilenargumente für Robot " +"Framework enthalten. Die Pfade sind relativ zum Basisverzeichnis von " +"Robot Framework-Projekten. Argumentdateien ermöglichen es, alle oder " +"einige Befehlszeilenoptionen und -argumente in einer externen Datei zu " +"speichern, aus der sie dann gelesen werden. Dies ist für exotischere RF-" +"Parameter, die von Robotmk nicht nativ unterstützt werden, oder für " +"problematische Zeichen nützlich. Die hier angegebenen Argumente werden " +"zusammen mit möglichen anderen Befehlszeilenoptionen verwendet. (Siehe auch " +"About " +"argument files)" msgid "" "Names of IPMI sensors that should be ignored during discovery. The pattern " @@ -39827,10 +40189,10 @@ msgid "Network interfaces" msgstr "Netzwerkschnittstellen" msgid "Network interfaces and switch ports" -msgstr "Netzwerkschnittstellen/Switch Ports" +msgstr "Netzwerkschnittstellen und Switch Ports" msgid "Network interfaces on Windows" -msgstr "Netzwerkkarten unter Windows" +msgstr "Netzwerkschnittstellen unter Windows" msgid "Network interfaces: last day view" msgstr "Netzwerkschnittstellen: Ansicht über den vergangenen Tag" @@ -40007,6 +40369,24 @@ msgstr "Nächste Benachrichtigung" msgid "Next run" msgstr "Nächster Lauf" +msgid "Next step: General properties" +msgstr "Nächster Schritt: Generelle Eigenschaften" + +msgid "Next step: Notification method (plug-in)" +msgstr "Nächster Schritt: Benachrichtigungsmethode (Plugin)" + +msgid "Next step: Recipient" +msgstr "Nächster Schritt: Empfänger" + +msgid "Next step: Saving" +msgstr "Nächster Schritt: Speichern" + +msgid "Next step: Sending conditions" +msgstr "Nächster Schritt: Bedingungen senden" + +msgid "Next step: Specify host/services" +msgstr "Nächster Schritt: Host/Services festlegen" + msgid "Nginx Server" msgstr "Nginx-Server" @@ -40022,6 +40402,10 @@ msgstr "Level für Nimble IO" msgid "No" msgstr "Nein" +#, python-format +msgid "No %s configuration yet" +msgstr "Noch keine %s Konfiguration vorhanden" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "Nein (Fehler: %s, Code: %d, Tiefe: %d)" @@ -40029,6 +40413,10 @@ msgstr "Nein (Fehler: %s, Code: %d, Tiefe: %d)" msgid "No API integrations, no Checkmk agent" msgstr "Keine API-Integrationen, kein Checkmk-Agent" +#, fuzzy +msgid "No AWS services found." +msgstr "Keine Hosts/Services gefunden." + msgid "No CSRF token received" msgstr "Kein CSRF-Token erhalten" @@ -40037,7 +40425,11 @@ msgstr "Keine Bedingungen" #, python-format msgid "No Configuration Quick setup for %s available" -msgstr "" +msgstr "Kein Quick Setup für die Konfiguration von %s verfügbar" + +#, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Keine FormSpec-Implementation für die Methode '%s' gefunden." msgid "No IP" msgstr "Keine IP" @@ -40055,7 +40447,7 @@ msgid "No TLS" msgstr "Kein TLS" msgid "No TX Credits" -msgstr "No TX Credits" +msgstr "Keine TX Credits" msgid "" "No UTF-8 encoding found in your locale -a! Please install appropriate " @@ -40113,9 +40505,6 @@ msgstr "Befehle in dieser Ansicht nicht möglich" msgid "No conditions" msgstr "Keine Bedingungen" -msgid "No configuration yet" -msgstr "Keine Konfiguration vorhanden" - msgid "No configured rules are affected" msgstr "Es sind keine konfigurierten Regeln betroffen" @@ -40172,6 +40561,16 @@ msgstr "" #, python-format msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +"Für den Bundle-Gruppentyp '%s' ist kein Editierkonfigurations-Bundle " +"implementiert." + +#, fuzzy +msgid "No elements available" +msgstr "Nicht verfügbar" + +#, fuzzy +msgid "No elements selected" +msgstr "Nicht ausgewählt" msgid "No entries" msgstr "Keine Einträge" @@ -40301,6 +40700,10 @@ msgstr "Keine Namen definiert" msgid "No need for syncing sites" msgstr "Synchronisierung von Instanzen nicht nötig" +#, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Keine Parameter für Benachrichtigung für die Methode '%s' gefunden" + msgid "No object type" msgstr "Kein Objekttyp" @@ -40310,6 +40713,9 @@ msgstr "Kein Passwort eingegeben. Bitte geben Sie ein Passwort ein." msgid "No password provided" msgstr "Kein Passwort angegeben" +msgid "No password selected" +msgstr "Es wurde kein Passwort ausgewählt" + msgid "No pending changes" msgstr "Keine anstehenden Änderungen" @@ -40385,6 +40791,9 @@ msgstr "Keine Suche" msgid "No search, specify list of arguments" msgstr "Keine Suche, Liste der Argumente angeben" +msgid "No smarthosts" +msgstr "Keine Smarthosts" + msgid "No snapshot to restore available." msgstr "Kein Snapshot für Wiederherstellung verfügbar." @@ -40665,14 +41074,15 @@ msgid "" "as group interfaces should not show up as single service. You can restrict " "grouped interfaces by iftype and the item name of the single interface." msgstr "" -"Normalerweise erstellen die Interface-Checks einen einzigen Service pro " -"Interface. Durch die Definition von \"if-group patterns\" können mehrere " -"Interfaces miteinander kombiniert werden. Für diese Interface-Gruppen wird " -"ein einzelner Service erstellt, der den Gesamt-Traffic der gruppierten " -"Interfaces anzeigt. Sie können konfigurieren, dass Interfaces, die als " -"Interface-Gruppe identifiziert werden, nicht als einzelner Service angezeigt " -"werden sollen. Sie können gruppierte Interfaces nach iftype und dem Item-" -"Name des einzelnen Interfaces einschränken." +"Normalerweise erstellen die Schnittstellen-Checks einen einzigen Service pro " +"Schnittstelle. Durch die Definition von \"if-group patterns\" können mehrere " +"Schnittstellen miteinander kombiniert werden. Für diese " +"Schnittstellengruppen wird ein einzelner Service erstellt, der den " +"Gesamtverkehr der gruppierten Schnittstellen anzeigt. Sie können " +"konfigurieren, dass Schnittstellen, die als Schnittstellengruppe " +"identifiziert werden, nicht als einzelner Service angezeigt werden sollen. " +"Sie können gruppierte Schnittstellen nach iftype und dem Item-Name der " +"einzelnen Schnittstelle einschränken." msgid "" "Normally the downtime has a fixed time range starting from the \"start time" @@ -40754,7 +41164,7 @@ msgstr "Nicht" #, python-format msgid "Not Before: %s - Not After: %s" -msgstr "" +msgstr "Nicht vor: %s - nicht nach: %s" msgid "Not a valid URL (Only http and https URLs are allowed)." msgstr "Keine gültige URL (nur http- und https-URLs sind zulässig)." @@ -40834,6 +41244,11 @@ msgstr "Hinweis" msgid "Notation: %s" msgstr "Hinweis: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" +"Notieren Sie sich die generierte Zugangsschlüssel-ID und den geheimen " +"Zugangsschlüssel." + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -40980,7 +41395,7 @@ msgid "Notification configuration" msgstr "Benachrichtigungskonfiguration" msgid "Notification core status" -msgstr "" +msgstr "Status des Benachrichtigungskerns" msgid "Notification delivery rate" msgstr "Zustellungsrate der Benachrichtigungen" @@ -40994,6 +41409,16 @@ msgstr "Loglevel für die Benachrichtigung" msgid "Notification method" msgstr "Benachrichtigungsmethode" +#, python-format +msgid "Notification method '%s' does not exist" +msgstr "Benachrichtigungsmethode '%s' existiert nicht" + +msgid "Notification method (plug-in)" +msgstr "Benachrichtigungsmethode (Plugin)" + +msgid "Notification parameter" +msgstr "Benachrichtigungsparameter" + msgid "Notification period" msgstr "Benachrichtigungsperiode" @@ -41149,7 +41574,7 @@ msgid "Ntop integration of this host" msgstr "Ntop Integration dieses Hosts" msgid "Ntop integration of this interface" -msgstr "Ntop Integration dieser Netzwerkschnittstelle" +msgstr "Ntop Integration dieser Schnittstelle" msgid "Ntop ports" msgstr "Ntop Ports" @@ -41176,7 +41601,7 @@ msgid "Ntopng integration" msgstr "Ntopng-Integration" msgid "Nullmailer: Mail Queue" -msgstr "Nullmailer: Mail Queue" +msgstr "Nullmailer: Mail-Warteschlange" msgid "Number" msgstr "Nummer" @@ -41187,7 +41612,7 @@ msgid "" "check waits for the incoming packets." msgstr "" "Anzahl der ICMP-Echo-Request-Pakete, die bei jeder Check-Ausführung an den " -"Zielhost gesendet werden. Alle Pakete werden direkt bei der Ausführung des " +"Ziel-Host gesendet werden. Alle Pakete werden direkt bei der Ausführung des " "Checks gesendet. Danach wartet der Check auf die eingehenden Pakete." msgid "Number is not a float value." @@ -41251,7 +41676,7 @@ msgid "Number of PING probes" msgstr "Anzahl von PING Versuchen" msgid "Number of Placement Groups" -msgstr "" +msgstr "Anzahl der Platzierungsgruppen" msgid "Number of Resources" msgstr "Anzahl von Ressourcen" @@ -41428,6 +41853,12 @@ msgstr "Anzahl von Ordnern, die pro Level anzulegen sind" msgid "Number of goroutines" msgstr "Anzahl der Go-Routinen" +msgid "Number of graphs per event (default: 5)" +msgstr "Anzahl an Graphen pro Ereignis (Standard: 5)" + +msgid "Number of graphs per notification (default: 5)" +msgstr "Anzahl an Graphen pro Benachrichtigung (Standard: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Untergrenzen für Anzahl der gesunden Hosts" @@ -42044,8 +42475,8 @@ msgstr "OSN Laser Dämpfung" msgid "OTLP endpoint" msgstr "OTLP-Endpunkt" -msgid "OVS bonding interface status" -msgstr "Status der OVS Bonding-Schnittstelle" +msgid "OVS bonding" +msgstr "OVS-Kopplung" msgid "Object" msgstr "Objekt" @@ -42404,8 +42835,8 @@ msgstr "" "übereinstimmenden Suites und nur solche, bei denen andere Filterkriterien " "greifen, ausgewählt. Bei Name kann es sich um ein einfaches Muster handeln, " "ähnlich wie bei --test, und es kann durch einen Punkt getrennte " -"Namen von übergeordneten Paketen enthalten. Zum Beispiel wählt X.Y " -"eine Suite Y nur aus, wenn der Parent X ist." +"Namen von Parent-Suites enthalten. Zum Beispiel wählt X.Y eine " +"Suite Y nur aus, wenn der Parent X ist." msgid "Only fetch specific OIDs" msgstr "Nur bestimmte OIDs holen" @@ -42454,8 +42885,8 @@ msgid "" "Only interfaces with the given port type are put into this group. For " "example 53 (propVirtual)." msgstr "" -"Nur Port des eingestellten Typs werden in die Gruppe aufgenommen (z.B. 53 " -"für propVirtual)." +"Nur Schnittstellen mit dem eingestellten Port-Typ werden in die Gruppe " +"aufgenommen. Zum Beispiel 53 (propVirtual)." #, python-format msgid "" @@ -42619,7 +43050,7 @@ msgid "Open this Aggregation" msgstr "Dieses Aggregat öffnen" msgid "Open this site's local web user interface" -msgstr "Lokale Webseite dieser Instanz öffnen" +msgstr "Lokale Web-Benutzeroberfläche dieser Instanz öffnen" msgid "Open this table for filtering / sorting" msgstr "Diese Tabelle zum Filtern/Sortieren öffnen" @@ -43020,7 +43451,7 @@ msgid "Oracle block change" msgstr "Oracle Blockänderung" msgid "Oracle block gets" -msgstr "" +msgstr "Oracle block gets" msgid "Oracle buffer busy wait" msgstr "Oracle Puffer beschäftigt Wartezeit" @@ -43059,7 +43490,7 @@ msgid "Oracle configuration wait class (FG)" msgstr "Oracle Konfigurations-Warteklasse (FG)" msgid "Oracle consistent gets" -msgstr "" +msgstr "Oracle consistent gets" msgid "Oracle control file large read bytes" msgstr "Oracle Kontrolldatei Large Read in Bytes" @@ -43185,28 +43616,28 @@ msgid "Oracle data file small writes" msgstr "Oracle Datei Small Writes" msgid "Oracle data pump dump file large read bytes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei Large Read in Bytes" msgid "Oracle data pump dump file large reads" -msgstr "" +msgstr "Oracle Pump Dump Datendatei große Lesezugriffe" msgid "Oracle data pump dump file large write bytes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei Large Write in Bytes" msgid "Oracle data pump dump file large writes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei große Schreibzugriffe" msgid "Oracle data pump dump file small read bytes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei Small Read in Bytes" msgid "Oracle data pump dump file small reads" -msgstr "" +msgstr "Oracle Pump Dump Datendatei kleine Lesezugriffe" msgid "Oracle data pump dump file small write bytes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei Small Writes in Bytes" msgid "Oracle data pump dump file small writes" -msgstr "" +msgstr "Oracle Pump Dump Datendatei kleine Schreibzugriffe" msgid "Oracle databases (Linux, Solaris, AIX, Windows)" msgstr "Oracle-Datenbanken (Linux, Solaris, AIX, Windows)" @@ -43859,6 +44290,9 @@ msgstr "Gesamtzahl aktueller Ereignisse" msgid "Overall latency" msgstr "Gesamtlatenz" +msgid "Overall response time" +msgstr "Allgemeine Antwortzeit" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "Gesamtstatus einer virtuellen Maschine (beispielsweise ESX VMs)" @@ -43919,7 +44353,8 @@ msgstr "Check-Status basierend auf dem Jobstatus überschreiben" msgid "Override check state based on last build result" msgstr "Check-Status basierend auf dem letzten Build-Ergebnis überschreiben" -msgid "Override current plan settings" +#, fuzzy +msgid "Override managed plan settings" msgstr "Aktuelle Planeinstellungen überschreiben" msgid "Override unit of sensor" @@ -43932,7 +44367,7 @@ msgid "Oversubscribed" msgstr "Überzeichnet" msgid "Overview" -msgstr "Overview" +msgstr "Überblick" msgid "Owned by other users" msgstr "Von anderen Benutzern" @@ -44005,195 +44440,200 @@ msgid "PENDING services of host" msgstr "PENDING Services von Host" msgid "PGs Activating + Undersized" -msgstr "" +msgstr "PGs Activating + Undersized" msgid "PGs Activating + Undersized + Degradedpgstate" -msgstr "" +msgstr "PGs Activating + Undersized + Degradedpgstate" msgid "PGs Active + Clean" -msgstr "" +msgstr "PGs Active + Clean" msgid "PGs Active + Clean + Inconsistent" -msgstr "" +msgstr "PGs Active + Clean + Inconsistent" msgid "PGs Active + Clean + Remapped" -msgstr "" +msgstr "PGs Active + Clean + Remapped" msgid "PGs Active + Clean + Scrubbing" -msgstr "" +msgstr "PGs Active + Clean + Scrubbing" msgid "PGs Active + Clean + Scrubbing + Deep" -msgstr "" +msgstr "PGs Active + Clean + Scrubbing + Deep" msgid "PGs Active + Clean + Scrubbing + Deep + Repair" -msgstr "" +msgstr "PGs Active + Clean + Scrubbing + Deep + Repair" msgid "PGs Active + Clean + Scrubbing + Deep + Snaptrim + Wait" -msgstr "" +msgstr "PGs Active + Clean + Scrubbing + Deep + Snaptrim + Wait" msgid "PGs Active + Clean + Snaptrim" -msgstr "" +msgstr "PGs Active + Clean + Snaptrim" msgid "PGs Active + Clean + Snaptrim + Wait" -msgstr "" +msgstr "PGs Active + Clean + Snaptrim + Wait" msgid "PGs Active + Clean + Wait" -msgstr "" +msgstr "PGs Active + Clean + Wait" msgid "PGs Active + Degraded" -msgstr "" +msgstr "PGs Active + Degraded" msgid "PGs Active + Recovering" -msgstr "" +msgstr "PGs Active + Recovering" msgid "PGs Active + Recovering + Degraded" -msgstr "" +msgstr "PGs Active + Recovering + Degraded" msgid "PGs Active + Recovering + Degraded + Inconsistent" -msgstr "" +msgstr "PGs Active + Recovering + Degraded + Inconsistent" msgid "PGs Active + Recovering + Degraded + Remapped" -msgstr "" +msgstr "PGs Active + Recovering + Degraded + Remapped" msgid "PGs Active + Recovering + Remapped" -msgstr "" +msgstr "PGs Active + Recovering + Remapped" msgid "PGs Active + Recovering + Undersized" -msgstr "" +msgstr "PGs Active + Recovering + Undersized" msgid "PGs Active + Recovering + Undersized + Degraded + Remapped" -msgstr "" +msgstr "PGs Active + Recovering + Undersized + Degraded + Remapped" msgid "PGs Active + Recovering + Undersized + Remapped" -msgstr "" +msgstr "PGs Active + Recovering + Undersized + Remapped" msgid "PGs Active + Recovery + Wait" -msgstr "" +msgstr "PGs Active + Recovery + Wait" msgid "PGs Active + Recovery + Wait + Degraded" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Degraded" msgid "PGs Active + Recovery + Wait + Degraded + Inconsistent" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Degraded + Inconsistent" msgid "PGs Active + Recovery + Wait + Degraded + Remapped" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Degraded + Remapped" msgid "PGs Active + Recovery + Wait + Remapped" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Remapped" msgid "PGs Active + Recovery + Wait + Undersized + Degraded" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Undersized + Degraded" msgid "PGs Active + Recovery + Wait + Undersized + Degraded + Remapped" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Undersized + Degraded + Remapped" msgid "PGs Active + Recovery + Wait + Undersized + Remapped" -msgstr "" +msgstr "PGs Active + Recovery + Wait + Undersized + Remapped" msgid "PGs Active + Remapped" -msgstr "" +msgstr "PGs Active + Remapped" msgid "PGs Active + Remapped + Backfill + Toofull" -msgstr "" +msgstr "PGs Active + Remapped + Backfill + Toofull" msgid "PGs Active + Remapped + Backfill + Wait" -msgstr "" +msgstr "PGs Active + Remapped + Backfill + Wait" msgid "PGs Active + Remapped + Backfill + Wait + Backfill + Toofull" -msgstr "" +msgstr "PGs Active + Remapped + Backfill + Wait + Backfill + Toofull" msgid "PGs Active + Remapped + Backfilling" -msgstr "" +msgstr "PGs Active + Remapped + Backfilling" msgid "PGs Active + Remapped + Inconsistent + Backfill + Toofull" -msgstr "" +msgstr "PGs Active + Remapped + Inconsistent + Backfill + Toofull" msgid "PGs Active + Remapped + Inconsistent + Backfill + Wait" -msgstr "" +msgstr "PGs Active + Remapped + Inconsistent + Backfill + Wait" msgid "PGs Active + Remapped + Inconsistent + Backfilling" -msgstr "" +msgstr "PGs Active + Remapped + Inconsistent + Backfilling" msgid "PGs Active + Undersized" -msgstr "" +msgstr "PGs Active + Undersized" msgid "PGs Active + Undersized + Degraded" -msgstr "" +msgstr "PGs Active + Undersized + Degraded" msgid "PGs Active + Undersized + Degraded + Inconsistent" -msgstr "" +msgstr "PGs Active + Undersized + Degraded + Inconsistent" msgid "PGs Active + Undersized + Degraded + Remapped + Backfill + Toofull" -msgstr "" +msgstr "PGs Active + Undersized + Degraded + Remapped + Backfill + Toofull" msgid "PGs Active + Undersized + Degraded + Remapped + Backfill + Wait" -msgstr "" +msgstr "PGs Active + Undersized + Degraded + Remapped + Backfill + Wait" msgid "PGs Active + Undersized + Degraded + Remapped + Backfilling" -msgstr "" +msgstr "PGs Active + Undersized + Degraded + Remapped + Backfilling" msgid "" "PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfill + " "Toofull" msgstr "" +"PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfill + " +"Toofull" msgid "" "PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfill + " "Wait" msgstr "" +"PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfill + " +"Wait" msgid "" "PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfilling" msgstr "" +"PGs Active + Undersized + Degraded + Remapped + Inconsistent + Backfilling" msgid "PGs Active + Undersized + Remapped" -msgstr "" +msgstr "PGs Active + Undersized + Remapped" msgid "PGs Active + Undersized + Remapped + Backfill + Toofull" -msgstr "" +msgstr "PGs Active + Undersized + Remapped + Backfill + Toofull" msgid "PGs Active + Undersized + Remapped + Backfill + Wait" -msgstr "" +msgstr "PGs Active + Undersized + Remapped + Backfill + Wait" msgid "PGs Active + Undersized + Remapped + Backfilling" -msgstr "" +msgstr "PGs Active + Undersized + Remapped + Backfilling" msgid "PGs Down" -msgstr "" +msgstr "PGs DOWN" msgid "PGs Incomplete" -msgstr "" +msgstr "PGs unvollständig" msgid "PGs Peering" -msgstr "" +msgstr "PGs Peering" msgid "PGs Remapped + Peering" -msgstr "" +msgstr "PGs Remapped + Peering" msgid "PGs Stale + Active + Clean" -msgstr "" +msgstr "PGs Stale + Active + Clean" msgid "PGs Stale + Active + Undersized + Degraded" -msgstr "" +msgstr "PGs Stale + Active + Undersized + Degraded" msgid "PGs Stale + Undersized + Degraded + Peered" -msgstr "" +msgstr "PGs Stale + Undersized + Degraded + Peered" msgid "PGs Stale + Undersized + Peered" -msgstr "" +msgstr "PGs Stale + Undersized + Peered" msgid "PGs Stale+active + Undersized" -msgstr "" +msgstr "PGs Stale+active + Undersized" msgid "PGs Undersized + Degraded + Peered" -msgstr "" +msgstr "PGs Undersized + Degraded + Peered" msgid "PGs Undersized + Peered" -msgstr "" +msgstr "PGs Undersized + Peered" msgid "PGs Unknown" -msgstr "" +msgstr "PGs UNKNOWN" msgid "PID" msgstr "PID" @@ -44495,12 +44935,15 @@ msgstr "Auslastung paralleler Verbindungen" msgid "Parallel pings to send" msgstr "Parallel zu sendende Pings" -msgid "Parallel plan groups" -msgstr "Parallele Plangruppen" +msgid "Parallel running sequences of plans" +msgstr "Parallel ablaufende Sequenzen von Plänen" msgid "Parallelize core config creation" msgstr "Parallelisiere die Erzeugung der Kernkonfiguration" +msgid "Parameter" +msgstr "Parameter" + msgid "Parameter groups" msgstr "Parametergruppen" @@ -44510,6 +44953,9 @@ msgstr "Parameter-Gruppen pro Region" msgid "Parameter name" msgstr "Parametername" +msgid "Parameter properties" +msgstr "Parametereigenschaften" + msgid "Parameter rule set" msgstr "Parameter-Regelsatz" @@ -44534,6 +44980,9 @@ msgstr "" "Zeichen eingeschlossenen Parameter (Beispiel $HOST$ oder $INST" "$) dargestellt werden." +msgid "Parameters for" +msgstr "Parameter für" + #, python-format msgid "Parameters for %s" msgstr "Parameter für %s" @@ -44541,6 +44990,9 @@ msgstr "Parameter für %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parameter für Eingangsphasen von USVs und PDUs" +msgid "Parameters for notification methods" +msgstr "Parameter der Benachrichtigungsmethoden" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parameter für die Ausgangslasten von USVs und PDUs" @@ -44600,26 +45052,26 @@ msgid "Parameters:" msgstr "Parameter:" msgid "Parent / Child" -msgstr "Eltern / Kind" +msgstr "Parent / Child" msgid "Parent / Child topology" -msgstr "Eltern- / Kinder-Topologie" +msgstr "Parent- / Child-Topologie" msgid "Parent definition" -msgstr "Parenthost-Definition" +msgstr "Parent-Definition" msgid "Parent scan" msgstr "Parent Scan" #, python-format msgid "Parent scan currently running in background." -msgstr "Der Eltern-Scan läuft derzeit im Hintergrund." +msgstr "Der Parent Scan läuft derzeit im Hintergrund." msgid "Parent scan finished" -msgstr "Eltern-Scan abgeschlossen" +msgstr "Parent Scan abgeschlossen" msgid "Parent/child topology" -msgstr "Eltern-/Kind-Topologie" +msgstr "Parent-/Child-Topologie" msgid "Parents" msgstr "Parents" @@ -44765,7 +45217,7 @@ msgid "" "file, relative to the base directory of Robot Framework projects." msgstr "" "Pfad zum Ordner der Robot Framework-Suite oder direkt zu einer bestimmten `." -"robot`-Datei, relativ zum Basisverzeichnis des Robot Framework Projekts." +"robot`-Datei, relativ zum Basisverzeichnis der Robot Framework Projekte." msgid "" "Path to the user certificate. If the path is not exist or empty, the user " @@ -44855,7 +45307,7 @@ msgid "Peers" msgstr "Peers" msgid "Pending" -msgstr "Pending" +msgstr "Ausstehend" msgid "Pending DHCP leases" msgstr "Ausstehende DHCP-Leases" @@ -45230,7 +45682,7 @@ msgid "Perform custom action" msgstr "Führe benutzerdefinierte Aktion aus" msgid "Perform network parent scan" -msgstr "Netzwerk-Parent-Scan ausführen" +msgstr "Netzwerk-Parent Scan ausführen" msgid "Perform periodic service discovery check" msgstr "Periodische Service-Erkennungs-Checks ausführen" @@ -45379,7 +45831,7 @@ msgid "" "Persistent connections are nearly useless with Livestatus Proxy Daemon. " "Better disable it." msgstr "" -"Persistente Verbindungen sind nahezu nutzlos, wenn Sie den Livestaus-Proxy-" +"Persistente Verbindungen sind nahezu nutzlos, wenn Sie den Livestatus Proxy " "Deamon einsetzen. Deaktivieren Sie diese besser." msgid "" @@ -45543,6 +45995,9 @@ msgstr "Die normale IP-Adresse anpingen" msgid "Ping timeout" msgstr "Ping Timeout" +msgid "Placeholder" +msgstr "Platzhalter" + msgid "Placeholder VMs" msgstr "Platzhalter-VMs" @@ -45591,6 +46046,9 @@ msgstr "" "Plan-IDs (Kombinationen von Applikationsnamen, Suite-Namen und Varianten) " "müssen eindeutig sein." +msgid "Plan settings" +msgstr "Plan-Einstellungen" + msgid "Plans" msgstr "Pläne" @@ -45616,6 +46074,10 @@ msgstr "Bitte mindestens eine Spalte zur Ansicht hinzufügen." msgid "Please add at least one endpoint to monitor" msgstr "Bitte mindestens einen Endpunkt für die Überwachung hinzufügen" +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Bitte fügen Sie mindestens einen untergeordneten Knoten hinzu." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -45680,6 +46142,9 @@ msgstr "Bitte wählen Sie ein gültiges PNG-Bild." msgid "Please choose an audit log to view:" msgstr "Bitte wählen Sie ein Audit-Log für die Anzeige aus:" +msgid "Please choose one or more regions to continue" +msgstr "Bitte wählen Sie eine oder mehrere Regionen aus, um fortzufahren" + msgid "Please choose the check plug-in" msgstr "Bitte Check-Plugin auswählen" @@ -45687,7 +46152,7 @@ msgid "" "Please configure at least either the discovery of single interfaces or the " "grouping" msgstr "" -"Bitte konfigurieren Sie mindestens entweder die Erkennung von einzelnen " +"Bitte konfigurieren Sie mindestens die Erkennung von einzelnen " "Schnittstellen oder die Gruppierung" msgid "Please configure proper bind credentials." @@ -46190,7 +46655,7 @@ msgstr "" msgid "Please specify the user and password needed to access the xml interface" msgstr "" "Bitte geben sie den Benutzernamen und das Passwort an, das benötigt wird, um " -"auf das XML Interface zuzugreifen" +"auf das XML-Interface zuzugreifen" msgid "Please specify your administrator login on the remote site." msgstr "Bitte Administrator-Login für Remote-Instanz anlegen." @@ -46304,6 +46769,9 @@ msgstr "Plugins, lokale Checks und MRPE für nicht-root-Benutzer" msgid "Plugin" msgstr "Plugin" +msgid "Plugin output" +msgstr "Plugin-Ausgabe" + msgid "Plugins" msgstr "Plugins" @@ -46444,6 +46912,9 @@ msgstr "Positive Übereinstimmung (Füge der Liste passende Hosts hinzu)" msgid "Positive match (Add matching services to the set)" msgstr "Positive Übereinstimmung (Füge der Liste passende Hosts hinzu)" +msgid "Positive match (Add services hosts to the set)" +msgstr "Positive match (Add services/hosts to the set)" + msgid "Postfix" msgstr "Postfix" @@ -46536,7 +47007,7 @@ msgstr "Gültige Ziffern des Floatwertes" #, python-format msgid "Precision: %d fractional digits, rounding mode: %s" -msgstr "" +msgstr "Genauigkeit: %d Nachkommastellen, Rundungsmodus: %s" msgid "Precompiled" msgstr "Vorkompiliert" @@ -46621,6 +47092,9 @@ msgstr "Zusätzlicher Text" msgid "Prepare AWS for Checkmk" msgstr "AWS für Checkmk vorbereiten" +msgid "Prepare Azure for Checkmk" +msgstr "Azure für Checkmk vorbereiten" + msgid "Prepend namespace prefix for hosts" msgstr "Namespace-Präfix für Hosts voranstellen" @@ -46790,7 +47264,7 @@ msgid "Private memory usage" msgstr "Private Speicherauslastung" msgid "Privilege Level" -msgstr "Privilege Level" +msgstr "Berechtigungsstufe" msgid "Privileged" msgstr "Privilegiert" @@ -47193,7 +47667,7 @@ msgid "Published messages" msgstr "Veröffentlichte Meldungen" msgid "Publisher" -msgstr "Publisher" +msgstr "Herausgeber" msgid "Pull: Checkmk server contacts the agent" msgstr "Pull: Checkmk-Server kontaktiert den Agenten" @@ -47208,13 +47682,13 @@ msgid "Pulse Secure users" msgstr "Pulse Secure Benutzer" msgid "Pure Storage Capacity" -msgstr "Pure Storage Capacity" +msgstr "Reine Speicherkapazität" msgid "Pure Storage FlashArray" msgstr "Pure Storage FlashArray" msgid "Purpose" -msgstr "" +msgstr "Zweck" msgid "Push configuration to this site" msgstr "Konfiguration auf diese Instanz übertragen" @@ -47262,14 +47736,14 @@ msgstr "Python-Version" msgid "Python agent plug-in execution (UNIX)" msgstr "Python Agent Plugin Ausführung (UNIX)" +#, fuzzy msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
path/vars.yaml
set_environment.py:testing" msgstr "" "Python- oder YAML-Datei, aus der Variablen gelesen werden sollen. (not available because Robotmk Core MKP " +"has been installed)" msgstr "RCC-Profilkonfiguration (%s, da Robotmk-Kern-MKP installiert wurde)" +#, fuzzy msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
" +"specific RCC environment, for example proxy settings." msgstr "" "RCC-Profil-Konfiguration: RCC-Profile können Einstellungen für diese " "spezielle RCC-Umgebung festlegen, z. B. Proxy-Einstellungen.
" @@ -48074,6 +48550,9 @@ msgstr "Empfänger" msgid "Recipient email address" msgstr "Empfänger E-Mail-Adresse" +msgid "Recipients" +msgstr "Empfänger" + #, python-format msgid "Recipients: %s" msgstr "Empfänger: %s" @@ -48383,7 +48862,7 @@ msgid "Registry Keys to search for software (Windows)" msgstr "Registrierungsschlüssel, in denen nach Software gesucht wird (Windows)" msgid "Regular Asserts" -msgstr "" +msgstr "Reguläre Asserts" msgid "Regular expression" msgstr "Regulärer Ausdruck" @@ -48556,6 +49035,9 @@ msgstr "Verbleibende Integrität" msgid "Remaining Open Slots" msgstr "Verbleibende offene Slots" +msgid "Remaining certificate validity time" +msgstr "Verbleibende Gültigkeitsdauer des Zertifikats" + msgid "Remaining credits lower levels" msgstr "Untergrenzen für verbleibende Credits" @@ -48578,6 +49060,8 @@ msgid "" "Remaining time (seconds) until the license expires. The defaults equateto 14 " "days (warning) and 7 days (critical)." msgstr "" +"Verbleibende Zeit (Sekunden), bis die Lizenz abläuft. Die Standardwerte " +"entsprechen 14 Tagen (Warnung) und 7 Tagen (kritisch)." msgid "Remaining validity time" msgstr "Verbleibende Gültigkeitsdauer" @@ -48714,9 +49198,6 @@ msgstr "Alle Dateien und Unterverzeichnisse entfernen" msgid "Remove downtimes" msgstr "Wartungszeiten löschen" -msgid "Remove downtimes?" -msgstr "Wartungszeiten entfernen?" - msgid "Remove explicit attribute settings" msgstr "Explizite Attributeinstellungen entfernen" @@ -48746,6 +49227,9 @@ msgstr "Geplante Wartungszeiten entfernen?" msgid "Remove service" msgstr "Entfernter Service" +msgid "Remove smarthost" +msgstr "Smarthost entfernen" + msgid "Remove style" msgstr "Stil entfernen" @@ -49299,6 +49783,9 @@ msgstr "" "Fordert Daten von einem Bazel Remote Cache Instanz Metrics Endpunkt mit " "Version v2.4.1 oder höher an" +msgid "Requests data from a Gerrit instance." +msgstr "Fordert Daten von einer Gerrit-Instanz an." + msgid "Requests data from a Jenkins instance." msgstr "Fordert Daten von einer Jenkins-Instanz an." @@ -49340,6 +49827,9 @@ msgstr "Erforderlich" msgid "Required context filters" msgstr "Erforderliche Kontextfilter" +msgid "Required field missing" +msgstr "Benötigtes Feld fehlt" + msgid "Required match (regular expression)" msgstr "Benötigte Übereinstimmung (regulärer Ausdruck)" @@ -49647,7 +50137,7 @@ msgid "Restrict generation of notifications" msgstr "Erstellung von Benachrichtigungen einschränken" msgid "Restrict interface items" -msgstr "Schnittstellenkennungen festlegen" +msgstr "Elemente der Schnittstelle einschränken" msgid "Restrict monitoring services by one of these AWS tags" msgstr "" @@ -49656,6 +50146,9 @@ msgstr "" msgid "Restrict number of processed messages per cycle" msgstr "Anzahl der verarbeiteten Nachrichten pro Zyklus begrenzen" +msgid "Restrict previous options to" +msgstr "Vorherige Optionen einschränken auf" + msgid "Restrict runtime of logfile parsing" msgstr "Laufzeit des Logdateien-Parsings begrenzen" @@ -49797,6 +50290,13 @@ msgstr "" "Beziehe Informationen über Prozesse mit WMI (Windows Management " "Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" +"Rufen Sie die erforderlichen Informationen ab: Sammeln Sie Subskriptions-ID, " +"Mieter-ID, Client-ID und das Client-Geheimnis von Azure." + msgid "Retry" msgstr "Wiederhole" @@ -49821,6 +50321,9 @@ msgstr "Test wiederholen" msgid "Retry time" msgstr "Wiederholungszeitraum" +msgid "Return WARNING if found, OK if not" +msgstr "Rückgabe WARNING wenn gefunden, OK wenn nicht" + msgid "Return code class 2xx (success)" msgstr "Rückgabecode Klasse 2xx (Erfolg)" @@ -49838,8 +50341,19 @@ msgstr "Zeige Ausführungszeiten innerhalb der Leistungsdaten" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" +"Kehren Sie zu Checkmk zurück, legen Sie einen eindeutigen AWS-Kontonamen " +"fest und verwenden Sie den Zugriffsschlüssel-ID und den geheimen " +"Zugriffsschlüssel unten." + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" +"Kehren Sie zu Checkmk zurück, legen Sie einen eindeutigen Azure-Kontonamen " +"fest und verwenden Sie die Subskritions-ID, Tenant-ID, Client-ID und das " +"Client-Geheimnis unten." msgid "" "Returns the latest crash dumps of each type as found in var/checkmk/crashes" @@ -49859,11 +50373,22 @@ msgstr "Verwerfe fremde Änderungen" msgid "Review and run preview service discovery" msgstr "Überprüfen und Ausführen einer Vorschau der Service-Erkennung" +#, fuzzy +msgid "Review and test configuration" +msgstr "Remote-Konfiguration" + msgid "Review your configuration and run preview service discovery" msgstr "" "Überprüfen Sie Ihre Konfiguration und führen Sie eine Vorschau der Service-" "Erkennung aus" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" +"Überprüfen Sie Ihre Benachrichtigungsregel, bevor Sie sie anwenden. Sie wird " +"sofort wirksam, ohne dass Sie \"Änderungen aktivieren\"." + msgid "Revolutions per minute" msgstr "Umdrehungen pro Minute" @@ -49913,6 +50438,9 @@ msgstr "Robot-Framework: %s" msgid "Robot Framework: Last log" msgstr "Robot-Framework: Letztes Protokoll" +msgid "Robot package" +msgstr "Roboter-Paket" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -50201,8 +50729,9 @@ msgid "" msgstr "" "Regeln, welche die Service-Erkennung beeinflussen. Diese Regeln erlauben z." "B. die Ausführung einer periodischen Service-Erkennung oder die " -"Deaktivierung von Checks und Services. Zusätzlich kann die Erkennung " -"individueller Checks wie z.B. des Interface Checks angepasst werden." +"Deaktivierung von Check-Plugins und Services. Zusätzlich kann die Erkennung " +"individueller Check-Plugins wie z.B. des Schnittstellen-Check-Plugins " +"angepasst werden." msgid "" "Rules to add [active_checks|network services] like HTTP and TCP to the " @@ -50404,14 +50933,14 @@ msgstr "eingebautes SAP Signierungszertifikat" msgid "SAML connections" msgstr "SAML-Verbindungen" -#, fuzzy, python-format +#, python-format msgid "SAML custom encryption certificate for the connection '%s'" msgstr "" -"benutzerdefiniertes SAP Verschlüsselungszertifikat für die Verbindung %s" +"benutzerdefiniertes SAML Verschlüsselungszertifikat für die Verbindung '%s'" #, python-format msgid "SAML custom signing certificate for the connection '%s'" -msgstr "" +msgstr "Benutzerdefiniertes SAML-Signaturzertifikat für die Verbindung '%s'" msgid "SAN" msgstr "SAN" @@ -50547,7 +51076,7 @@ msgstr "SI" #, python-format msgid "SI with symbol %s" -msgstr "" +msgstr "SI mit Symbol %s" msgid "SID" msgstr "SID" @@ -50736,16 +51265,16 @@ msgid "SNMP credentials of monitored hosts" msgstr "SNMP-Zugangsdaten von überwachten Hosts" msgid "SNMP interface check for LANCOM devices" -msgstr "SNMP-Portüberwachung von LANCOM-Geräten" +msgstr "SNMP-Schnittstellenüberwachung von LANCOM-Geräten" msgid "SNMP interface check for TP-Link Switches" -msgstr "SNMP-Portüberwachung von TP-Link-Switches" +msgstr "SNMP-Schnittstellenüberwachung von TP-Link-Switches" msgid "SNMP interface check with 32 bit counters (v1)" -msgstr "SNMP Portüberwachung mit 32-Bit-Zählern (v1)" +msgstr "SNMP-Schnittstellenüberwachung mit 32-Bit-Zählern (v1)" msgid "SNMP interface check with 64 bit counters (using v2c)" -msgstr "SNMP Portüberwachung mit 64-Bit-Zählern (verwendet v2c)" +msgstr "SNMP-Schnittstellenüberwachung mit 64-Bit-Zählern (verwendet v2c)" msgid "SNMP rules" msgstr "SNMP Regeln" @@ -50870,7 +51399,7 @@ msgid "STunnel" msgstr "STunnel" msgid "STunnel status" -msgstr "Tunnel-Status" +msgstr "STunnel-Status" msgid "SUSEConnect (Linux)" msgstr "SUSEConnect (Linux)" @@ -50951,14 +51480,17 @@ msgstr "Als neues Layout für diese Aggregation speichern" msgid "Save response" msgstr "Antwort speichern" -msgid "Save the generated Access key and Secret access key." -msgstr "" -"Speichern Sie den generierten Zugangsschlüssel und den geheimen " -"Zugangsschlüssel." - msgid "Save this host and go to" msgstr "Speichere Host und gehe zu" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" +"Speichern Sie Ihren Fortschritt und gehen Sie auf die Seite Änderungen " +"aktivieren, um sie zu aktivieren. Es kann ein paar Minuten dauern, bis die " +"EC2-Instanzen angezeigt werden." + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "Check-Konfiguration von '%s' mit %d Services gespeichert" @@ -51007,9 +51539,6 @@ msgstr "Wartungszeit für Host festlegen" msgid "Schedule downtime on service" msgstr "Wartungszeit für Service festlegen" -msgid "Schedule downtime?" -msgstr "Wartungszeit planen?" - msgid "Schedule downtimes" msgstr "Wartungszeiten planen" @@ -51062,18 +51591,18 @@ msgid "Scheduling report in background failed: %s" msgstr "Planung von Report in Hintergrund fehlgeschlagen: %s" msgid "Scientific (engineering)" -msgstr "" +msgstr "Wissenschaftlich (Ingenieurwesen)" #, python-format msgid "Scientific (engineering) with symbol %s" -msgstr "" +msgstr "Wissenschaftlich (Ingenieurwesen) mit Symbol %s" msgid "Scientific (standard)" -msgstr "" +msgstr "Wissenschaftlich (Standard)" #, python-format msgid "Scientific (standard) with symbol %s" -msgstr "" +msgstr "Wissenschaftlich (Standard) mit Symbol %s" msgid "" "Scope to be used in LDAP searches. In most cases Search whole subtree " @@ -51366,6 +51895,9 @@ msgstr "Wartezeit in Sekunden zwischen Senden und Abfragen" msgid "Secret access key" msgstr "Geheimer Zugangsschlüssel" +msgid "Secret access key cannot be empty" +msgstr "Geheimer Zugangsschlüssel darf nicht leer sein" + msgid "Secret key" msgstr "Geheimer Schlüssel" @@ -51533,6 +52065,15 @@ msgid "Select and configure AWS services you would like to monitor" msgstr "" "Wählen und konfigurieren Sie die AWS-Services, die Sie überwachen möchten" +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "" +"Wählen und konfigurieren Sie die Microsoft Azure-Services, die Sie " +"überwachen möchten" + +msgid "Select contact group" +msgstr "Kontaktgruppe auswählen" + msgid "Select datasource" msgstr "Datenquelle auswählen" @@ -51578,7 +52119,7 @@ msgid "Select individual files from list" msgstr "Wähle individuelle Dateien aus Liste" msgid "Select interface port type" -msgstr "Schnittstellentypen auswählen" +msgstr "Schnittstellentyp auswählen" msgid "Select metrics to send to InfluxDB" msgstr "Auswahl der an InfluxDB zu sendenden Metriken" @@ -51631,7 +52172,7 @@ msgid "" "within the brackets." msgstr "" "Wählen Sie Tests nach Namen oder nach dem langen Namen aus, der auch den " -"Namen der übergeordneten Suite enthält, z. B. Parent.Test. Der Name " +"Namen der Parent-Suites enthält, z. B. Parent.Test. Der Name " "unterscheidet nicht zwischen Groß- und Kleinschreibung und kann auch ein " "einfaches Muster sein, wobei * auf irgendetwas, ? auf ein " "beliebiges einzelnes Zeichen und [chars] auf ein Zeichen innerhalb " @@ -51749,6 +52290,9 @@ msgstr "Wählen Sie den Typ des Seitenelements" msgid "Select type from list" msgstr "Typ aus der Liste auswählen" +msgid "Select user" +msgstr "Benutzer auswählen" + msgid "Select view" msgstr "Ansicht auswählen" @@ -51762,6 +52306,15 @@ msgid "" "Alternatively you can send the traces to another OpenTelemetry collector via " "OTLP." msgstr "" +"Wählen Sie aus, wohin OpenTelemetry Traces von Checkmk-Diensten gesendet " +"werden sollen. Der einfachste Ansatz besteht darin, Traces an die lokale " +"Jaeger-Instanz der Instanz zu senden. Um dies zu ermöglichen, müssen Sie " +"zusätzlich die globale Einstellung „Support > Traces empfangen“ " +"konfigurieren. Wenn Sie die Rückverfolgung in verteilten Setups durchführen " +"möchten, müssen Sie diese Option nur in der Zentralinstanz konfigurieren und " +"diese Option auf „Traces an die Zentralinstanz der Jaeger Instanz senden“ " +"setzen. Alternativ können Sie die Traces auch über OTLP an einen anderen " +"OpenTelemetry-Kollektor senden." msgid "" "Select which Azure services to monitor.\n" @@ -51785,6 +52338,9 @@ msgstr "Die ausgewählten %s wurden gelöscht." msgid "Selected credential has been deleted" msgstr "Ausgewählte Zugangsdaten wurden gelöscht" +msgid "Selected options" +msgstr "Ausgewählte Optionen" + msgid "Selected sections will not be executed by the agent." msgstr "Ausgewählte Sektionen werden nicht vom Agenten ausgeführt." @@ -51858,6 +52414,9 @@ msgstr "HTTP POST Daten senden" msgid "Send custom notification" msgstr "Individuelle Benachrichtigung senden" +msgid "Send custom notification?" +msgstr "Individuelle Benachrichtigung senden?" + msgid "Send data" msgstr "Daten senden" @@ -51900,12 +52459,10 @@ msgstr "Benachrichtigungen an Event Console senden" msgid "Send notifications to remote Event Console" msgstr "Benachrichtigungen an Remote Event Console senden" -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "" "HTML/ASCII E-Mail-Benachrichtigung gemäß den Benachrichtigungsregeln " -"verschicken (deaktivieren, um Spam zu vermeiden)" +"verschicken" msgid "" "Send regardless of restrictions, e.g. notification period or disabled " @@ -51914,9 +52471,6 @@ msgstr "" "Senden unabhängig von Einschränkungen, z. B. Benachrichtigungsperiode oder " "deaktivierte Benachrichtigungen (erzwungen)" -msgid "Send separate notifications to every recipient" -msgstr "An jeden Empfänger separate Benachrichtigungen versenden" - msgid "Send service metrics to Graphite" msgstr "Service-Metriken an Graphite senden" @@ -51930,13 +52484,13 @@ msgid "Send to remote Event Console via syslog" msgstr "An Remote Event Console über Syslog senden" msgid "Send traces from Checkmk" -msgstr "" +msgstr "Traces von Checkmk senden" msgid "Send traces to another OpenTelemetry collector" -msgstr "" +msgstr "Traces an einen anderen OpenTelemetry-Kollektor senden" msgid "Send traces to site local Jaeger instance" -msgstr "" +msgstr "Traces an die Instanz lokale Jaeger Instanz senden" msgid "Send user message" msgstr "Nutzernachricht senden" @@ -51956,6 +52510,9 @@ msgstr "Per E-Mail versenden" msgid "Sending Power" msgstr "Sendeleistung" +msgid "Sending conditions" +msgstr "Versandbedingungen" + msgid "Sending reply" msgstr "Sende Antwort" @@ -52007,8 +52564,11 @@ msgstr "Trenner" msgid "September" msgstr "September" -msgid "Sequential plans" -msgstr "Sequenzielle Pläne" +msgid "Sequence execution interval" +msgstr "Ausführungsintervall der Sequenz" + +msgid "Sequence of plans" +msgstr "Sequenz von Plänen" msgid "Serial" msgstr "Seriennummer" @@ -52070,7 +52630,7 @@ msgid "Service (exact match)" msgstr "Service (genaue Übereinstimmung)" msgid "Service (regex)" -msgstr "Service (regex)" +msgstr "Service (Regex)" msgid "Service Checks" msgstr "Service-Checks" @@ -52237,6 +52797,9 @@ msgstr "Service-Erkennung: Service-Name" msgid "Service discovery: State" msgstr "Service-Erkennung: Zustand" +msgid "Service events" +msgstr "Service-Ereignisse" + msgid "Service goes into critical state" msgstr "Service in Status CRIT gewechselt" @@ -52556,6 +53119,9 @@ msgstr "Services der Instanz" msgid "Services per cluster" msgstr "Services pro Cluster" +msgid "Services per region" +msgstr "Services pro Region" + msgid "Services per region to monitor" msgstr "Zu überwachende Dienste pro Region" @@ -52850,8 +53416,8 @@ msgid "" "'Activate only services matching', both rules have to apply for a service to " "be activated." msgstr "" -"Setzen Sie hier Service-Namen oder reguläre Ausdrücke, um passende Services " -"nicht automatisch zu aktivieren. Wenn Sie dies zusammen mit \"Nur " +"Geben Sie hier Service-Namen oder reguläre Ausdrücke ein, um passende " +"Services nicht automatisch zu aktivieren. Wenn Sie dies zusammen mit \"Nur " "zutreffende Services aktivieren\" verwenden, müssen beide Regeln zutreffen " "damit ein Service aktiviert wird." @@ -52861,7 +53427,7 @@ msgid "" "only matching vanished services', both rules have to apply for a service to " "be removed." msgstr "" -"Legen Sie hier Service-Namen oder Muster für reguläre Ausdrücke fest, um das " +"Geben Sie hier Service-Namen oder Muster für reguläre Ausdrücke ein, um das " "automatische Entfernen passender verschwundener Services zu verhindern. Wenn " "Sie sowohl dies als auch 'Verschwundene Services entfernen' einstellen, " "müssen beide Regeln zutreffen, damit ein Service entfernt wird." @@ -52872,7 +53438,7 @@ msgid "" "matching vanished services', both rules have to apply for a service to be " "removed." msgstr "" -"Stellen Sie hier Service-Namen oder Muster für reguläre Ausdrücke ein, um " +"Geben Sie hier Service-Namen oder Muster für reguläre Ausdrücke ein, um " "passende verschwundene Services automatisch zu entfernen. Wenn Sie sowohl " "dies als auch 'Verschwundene Services nicht entfernen' einstellen, müssen " "beide Regeln zutreffen, damit ein Service entfernt wird." @@ -53015,6 +53581,8 @@ msgstr "Breite setzen" msgid "" "Set this in order to specify the name of mode the virtual host for the query." msgstr "" +"Legen Sie dies fest, um den Namen des Modus für den virtuellen Host für die " +"Abfrage anzugeben." msgid "Set this ntopng instance active" msgstr "Diese ntopng Instanz aktiv setzen" @@ -53061,18 +53629,19 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." msgstr "" -"Setzt ein Limit für die Anzahl an Sammelbenachrichtigungen für welche " -"Graphen angezeigt werden. Wenn keine Sammelbenachrichtigungen verwendet " -"werden wird diese Option ignoriert. Merke: Jeder Graph erhöht die Größe der " -"Mail und benötigt Zeit um am Monitoring-Server gerendered zu werden. " -"Deswegen können große Ansammlungen die maximale Größe an Anhängen " -"überschreiten oder das Plugin kann in eine Zeitüberschreitung laufen wodurch " -"eine fehlgeschlagene Benachrichtigung erzeugt wird." +"Legt ein Limit für die Anzahl der Benachrichtigungen in einer Sammlung " +"(Bulk) fest, für die Graphen angezeigt werden. Wenn Sie keine " +"Sammelbenachrichtigungen verwenden, wird diese Option ignoriert. Merke: " +"Jeder Graph erhöht die Größe der E-Mail und benötigt Zeit zum Rendern auf " +"dem Monitoring-Server. Daher kann bei großen Sammlungen die maximale Größe " +"für Anhänge überschritten werden oder das Plugin kann in eine " +"Zeitüberschreitung laufen, wodurch eine fehlgeschlagene Benachrichtigung " +"erzeugt wird." msgid "" "Sets custom user attributes based on the group memberships in LDAP. This " @@ -53114,7 +53683,7 @@ msgstr "" "Services anders als OK sein können, wenn Laufzeiten überschritten wurden." msgid "Sets the user of the alert. Display name of the request owner." -msgstr "" +msgstr "Legt den Benutzer des Alerts fest. Anzeige-Name des Anfragestellers." msgid "" "Sets thresholds for the runtime of a KPI. Note that runtime monitoring is " @@ -53223,7 +53792,7 @@ msgstr "" "Ihrer multisite.mk, wenn Sie das Setup-Menü verwenden möchten." msgid "Setup shortcuts" -msgstr "" +msgstr "Shortcuts einrichten" msgid "Setup, site management" msgstr "Installation, Instanzverwaltung" @@ -53437,6 +54006,9 @@ msgstr "Checkboxen anzeigen" msgid "Show column headings" msgstr "Spaltentitel anzeigen" +msgid "Show contact groups" +msgstr "Kontaktgruppen anzeigen" + msgid "Show context" msgstr "Kontext anzeigen" @@ -53503,9 +54075,15 @@ msgstr "Hinweis im Menü \"Benutzer\" anzeigen" msgid "Show historic values" msgstr "Historische Werte anzeigen" +msgid "Show host labels" +msgstr "Host-Labels anzeigen" + msgid "Show host status" msgstr "Host-Status anzeigen" +msgid "Show host tags" +msgstr "Host-Tags anzeigen" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Symbol anzeigen, das auf den Setup-Parameter-Editor für Dienste verweist" @@ -53580,6 +54158,10 @@ msgstr "Zeige mehr / Zeige weniger" msgid "Show notification bulks" msgstr "Benachrichtigungs-Bulks anzeigen" +msgid "Show notification rule that triggered the notification" +msgstr "" +"Benachrichtigungsregel anzeigen, welche die Benachrichtigung ausgelöst hat" + msgid "Show number of groups" msgstr "Anzahl der Gruppen anzeigen" @@ -53641,6 +54223,9 @@ msgstr "Regeln mit diesem %s anzeigen" msgid "Show separate result for each SLA period" msgstr "Zeige separates Ergebnis für jede SLA Periode" +msgid "Show service labels" +msgstr "Service-Labels anzeigen" + msgid "Show service name" msgstr "Service-Name anzeigen" @@ -54023,6 +54608,13 @@ msgstr "" "Zweifelsfall der bevorzugte). Sie können diesen Automatismus außer Kraft " "setzen, indem Sie hier einen Knoten angeben." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" +"Da verwaltete Roboter in Bäckereiregeln verwendet werden, benötigen Sie die " +"Berechtigung zur Bearbeitung dieser Regeln, um auf diese Seite zuzugreifen." + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -54193,7 +54785,7 @@ msgstr "" "Instanz nutzt HTTP im Klartext. Prüfen Sie, ob Sie HTTPS aktivieren können." msgid "Site is using the Livestatus Proxy Daemon" -msgstr "Instanz nutzt den Livestatus-Proxy-Daemon" +msgstr "Instanz nutzt den Livestatus Proxy Daemon" msgid "Site management" msgstr "Instanzverwaltung" @@ -54405,7 +54997,7 @@ msgid "Slab (Various smaller caches)" msgstr "Slab (Verschiedene kleinere Caches)" msgid "Slack Webhooks must use HTTPS." -msgstr "" +msgstr "Slack Webhooks erfordern HTTPS." msgid "Slave usage bytes across all pools" msgstr "Remote Byte Nutzung über alle Pools" @@ -54883,7 +55475,7 @@ msgid "Source Path" msgstr "Quellpfad" msgid "Source association changed" -msgstr "" +msgstr "Quellenzuordnung geändert" msgid "" "Source field of the alert. Default value is IP address of the incoming " @@ -54932,6 +55524,9 @@ msgstr "Bestimmte Objekte" msgid "Specific sites" msgstr "Bestimmte Instanzen" +msgid "Specific users" +msgstr "Bestimmte Benutzer" + msgid "Specific version" msgstr "Bestimmte Version" @@ -54954,17 +55549,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Gibt den Standard-Linienstil an" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" -"Gibt die maximale Zeit an, die der Scheduler für die Ausführung eines Robot " -"Frameworks zulässt. Diese Zeit, multipliziert mit der Anzahl der " -"wiederholten Ausführungen, darf in der Summe mit allen anderen Plänen in " -"dieser Gruppe nicht größer sein als das Gruppenausführungsintervall." - msgid "Specifies whether password authentication is allowed" msgstr "Gibt an, ob die Passwortauthentifizierung erlaubt ist" @@ -55132,21 +55716,10 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" "Geben Sie hier an, ob das Arbeitsverzeichnis von Robotmk (`/var/lib/" -"check_mk_agent/robotmk/working/suites`) auf dem Zielhost entweder nach einer " -"bestimmten Zeit oder nach einer bestimmten Anzahl von Testausführungen " +"check_mk_agent/robotmk/working/suites`) auf dem Ziel-Host entweder nach " +"einer bestimmten Zeit oder nach einer bestimmten Anzahl von Testausführungen " "bereinigt werden soll." -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" -"Geben Sie hier an, ob das Arbeitsverzeichnis von Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites\\`) auf dem Zielhost " -"entweder nach einer bestimmten Zeit oder nach einer bestimmten Anzahl von " -"Testausführungen bereinigt werden soll." - #, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -55283,11 +55856,11 @@ msgid "" "com'
  • China: Login into 'https://login.partner.microsoftonline.cn', " "get data from 'https://microsoftgraph.chinacloudapi.cn'
  • " msgstr "" -"Wählen Sie die Behörde, mit der Sie sich verbinden wollen:
    • Weltweit: " -"Melden Sie sich bei 'https://login.microsoftonline.com' an, die Daten " -"erhalten Sie von 'https://graph.microsoft.com'
    • China: Melden Sie " -"sich bei 'https://login.partner.microsoftonline.cn' an, die Daten erhalten " -"Sie von 'https://microsoftgraph.chinacloudapi.cn'
    " +"Wählen Sie die Einrichtung, mit der Sie sich verbinden wollen:" +"
    • Weltweit: Melden Sie sich bei 'https://login.microsoftonline.com' " +"an, die Daten erhalten Sie von 'https://graph.microsoft.com'
    • China: " +"Melden Sie sich bei 'https://login.partner.microsoftonline.cn' an, die Daten " +"erhalten Sie von 'https://microsoftgraph.chinacloudapi.cn'
    " msgid "" "Specify the destination path in the format Path/To/Folder, for " @@ -55587,6 +56160,13 @@ msgstr "" "Geben Sie hier an, was passieren soll, wenn der gewählte Graph fehlt oder " "nicht geholt werden kann." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" +"Legen Sie fest, wann und wie Benachrichtigungen gesendet werden, basierend " +"auf Kriterien wie Häufigkeit, Zeitpunkt und Inhalt." + msgid "Specify which port types should not be discovered" msgstr "Festlegen, welche Porttypen nicht erkannt werden sollen" @@ -55611,7 +56191,7 @@ msgid "Speed" msgstr "Geschwindigkeit" msgid "Speed of interface groups (Netapp only)" -msgstr "Geschwindigkeit der Interface-Gruppen (nur Netapp)" +msgstr "Geschwindigkeit der Schnittstellengruppen (nur Netapp)" msgid "Splunk" msgstr "Splunk" @@ -55805,6 +56385,9 @@ msgstr "Anfang des nächsten Jahres" msgid "Start or end of a scheduled downtime" msgstr "Beginn oder Ende einer geplanten Wartungszeit" +msgid "Start or end of downtime" +msgstr "Anfang oder Ende der Wartungszeit" + msgid "Start or end of flapping state" msgstr "Beginn oder Ende einer Unstetigkeit" @@ -56016,6 +56599,13 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Status für bestimmte Bindungsarten" +msgid "State for unexpected number of interfaces" +msgstr "Status für unerwartete Anzahl an Schnittstellen" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Ausstehende Service-Erkennung" + msgid "State if 'maintenance' services are found" msgstr "Zustand, falls 'Maintainane'-Services gefunden werden" @@ -56937,6 +57527,7 @@ msgstr "Streng - Sichtbar, wenn der Benutzer ein Kontakt für den Service ist" msgid "Strict: Round the fractional part to the given fractional digits." msgstr "" +"Streng: Rundet den Bruchteil auf die angegebene Anzahl von Nachkommastellen." msgid "String" msgstr "String" @@ -57010,11 +57601,11 @@ msgstr "Subjektname" msgid "Subject for bulk notifications" msgstr "Betreff für Sammelbenachrichtigungen" -msgid "Subject for host notifications" -msgstr "Betreff für Host-Benachrichtigungen" +msgid "Subject line for host notifications" +msgstr "Betreffzeile für Host-Benachrichtigungen" -msgid "Subject for service notifications" -msgstr "Betreff für Service-Benachrichtigungen" +msgid "Subject line for service notifications" +msgstr "Betreffzeile für Service-Benachrichtigungen" msgid "Submit" msgstr "Anwenden" @@ -57316,7 +57907,7 @@ msgid "Symantec Brightmail Queues" msgstr "Symantec Brightmail-Queues" msgid "Symbol" -msgstr "" +msgstr "Symbol" msgid "Symmetric encryption (Linux, Windows)" msgstr "Symmetrische Verschlüsselung (Linux, Windows)" @@ -57392,6 +57983,10 @@ msgstr "Synchron" msgid "Syncing" msgstr "Synchronisieren" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "SAP Router Zertifikat" + msgid "Synology Updates" msgstr "Updates für Synology" @@ -57427,7 +58022,7 @@ msgid "Syslog application to cancel event" msgstr "Ereignis abbrechen bei Syslog-Anwendung" msgid "Syslog facility" -msgstr "Syslog-Einrichtung" +msgstr "Syslog Facility" msgid "Syslog facility for Event Console notifications" msgstr "Event Console Benachrichtigungen ausliefern mit Syslog Facility" @@ -57442,34 +58037,34 @@ msgstr "" msgid "Syslog facility of forwarded logs shown in Event Console." msgstr "" -"Syslog-Einrichtung für weitergeleitete Logs, die in der Event Console " -"angezeigt werden." +"Syslog Facility für weitergeleitete Logs, die in der Event Console angezeigt " +"werden." msgid "Syslog facility to use" msgstr "zu verwendende Syslog Facility" msgid "Syslog priority" -msgstr "Syslog-Priorität" +msgstr "Syslog Priority" msgid "Syslog priority of forwarded events shown in Event Console." msgstr "" -"Syslog-Priorität der weitergeleiteten Ereignisse, die in der Event Console " +"Syslog Priority der weitergeleiteten Ereignisse, die in der Event Console " "angezeigt werden." msgid "Syslog priority to cancel event" -msgstr "Ereignis abbrechen bei Syslog-Priority" +msgstr "Ereignis abbrechen bei Syslog Priority" msgid "Syslog tag / Application" msgstr "Syslog-Tag / Anwendung" msgid "Syslog-Facility" -msgstr "Syslog-Facility" +msgstr "Syslog Facility" msgid "Syslog-Priority" -msgstr "Syslog-Priority" +msgstr "Syslog Priority" msgid "Syslog-like message logging" -msgstr "Meldungen in wie Syslog in Dateien schreiben" +msgstr "Syslog-ähnliche Nachrichtenprotokollierung" msgid "System" msgstr "System" @@ -57511,7 +58106,7 @@ msgid "System messages" msgstr "System Meldungen" msgid "System metrics (requires 'Metrics' plugin in Jenkins)" -msgstr "" +msgstr "Systemmetriken (erfordert 'Metrics'-Plugin in Jenkins)" msgid "System name" msgstr "Systemname" @@ -57568,7 +58163,7 @@ msgid "Systems larger than" msgstr "Systeme größer als" msgid "TBD" -msgstr "" +msgstr "noch offen" msgid "TCP" msgstr "TCP" @@ -57668,6 +58263,9 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLS-Authentifizierung ohne TLS ist nicht möglich" +msgid "TLS certificate verification" +msgstr "Verifizierung des TLS-Zertifikats" + msgid "TLS processed bytes" msgstr "Verarbeitete Bytes über TLS" @@ -57873,6 +58471,15 @@ msgid "Tags can be used to classify hosts and services in a flexible way." msgstr "" "Mit Hilfe von Tags können Hosts und Services flexibel klassifiziert werden." +msgid "Tags enabled but no key defined." +msgstr "Tags aktiviert, aber kein Schlüssel definiert." + +msgid "Tags enabled but no tags defined." +msgstr "Tags aktiviert, aber keine Tags definiert." + +msgid "Tags enabled but no values defined." +msgstr "Tags aktiviert, aber keine Werte definiert." + #, python-format msgid "Tags of the alert.

    %s" msgstr "Merkmale des Alerts.

    %s" @@ -58100,6 +58707,10 @@ msgstr "" msgid "Test authentication" msgstr "Test-Authentifizierung" +#, fuzzy +msgid "Test configuration" +msgstr "Hostkonfiguration" + msgid "Test connection" msgstr "Prüfe Verbindung" @@ -58129,6 +58740,9 @@ msgstr "Benachrichtigungen testen auf" msgid "Test runtime" msgstr "Testlaufzeit" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + msgid "Test verification" msgstr "Testverifizierung" @@ -58717,8 +59331,8 @@ msgstr "" "Das Inotify (Inode notify) ist ein Subsystem im Linux Kernel, welches in der " "Lage ist bestimmte Events im Dateisystem erkennen. Das Inotify Plugin " "erkennt diese Änderungen und meldet diese ans Monitoring-System. Auf dem " -"Zielhost muss für den Betrieb dieses Plugins auch das Python Modul pynotify " -"installiert sein." +"Zielsystem muss für den Betrieb dieses Plugins auch das Python Modul " +"pynotify installiert sein." msgid "" "The Inotify is running permanently on the target system and expects regular " @@ -58796,9 +59410,9 @@ msgid "" "Using the Livestatus Proxy Daemon improves the responsiveness and " "performance of your GUI and will decrease resource usage." msgstr "" -"Der Livestatus-Proxy-Daemon ist in der Checkmk Enterprise Edition enthalten " +"Der Livestatus Proxy Daemon ist in der Checkmk Enterprise Edition enthalten " "und verbessert die Behandlung der Verbindungen zwischen mehreren Instanzen. " -"Durch die Nutzung des Livestatus-Proxy-Daemon verbessern Sie die Antwortzeit " +"Durch die Nutzung des Livestatus Proxy Daemon verbessern Sie die Antwortzeit " "und die Performance Ihrer Oberfläche bei gleichzeitiger Reduktion der " "Ressourcennutzung." @@ -59362,6 +59976,9 @@ msgstr "" "Die Zentralinstanz (%s) und die Remote-Instanz (%s) sind nicht kompatibel. " "Grund: %s" +msgid "The changes have been activated successfully." +msgstr "Die Änderungen wurden erfolgreich aktiviert." + #, python-format msgid "The character %s is not allowed here." msgstr "Das Zeichen %s ist hier nicht erlaubt." @@ -59498,7 +60115,7 @@ msgid "The configuration \"%s\" does not exist." msgstr "Die Konfiguration \"%s\" existiert nicht." msgid "The configuration bundle does not contain all required objects." -msgstr "" +msgstr "Das Konfigurationsbündel enthält nicht alle erforderlichen Objekte." msgid "The configuration is currently in read only mode. " msgstr "Die Konfiguration ist aktuell schreibgeschützt. " @@ -59609,8 +60226,8 @@ msgid "" "This violates the CME folder hierarchy." msgstr "" "Die konfigurierte Zielinstanz gehört dem Default-Kunden %s. Der " -"Eltern-Ordner jedoch, hat bereits den speziellen Kunden %s gesetzt. " -"Das verletzt die CME Ordner Hierarchie." +"übergeordnete Ordner jedoch, hat bereits den speziellen Kunden %s " +"gesetzt. Das verletzt die CME Ordner Hierarchie." msgid "" "The configured value for a host is accessible in notifications as well via " @@ -59651,6 +60268,11 @@ msgstr "" "Die Verbindung erstellt Hosts in diesem spezifischen Ordner. Sie können die " "Hosts anschließend nach Belieben in einen anderen Ordner verschieben." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "Die Verbindung zu dieser Instanz wurde deaktiviert." @@ -59916,25 +60538,6 @@ msgstr "Das Element kann nicht auf dem Dashboard gefunden werden." msgid "The element does not exist." msgstr "Das Element ist nicht vorhanden." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"Die E-Mail-Adresse und der sichtbare Name, die im Absender-Header von " -"Benachrichtigungsmeldungen verwendet werden. Wenn keine E-Mail-Adresse " -"angegeben ist, wird die Standardadresse OMD_SITE@FQDN verwendet. " -"Wenn die Umgebungsvariable OMD_SITE nicht gesetzt ist, wird sie " -"standardmäßig auf checkmk gesetzt." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"Die E-Mail-Adresse und der sichtbare Name, die im Reply-To-Header von " -"Benachrichtigungsnachrichten verwendet werden." - msgid "" "The email address is optional and is needed if the user is a monitoring " "contact and receives notifications via email." @@ -59986,7 +60589,7 @@ msgid "" "here and are available in the sidebar snap-in Event Console performance" msgstr "" -"Der Event-Daemon führt Statistiken über die Anzahl von Nachrichten, Treffer " +"Der Event Daemon führt Statistiken über die Anzahl von Nachrichten, Treffer " "für Ereignisregeln und anderen Dingen. Diese Werte werden im hier " "festgelegten Zeitintervall aktualisiert und im Seitenleisten-Snapin Event " "Console Leistungsdaten angezeigt" @@ -60187,7 +60790,7 @@ msgid "The found hosts' children (with child filtering)" msgstr "Die Child Hosts der gefundenen Hosts (mit Child-Filter)" msgid "The found hosts' parents" -msgstr "Die 'Parents' des Hosts" +msgstr "Die Parents des gefundenen Hosts" msgid "" "The full URL to the Cluster Collector service including the protocol (http " @@ -60300,15 +60903,6 @@ msgstr "Die Graph-Spezifikation fehlt" msgid "The graph template id '%s' is disabled" msgstr "Die Graphenvorlage id '%s' ist deaktiviert" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" -"Das Gruppenausführungsintervall muss größer sein als die Summe der einzelnen " -"Planlaufzeitgrenzen. Die Laufzeitgrenze eines Plans wird wie folgt " -"berechnet: Limit_pro_Versuch x (1 + max_Anzahl_der_Wiederholungen)." - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -60534,17 +61128,6 @@ msgstr "" "Der Instanzname, der Datenbankname und der Tablespace-Name, wie folgt " "zusammengesetzt: db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" -"Das Intervall, in dem eine Ausführungsgruppe ausgeführt wird. Das Intervall " -"muss größer sein als die Summe der individuellen Planlaufzeitgrenzen. Die " -"Laufzeitgrenze eines Plans wird wie folgt berechnet: Limit_pro_Versuch x " -"(1 + max_Anzahl_der_Wiederholungen)." - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -60594,7 +61177,7 @@ msgstr "" "Beschreibung: %s)" msgid "The key file is invalid or the password is wrong." -msgstr "" +msgstr "Die Schlüsseldatei ist ungültig oder das Passwort ist falsch." msgid "" "The key size is provided as an integer and needs to match exactly the value " @@ -60865,8 +61448,8 @@ msgid "" "in between." msgstr "" "Die maximale, durchschnittliche Paketumlaufzeit in Millisekunden, bevor " -"dieser Service in WARN/CRIT wechselt. Dieser Alarm wird nur auf den Zielhost " -"angewendet, nicht auf die einzelnen Hops." +"dieser Service in WARN/CRIT wechselt. Dieser Alarm wird nur auf den Ziel-" +"Host angewendet, nicht auf die einzelnen Hops." msgid "The maximum key length is 128 characters." msgstr "Die maximale Schlüssellänge beträgt 128 Zeichen." @@ -60929,9 +61512,19 @@ msgid "" "host, not the hops in between." msgstr "" "Die maximale Standardabweichung der Paketumlaufzeit in Millisekunden, bevor " -"der Service in WARN/CRIT wechselt. Dieser Alarm wird nur auf den Zielhost " +"der Service in WARN/CRIT wechselt. Dieser Alarm wird nur auf den Ziel-Host " "angewendet, nicht auf die einzelnen Hops." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" +"Die maximale Zeit, die der Robotmk-Scheduler für eine einzelne Robot " +"Framework-Ausführung zulässt. Diese Zeit, multipliziert mit der Anzahl der " +"Ausführungen, legt die maximale Gesamtlaufzeit für die Ausführung eines " +"Plans fest." + msgid "The maximum value length is 256 characters." msgstr "Die maximale Wertlänge beträgt 256 Zeichen." @@ -61172,7 +61765,8 @@ msgstr "" "empfohlen. Er wird aus Gründen der Rückwärtskompatibilität beibehalten." msgid "The name of the interface (Public/Private IPv4/IPv6 Network Interface)" -msgstr "Name der Schnittstelle (Public/Private IPv4/IPv6 Netzwerkinterface)" +msgstr "" +"Name der Schnittstelle (Public/Private IPv4/IPv6 Netzwerkschnittstelle)" msgid "" "The name of the macro (including the '$'s) which contains the port number. " @@ -61210,6 +61804,8 @@ msgid "" "The name of the team where the integration was created. If this field is " "set, additional information can be added to alerts." msgstr "" +"Der Name des Teams, in dem die Integration erstellt wurde. Wenn dieses Feld " +"gesetzt ist, können zusätzliche Informationen zu Alerts hinzugefügt werden." msgid "The name of the view may only contain letters, digits and underscores." msgstr "Gültige Zeichen im Namen: Buchstaben, Ziffern und _." @@ -61373,7 +61969,7 @@ msgid "" "accordingly." msgstr "" "Die Anzahl der Sekunden, die eine Cache-Datei alt sein darf, wenn Checkmk " -"sie verwenden soll anstatt Informationen von den Zielhosts während der " +"sie verwenden soll anstatt Informationen von den Ziel-Hosts während der " "Überprüfung eines Clusters zu erhalten. Standardmäßig ist dies aktiviert und " "auf 90 Sekunden eingestellt. Wenn Ihr Prüfzyklus auf einen größeren Wert als " "eine Minute eingestellt ist, sollten Sie diesen Wert entsprechend erhöhen." @@ -61538,7 +62134,7 @@ msgstr "" "Der Parent '%s' wird auf Instanz '%s' überwacht, der Host auf Instanz '%s'. " "Beide müssen auf derselben Instanz überwacht werden. Wichtig: Die Parent/" "Child-Beziehung wird benutzt um die Erreichbarkeit von Hosts eines " -"Monitoring-Daemons zu beschreiben." +"Monitoring Daemons zu beschreiben." msgid "" "The parent scan will try to detect the last gateway on layer 3 (IP) before a " @@ -62553,7 +63149,7 @@ msgid "The text" msgstr "Der Text" msgid "The text entered here is handled as a regular expression pattern." -msgstr "Der eingegebene Text wird als Regulärer Ausdruck behandelt." +msgstr "Der eingegebene Text wird als regulärer Ausdruck behandelt." msgid "" "The text entered here well be prefixed to the host name. Ending the prefix " @@ -62605,6 +63201,28 @@ msgstr "" "Die Schwellwerte für wait_duration_ms. Überschreibt den oben eingestellten " "Standardstatus." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" +"Das Zeitintervall für die Ausführung einer Sequenz von Plänen muss größer " +"sein als die Summe aller Gesamtplanlaufzeitgrenzen. Die Gesamtlaufzeitgrenze " +"eines Plans wird wie folgt berechnet: Limit_pro_Versuch x (1 + " +"max_Anzahl_der_Wiederholungen)." + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" +"Das Zeitintervall für die Ausführung einer Sequenz von Plänen. Dieses " +"Intervall muss größer sein als die Summe aller Gesamtplanlaufzeitgrenzen. " +"Die Gesamtlaufzeitgrenze eines Plans wird wie folgt berechnet: " +"Limit_pro_Versuch x (1 + max_Anzahl_der_Wiederholungen)." + msgid "The time interval statistical data is saved to disk" msgstr "Das Zeitinterval mit dem die statistischen Daten abgespeichert werden" @@ -62765,6 +63383,13 @@ msgid "The username returned by the %s connector is not of type string (%r)." msgstr "" "Der vom Konnektor %s gelieferte Benutzername ist nicht vom Typ string (%r)." +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"Der Benutzername, der für den Zugriff auf die Gerrit-API verwendet werden " +"soll. Dieser muss (mindestens) Leserechte haben." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -63066,8 +63691,8 @@ msgid "There is no backup job configured" msgstr "Es ist kein Sicherungs-Job konfiguriert" #, python-format -msgid "There is no graph template with the id '%s'" -msgstr "Es gibt keine Graph-Vorlage mit der Id '%s'" +msgid "There is no graph graph_plugin with the id '%s'" +msgstr "Es gibt keinen Graph graph_plugin mit der Id '%s'" msgid "There is no manpage for this check." msgstr "Für diesen Check gibt es keine Beschreibung." @@ -63244,10 +63869,11 @@ msgstr "Diese Knoten sind nicht in der eingefrorenen Aggregation" msgid "These nodes are only in the frozen aggregation" msgstr "Diese Knoten sind nur in der eingefrorenen Aggregation" +#, fuzzy msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" "Diese Optionen ermöglichen die Angabe der gebräuchlichsten " "Kommandozeilenparameter für das Robot Framework. Um andere Parameter zu " @@ -63566,6 +64192,11 @@ msgstr "" "Sie auch den Agent Controller auf dem überwachten Host zurücksetzen (siehe " "`cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" +"Diese Aktion wirkt sich auf alle ausstehenden Änderungen aus, die Sie " +"vorgenommen haben." + msgid "" "This active check sends out special emails to a defined mail address using " "either the SMTP protocol or an EWS connection and then tries to receive " @@ -63585,7 +64216,7 @@ msgid "" "failover to a secondary route." msgstr "" "Dieser aktive Check verwendet traceroute, um das aktuelle Routing " -"vom Monitoring-Host zum Zielhost zu ermitteln. Sie können eine beliebige " +"vom Monitoring-Host zum Ziel-Host zu ermitteln. Sie können eine beliebige " "Anzahl von fehlenden oder erwarteten Routen angeben, um z. B. einen " "(unbeabsichtigten) Failover auf eine sekundäre Route zu erkennen." @@ -63942,7 +64573,7 @@ msgid "This collection as PDF" msgstr "Diese Kollektion als PDF" msgid "This command will be executed on the target host." -msgstr "Dieser Befehl wird auf dem Zielhost ausgeführt." +msgstr "Dieser Befehl wird auf dem Ziel-Host ausgeführt." msgid "This condition makes the rule match only hosts of the selected sites." msgstr "" @@ -64221,6 +64852,7 @@ msgstr "Der Zustand dieses Hosts oszilliert" msgid "" "This host is missing one or more of the labels: %s (it has the labels %s)" msgstr "" +"Diesem Host fehlen ein oder mehrere der Labels: %s (er hat das Label %s)" msgid "This host is stale" msgstr "Dieser Hostzustand ist veraltet" @@ -64306,7 +64938,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -64314,10 +64946,10 @@ msgid "" msgstr "" "Dies ist im Wesentlichen das rohe Agent Updater-Skript, das in den " "Binärversionen verpackt wird. Sie müssen sich selbst um die Abhängigkeiten " -"kümmern. Das Skript erfordert eine Installation von Python 3.4 (oder höher) " +"kümmern. Das Skript erfordert eine Installation von Python 3.7 (oder höher) " "und die passenden Python-Pakete \"requests\", \"PySocks\" und \"cryptography" -"\" auf den Zielhosts. Die Anforderungen können sich eventuell ohne " -"Ankündigung ändern. Dies könnte dennoch die richtige Wahl für erfahrene " +"\" auf den Ziel-Hosts. Die Anforderungen können sich eventuell ohne " +"Ankündigung ändern. Dies könnte jedoch die richtige Wahl für erfahrene " "Benutzer oder Benutzer sein, die den Agent Updater auf Architekturen wie " "ARM, ppc oder anderen ausführen möchten." @@ -64823,6 +65455,11 @@ msgid "" "addition to this option, you need to configure the global setting \"Support " "> Send traces from Checkmk\"." msgstr "" +"Diese Option ermöglicht den Empfang von OpenTelemetry-Traces in einer Jaeger-" +"Instanz, die auf der Checkmk-Instanz läuft. Diese Instanz wird zu " +"Diagnosezwecken von Checkmk betrieben und ist derzeit nicht für externe " +"Anwendungsfälle vorgesehen. Zusätzlich zu dieser Option müssen Sie die " +"globale Einstellung \"Support > Traces von Checkmk senden\" konfigurieren." msgid "" "This option enables the Event Console - The event processing and " @@ -64938,7 +65575,7 @@ msgid "" "port number as item." msgstr "" "Mit dieser Option kann Checkmk entweder die Schnittstellenbeschreibung, den " -"Alias oder die Portnummer als Element verwenden." +"Alias oder die Port-Nummer als Element verwenden." msgid "" "This option makes the HTTP check produce more detailed performance data " @@ -65163,11 +65800,10 @@ msgstr "" "gilt, nicht für die anderer Benutzer (fremde Änderungen)." msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" -"Mit dieser Berechtigung können Benutzer verwaltete Roboter administrieren " -"(hinzufügen, löschen, ändern)." +"Diese Berechtigung erlaubt Benutzern die Bearbeitung (hinzufügen, löschen, " +"ändern) von verwalteten Robotern." msgid "" "This permission allows users to migrate other users to another connection" @@ -65222,7 +65858,7 @@ msgid "" msgstr "" "Diese Berechtigung ist für die Aktivierung der aktuellen Konfiguration " "notwendig (und somit für das Neuschreiben der Monitoring-Konfiguration und " -"den Neustart des Monitoring-Daemons.)" +"den Neustart des Monitoring Daemons.)" msgid "" "This permission is needed for creating alert handlers, which automatically " @@ -65736,13 +66372,6 @@ msgstr "" "eines dieser Parameter führt zu häufigen Änderungen in der HW-/SW-Inventur, " "wodurch sich das temporäre Dateisystem schnell füllen kann." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Diese Regel ermöglicht das Monitoring von VMware ESXi über die vSphere-API. " -"Sie können Ihre Verbindungseinstellungen hier konfigurieren." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -65844,7 +66473,7 @@ msgid "" "to the controller." msgstr "" "Mit dieser Regel können Sie Controller-Verbindungen in ein Agentenpaket " -"einbacken. Beim Start stellt der Controller-Daemon sicher, dass Verbindungen " +"einbacken. Beim Start stellt der Controller Daemon sicher, dass Verbindungen " "zu den angegebenen Instanzen bestehen. Ist dies nicht der Fall, wird der " "Controller versuchen, den Befehl \"register-new\" mit den angegebenen " "Parametern auszuführen.\n" @@ -66315,7 +66944,7 @@ msgid "" "Agent which collects the data through the Ruckus Spot web interface" msgstr "" "Diese Regel wählt den Ruckus Spot-Agenten statt dem normalen Checkmk-Agenten " -"aus, der über das Ruckus Spot Webinterface Daten sammelt" +"aus, der über das Ruckus Spot Weboberfläche Daten sammelt" msgid "" "This rule selects the EMC VNX agent instead of the normal Checkmk Agent and " @@ -66425,15 +67054,6 @@ msgstr "" "Dieser Regelsatz wählt den NetApp-Spezialagenten anstelle des normalen " "Checkmk-Agenten und ermöglicht das Monitoring über die NetApp Ontap REST API." -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Dieser Regelsatz wählt den Spezialagent für HPE StoreOnce Appliances " -"anstelle des normalen Checkmk-Agenten aus und ermöglicht das Monitoring über " -"die REST API v4.x oder höher. " - msgid "" "This rule sets limits to the current number of connections through a Check " "Point firewall." @@ -66886,7 +67506,7 @@ msgstr "" "unerreichbar angesehen wird. Es wird dringend empfohlen, hier einen " "möglichst niedrigen Wert einzustellen, da diese Einstellung direkt die GUI-" "Antwortzeit beeinflusst, wenn das Ziel nicht erreichbar ist. Bei Verwendung " -"des Livestatus Proxy-Daemons verbindet sich die GUI mit dem lokalen Proxy, " +"des Livestatus Proxy Daemons verbindet sich die GUI mit dem lokalen Proxy, " "in dieser Situation wird ein niedrigerer Wert, wie z.B. 2 Sekunden empfohlen." msgid "" @@ -66975,8 +67595,9 @@ msgid "" msgstr "" "Diese Einstellung erlaubt es Ihnen, den Informationstext, der im Check-" "Output zwischen den eckigen Klammern zu sehen ist, zu modifizieren. Bitte " -"beachten Sie, dass dies nicht für gruppierte Interfaces gilt, da die " -"zusätzliche Information von gruppierten Interfaces sich hiervon unterscheiden" +"beachten Sie, dass dies nicht für gruppierte Schnittstellen gilt, da die " +"zusätzliche Information von gruppierten Schnittstellen sich hiervon " +"unterscheiden" #, no-python-format msgid "" @@ -67005,8 +67626,8 @@ msgid "" "This setting decides how often the dynamic configuration daemon will get " "updates from the the site. Default is 5 minutes" msgstr "" -"Diese Einstellung legt fest, wie oft der Dämon der dynamischen Konfiguration " -"Aktualisierungen von der Instanz erhält. Standard ist 5 Minuten" +"Diese Einstellung legt fest, wie oft der Daemon der dynamischen " +"Konfiguration Aktualisierungen von der Instanz erhält. Standard ist 5 Minuten" msgid "" "This setting decides when the activate changes operation will be timed out. " @@ -67027,7 +67648,7 @@ msgid "" "the Checkmk Micro Core. The object history (service alerts, events, etc.) is " "not affected by this setting." msgstr "" -"Diese Einstellung legt fest, welche Arten von Meldungen in das Daemon-Log " +"Diese Einstellung legt fest, welche Arten von Meldungen in das Daemon Log " "des Checkmk Micro Core geschrieben werden. Die Objekthistorie (Service-" "Alarme, Ereignisse, etc.) wird davon nicht beeinflusst." @@ -67392,8 +68013,8 @@ msgid "" "This will be used as service name in Checkmk. It must be a unique name per " "host." msgstr "" -"Dies wird als Service-Name innerhalb von Checkmk benutzt. Es muss ein " -"eindeutiger Name pro Host sein." +"Dies wird als Service-Name in Checkmk benutzt. Es muss ein eindeutiger Name " +"pro Host sein." msgid "" "This will be used as service name within Checkmk. It must be a unique name " @@ -67556,6 +68177,8 @@ msgid "" "This will deploy the agent plugin ceph for monitoring the status of " "Ceph. This plug-in will be run asynchronously in the background." msgstr "" +"Hiermit wird das Agentenplugin ceph zur Überwachung des Ceph-Status " +"bereitgestellt. Dieses Plugin wird asynchron im Hintergrund ausgeführt." msgid "" "This will deploy the two agent plug-ins plesk_backup and " @@ -67653,10 +68276,10 @@ msgid "Threads: daemon" msgstr "Threads: Daemon" msgid "Threads: deadlocked" -msgstr "" +msgstr "Threads: festgefahren" msgid "Threads: terminated" -msgstr "" +msgstr "Threads: beendet" msgid "Threads: timed waiting" msgstr "Threads: Wartezeiten" @@ -67710,7 +68333,7 @@ msgid "Thursday" msgstr "Donnerstag" msgid "TiB" -msgstr "" +msgstr "TiB" msgid "Tiles" msgstr "Kacheln" @@ -67959,7 +68582,7 @@ msgid "Time since last checkpoint" msgstr "Zeit seit letztem Checkpoint" msgid "Time since last garbage collection" -msgstr "" +msgstr "Zeit seit der letzten Müllsammlung" msgid "Time since last successful build" msgstr "Zeit seit dem letzten erfolgreichen Build" @@ -68223,7 +68846,7 @@ msgid "Timespan or Duration in seconds" msgstr "Zeitspanne oder Dauer in Sekunden" msgid "Timespan since last Go garbage collection cycle" -msgstr "" +msgstr "Zeitspanne seit dem letzten \"Go garbage collection\"-Zyklus" #, python-format msgid "Timespecific parameters computed at %s" @@ -68832,7 +69455,7 @@ msgid "Total number of hosts" msgstr "Gesamtzahl der Hosts" msgid "Total number of incoming AC get cache request hits" -msgstr "" +msgstr "Gesamtzahl der Treffer für eingehende AC-Get-Cache-Anfragen" msgid "Total number of incoming AC get cache request misses" msgstr "" @@ -70516,7 +71139,7 @@ msgid "Total used memory" msgstr "Gesamter genutzter Speicher" msgid "Total user and system CPU time" -msgstr "" +msgstr "Gesamte Benutzer- und System-CPU-Zeit" msgid "Total virtual memory" msgstr "Gesamter virtueller Speicher" @@ -70697,9 +71320,15 @@ msgstr "Die Probezeit ist während der Beta-Phase nicht definiert" msgid "Tried to register incompatible rulespec: %r" msgstr "Es wurde versucht, inkompatible Regeln zu registrieren: %r" +msgid "Triggering events" +msgstr "Auslösende Ereignisse" + msgid "Trivial change" msgstr "Triviale Änderung" +msgid "Troubleshooting/testing settings" +msgstr "Fehlerbehebung/Test der Einstellungen" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -71180,6 +71809,8 @@ msgid "" "Unable to delete connection id: %s. Connecter and connectee sites must be " "specified." msgstr "" +"Die Verbindungs-ID kann nicht gelöscht werden: %s. Verbindungs- und " +"Anschlussseite müssen angegeben werden." #, python-format msgid "Unable to delete group. It is still in use by: %s" @@ -71227,7 +71858,7 @@ msgid "" "customer %s. This violates the folder CME folder hierarchy." msgstr "" "Kann Host %s nicht verschieben. Seine explizit gesetzte Instanz ID " -"%s gehört dem Kunden %s. Der Zielfolder jedoch, gehört dem Kunden " +"%s gehört dem Kunden %s. Der Zielordner jedoch gehört dem Kunden " "%s. Dies verletzt die CME Ordner Hierarchie." #, python-format @@ -71873,6 +72504,12 @@ msgstr "Antwort hochladen" msgid "Upload verification response file" msgstr "Verifizierungsantwortdatei hochladen" +msgid "Uploaded" +msgstr "Hochgeladen" + +msgid "Uploaded by" +msgstr "Hochladen durch" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "Angepasstes GUI-Logo %s hochgeladen" @@ -72653,7 +73290,7 @@ msgid "Use LDAPS (SSL)" msgstr "LDAPS (SSL) verwenden" msgid "Use Livestatus Proxy Daemon" -msgstr "Livestatus-Proxy-Daemon verwenden" +msgstr "Livestatus Proxy Daemon verwenden" msgid "Use Piggyback" msgstr "Piggyback-Modus verwenden" @@ -72931,7 +73568,7 @@ msgid "Use other host name" msgstr "Anderen Host-Namen benutzen" msgid "Use parent host information for the NetBIOS server name" -msgstr "Parent-Host-Informationen für den NetBIOS-Servernamen verwenden" +msgstr "Parent Host-Informationen für den NetBIOS-Servernamen verwenden" msgid "Use persistent connections" msgstr "Verwende bestehende Verbindungen" @@ -73002,7 +73639,7 @@ msgid "Use the GUI at all" msgstr "Benutzen der GUI" msgid "Use the Livestatus Proxy Daemon for your site" -msgstr "Livestatus-Proxy-Daemon für Ihre Instanz verwenden" +msgstr "Livestatus Proxy Daemon für Ihre Instanz verwenden" msgid "" "Use the Setup BI module, create, modify and delete BI rules and aggregations " @@ -73142,6 +73779,9 @@ msgid "" "set up in such a way that it matches the given host (either by being unset " "or set)." msgstr "" +"Verwenden Sie dieses Feld, um nach Regeln zu suchen, deren explizite Host-" +"Bedingung so eingestellt ist, dass sie mit dem angegebenen Host " +"übereinstimmt (entweder indem sie nicht gesetzt oder gesetzt ist)." msgid "" "Use this field to search for rules which have their item condition set up in " @@ -73220,6 +73860,9 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">globale " "Ereignissbegrenzung für Regeln
    überschreiben" +msgid "Use this option to query a non-standard port." +msgstr "Verwenden Sie diese Option, um einen Nicht-Standard-Port abzufragen." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -73261,6 +73904,14 @@ msgstr "" "der nächste Server abgefragt (Fallback). Die Prüfung gibt nur Daten vom " "ersten Host aus, der eine Antwort sendet." +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Verwenden Sie diese Option, um festzulegen, welche Instanz vom " +"Spezialagenten überprüft werden soll. Bitte geben Sie hier den Host-Namen " +"an, z. B. my_gerrit.com." + msgid "" "Use this option to set which instance should be checked by the special " "agent. Please add the host name here, e.g. my_graylog.com." @@ -73624,7 +74275,7 @@ msgid "User interface settings" msgstr "Einstellungen der Benutzeroberfläche" msgid "User interface theme" -msgstr "Aussehen des User Interfaces" +msgstr "Aussehen der Benutzeroberfläche" msgid "User is locked" msgstr "Benutzer ist gesperrt" @@ -73644,8 +74295,9 @@ msgstr "Benutzer-Benachrichtigungen" msgid "User name" msgstr "Benutzername" -msgid "User name on the storage system. Read only permissions are sufficient." -msgstr "Benutzerkennung auf dem Speichersystem. Leserechte sind ausreichend." +msgid "User name on the storage system. Read-only permissions are sufficient." +msgstr "" +"Benutzerkennung auf dem Speichersystem. Nur-Leserechte sind ausreichend." msgid "User notification" msgstr "Benutzerbenachrichtigung" @@ -73735,6 +74387,9 @@ msgstr "" "Hier eingetragene Benutze können trotz aktivem Schreibschutz die " "Konfiguration ändern." +msgid "Users of contact groups" +msgstr "Benutzer der Kontaktgruppen" + msgid "Users using a cifs share" msgstr "Nutzer einer cifs-Freigabe" @@ -74396,7 +75051,7 @@ msgid "VPC security groups" msgstr "VPC-Sicherheitsgruppen" msgid "VPC security groups of elastic network interface" -msgstr "VPC-Sicherheitsgruppen der Elastic Network-Schnittstelle" +msgstr "VPC-Sicherheitsgruppen der Elastic Netzwerkschnittstelle" msgid "VPN tunnel" msgstr "VPN-Tunnel" @@ -74445,9 +75100,8 @@ msgstr "Gültig bis Checkmk-Version" msgid "Validate server certificate during port query" msgstr "Serverzertifikat bei Portabfrage validieren" -#, fuzzy msgid "Validity" -msgstr "Gültig bis" +msgstr "Gültigkeit" msgid "Validity of missing data" msgstr "Gültigkeit der fehlenden Daten" @@ -74592,7 +75246,7 @@ msgid "Varnish Worker Thread Ratio" msgstr "Varnish Worker Thread Ratio" msgid "Varnish Worker thread ratio" -msgstr "Varnish Worker thread ratio" +msgstr "Varnish Worker Thread Ratio" msgid "Vault size" msgstr "Vault Größe" @@ -74648,6 +75302,9 @@ msgid "Verify SSL certificate (not verifying is insecure)" msgstr "" "Überprüfen Sie das SSL-Zertifikat (eine Nicht-Überprüfung ist unsicher)" +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "TLS-Zertifikat verifizieren (nicht verifizieren ist unsicher)" + msgid "Verify certificates" msgstr "Überprüfen von Zertifikaten" @@ -74709,6 +75366,11 @@ msgstr "Version der PKI-Appliance" msgid "Version of Server" msgstr "Version des Servers" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" +"Die Version wird nur dann in der Zusammenfassung angezeigt, wenn der Status " +"nicht auf \"OK\" gesetzt ist." + #, python-format msgid "Version: %s" msgstr "Version: %s" @@ -75147,6 +75809,10 @@ msgstr "Wartende Verbindungen" msgid "Waiting containers" msgstr "Wartende Container" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Netapp Port-Erkennung" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -75179,7 +75845,7 @@ msgid "Wanted VM State for defined Nutanix VMs" msgstr "Gewünschter VM Status für die definierten Nutanix VMs" msgid "Warn" -msgstr "Warn" +msgstr "WARN" msgid "Warn about configurations to review" msgstr "Warnung wegen zu überprüfenden Konfigurationen" @@ -75524,6 +76190,9 @@ msgstr "Was ist der Anlass?" msgid "What is the purpose?" msgstr "Was ist der Zweck?" +msgid "What should be send out?" +msgstr "Was soll verschickt werden?" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -75942,9 +76611,9 @@ msgstr "" "der Platzhalter $HOSTALIAS$ enthält dessen Alias.

    Bei der " "Auswahl von Die Parents der gefundenen Hosts werden die Bedingungen " "(Tags und Host-Name) verwendet, um einen Host zu finden, aber es wird ein " -"Knoten für jeden der Parent-Hosts des gefundenen Hosts erstellt. Der " +"Knoten für jeden der Parent Hosts des gefundenen Hosts erstellt. Der " "Platzhalter $HOSTNAME$ enthält den Namen des Child-Hosts und " -"$2$ den Namen des Parent-Hosts." +"$2$
    den Namen des Parent Hosts." msgid "" "When sending notifications from the monitoring system to the event console " @@ -76039,7 +76708,7 @@ msgid "" "retrieve information about current and historic events then this timeout " "will be applied." msgstr "" -"Wenn die Multisite-GUI eine Verbindung mit dem Socket des Ereignis-Daemons " +"Wenn die Multisite-GUI eine Verbindung mit dem Socket des Event Daemons " "herstellt, um Informationen über aktuelle und historische Ereignisse " "abzurufen, wird diese Zeitüberschreitung angewendet." @@ -76051,8 +76720,8 @@ msgid "" "queued before refusing new connections." msgstr "" "Wenn die Multisite-GUI oder der aktive Check check_mkevents eine Verbindung " -"zum Socket des Ereignis-Daemons herstellt, um Informationen über aktuelle " -"und historische Ereignisse abzurufen, kann die Verbindungsanfrage in eine " +"zum Socket des Event Daemons herstellt, um Informationen über aktuelle und " +"historische Ereignisse abzurufen, kann die Verbindungsanfrage in eine " "Warteschlange gestellt werden, bevor sie verarbeitet wird. Mit dieser " "Einstellung wird die Anzahl der nicht akzeptierten Verbindungen festgelegt, " "die in die Warteschlange gestellt werden, bevor neue Verbindungen abgelehnt " @@ -76585,6 +77254,9 @@ msgstr "" msgid "Who" msgstr "Wer" +msgid "Who should receive the notification?" +msgstr "Wer sollte die Benachrichtigung erhalten?" + msgid "WiFi connection types" msgstr "WiFi-Verbindungstypen" @@ -76746,9 +77418,10 @@ msgstr "" "Wenn der Authentifizierungstyp auf 'OAuth2' eingestellt ist, muss die Option " "'%s' angegeben werden." +#, fuzzy msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -76757,9 +77430,9 @@ msgid "" msgstr "" "Mit Hilfe der Binärdatei RCC kann der Robotmk-Scheduler die Python-Umgebungen " -"erzeugen, die für die Ausführung von Robot Framework-Suiten erforderlich " +"erzeugen, die für die Ausführung von Robot Framework Suiten erforderlich " "sind. Dadurch entfällt die Notwendigkeit, Python und alle dazugehörigen " -"Bibliothekspakete auf den Zielhosts zu installieren und zu konfigurieren. " +"Bibliothekspakete auf den Ziel-Hosts zu installieren und zu konfigurieren. " "RCC-Umgebungen werden direkt nach dem Start des Schedulers durch den Checkmk-" "Agenten und vor Beginn der Planungsphase erstellt." @@ -77072,6 +77745,19 @@ msgstr "" "zu Verwirrung führen. Diese Regel sollte nur in der Frühphase " "konfiguriert werden." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" +"Ohne eine Fallback-E-Mail-Adresse verpassen Sie möglicherweise " +"Benachrichtigungen, die nicht von einer Benachrichtigungsregel abgedeckt " +"werden. Um eine vollständige Benachrichtigungsabdeckung zu gewährleisten, " +"empfehlen wir Ihnen, eine Fallback-E-Mail-Adresse zu konfigurieren, an die " +"alle Benachrichtigungen gesendet werden, die nicht mit einer " +"Benachrichtigungsregel übereinstimmen." + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -77979,6 +78665,14 @@ msgstr "" "Sie können diese %s nicht löschen, da sie in Verwendung ist." +#, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"Sie können diesen verwalteten Roboter nicht löschen, das er in den folgenden " +"Regeln verwendet wird: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -78672,8 +79366,8 @@ msgstr "Namen von Wochentagen (%s) können nicht in Ausnahmen verwendet werden" msgid "You configured the host to be it's own parent, which is not allowed." msgstr "" -"Sie haben den Host als seinen eigenen Parenthost konfiguriert. Das ist nicht " -"erlaubt." +"Sie haben den Host als seinen eigenen Parent Host konfiguriert. Das ist " +"nicht erlaubt." #, python-format msgid "You defined the non-existing host '%s' as a parent." @@ -78810,6 +79504,10 @@ msgstr "" "Sie haben bislang keinen Agenten-Signatur-" "Schlüssel erstellt. Dies ist erforderlich." +msgid "You have not created any parameters for this notification method yet." +msgstr "" +"Sie haben noch keine Parameter für diese Benachrichtigungsmethode angelegt." + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -78870,7 +79568,7 @@ msgstr "" #, python-format msgid "You have selected %d hosts for parent scan. " -msgstr "Sie haben %d Hosts für den Parent-Scan ausgewählt. " +msgstr "Sie haben %d Hosts für den Parent Scan ausgewählt. " msgid "You have signed some or all agent packages" msgstr "Sie haben manche oder alle Pakete signiert" @@ -78996,7 +79694,8 @@ msgstr "" msgid "You may only use paths relative to the report archive base directory" msgstr "" -"Sie dürfen nur Pfade relativ zum Basispfad des Report-Archivs konfigurieren" +"Sie dürfen nur Pfade relativ zum Basisverzeichnis des Berichtsarchivs " +"konfigurieren" #, python-format msgid "" @@ -79220,6 +79919,10 @@ msgid "" "content is generated externally. It is prone to injection attacks (executed " "on the host where the test is executed). Proceed with caution." msgstr "" +"Unten sollten Sie das Standard-HTML-Protokoll von Robot Framework sehen. " +"Dieser Inhalt wird jedoch extern generiert. Er ist anfällig für " +"Injektionsangriffe (ausgeführt auf dem Host, auf dem der Test ausgeführt " +"wird). Seien Sie also vorsichtig." msgid "" "You will have to configure the host address of the server which hosts the " @@ -79824,7 +80527,7 @@ msgid "check." msgstr "check." msgid "children" -msgstr "Childhosts" +msgstr "Children" msgid "clients" msgstr "Clients" @@ -80519,7 +81222,7 @@ msgid "invalid:" msgstr "ungültig:" msgid "iops" -msgstr "" +msgstr "IOPS" msgid "is" msgstr "ist" @@ -80741,9 +81444,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "überwachen" - msgid "month" msgstr "Monat" @@ -81155,10 +81855,12 @@ msgid "requests/sec" msgstr "Anfragen/Sek" msgid "require interface that sorts lowest alphabetically" -msgstr "Benötigt alphanumerisch niedrigste Schnittstelle" +msgstr "" +"benötige eine Schnittstelle, welche die niedrigsten Werte alphabetisch " +"sortiert" msgid "require primary interface to be active" -msgstr "Benötigt aktive primäre Schnittstelle" +msgstr "primäre Schnittstelle muss aktiv sein" msgid "reset" msgstr "zurücksetzen" @@ -81646,6 +82348,9 @@ msgstr "{actual} ist zu hoch. Erlaubtes Maximum ist {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} ist zu niedrig. Erlaubtes Minimum ist {bound}." +msgid "{checkname} - {check['title']}" +msgstr "{checkname} - {check['title']}" + #, python-brace-format msgid "{region} ({id_})" msgstr "{region} ({id_})" @@ -81654,6 +82359,155 @@ msgstr "{region} ({id_})" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Alle Rechte vorbehalten." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "RCC-Profilkonfiguration (%s, da Robotmk-Kern-MKP installiert wurde)" + +#~ msgid "" +#~ "Specify here whether the working directory of Robotmk (`C:\\ProgramData" +#~ "\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " +#~ "should be cleaned up either after a certain time or after a certain " +#~ "number of test executions." +#~ msgstr "" +#~ "Geben Sie hier an, ob das Arbeitsverzeichnis von Robotmk (`C:\\ProgramData" +#~ "\\checkmk\\agent\\robotmk_output\\working\\suites\\`) auf dem Ziel-Host " +#~ "entweder nach einer bestimmten Zeit oder nach einer bestimmten Anzahl von " +#~ "Testausführungen bereinigt werden soll." + +#~ msgid "API key from password store" +#~ msgstr "API Schlüssel aus dem Passwortspeicher" + +#~ msgid "Host Path" +#~ msgstr "Host-Pfad" + +#~ msgid "" +#~ "This page is currently not implemented, needs FormSpec migration of " +#~ "NotificationParameter." +#~ msgstr "" +#~ "Diese Seite ist derzeit nicht implementiert, sie benötigt eine FormSpec-" +#~ "Migration von NotificationParameter." + +#, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Broker-Zertifikate konnten nicht gespeichert werden: %s" + +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Wenn Ihr Monitoring eine Benachrichtigung erzeugt, die keiner Ihrer " +#~ "Benachrichtigungsregeln entspricht, wird die Benachrichtigung nicht " +#~ "versendet. Um dies zu verhindern, empfehlen wir Ihnen, entweder die " +#~ "globale Einstellung zu konfigurieren oder die Fallback-Kontaktoption für " +#~ "mindestens einen Ihrer Benutzer zu aktivieren." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Sammelbenachrichtigungen mit Graphen (Standard: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Normalerweise werden mehrfach-Graphen in Emails ja nach Platz " +#~ "nebeneinander oder untereinander dargestellt. Mit dieser Option können " +#~ "Sie eine Darstellung untereinander erzwingen." + +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Aktivieren Sie dies damit das Benachrichtigungs-Plugin sich direkt mit " +#~ "dem SMTP-Server verbindet. Dies hat den Vorteil, dass im Fehlerfall " +#~ "bessere Fehlermeldungen ausgegeben werden, erfordert aber mehr " +#~ "Konfiguration und ist streng synchron. Wir raten daher, diese Option nur " +#~ "bei Enterprise-Installationen zu verwenden, die den Benachrichtigungs-" +#~ "Spooler nutzen." + +#~ msgid "Display additional information" +#~ msgstr "Ergänzende Informationen anzeigen" + +#~ msgid "Display graphs among each other" +#~ msgstr "Graphen untereinander darstellen" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Graphen untereinander darstellen" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "Die E-Mail-Adresse und der sichtbare Name, die im Absender-Header von " +#~ "Benachrichtigungsmeldungen verwendet werden. Wenn keine E-Mail-Adresse " +#~ "angegeben ist, wird die Standardadresse OMD_SITE@FQDN verwendet. " +#~ "Wenn die Umgebungsvariable OMD_SITE nicht gesetzt ist, wird sie " +#~ "standardmäßig auf checkmk gesetzt." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "Die E-Mail-Adresse und der sichtbare Name, die im Reply-To-Header von " +#~ "Benachrichtigungsnachrichten verwendet werden." + +#~ msgid "Activate" +#~ msgstr "Aktivieren" + +#~ msgid "Deactivate" +#~ msgstr "Deaktiviert" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Diese Regel ermöglicht das Monitoring von VMware ESXi über die vSphere-" +#~ "API. Sie können Ihre Verbindungseinstellungen hier konfigurieren." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Dieser Regelsatz wählt den Spezialagent für HPE StoreOnce Appliances " +#~ "anstelle des normalen Checkmk-Agenten aus und ermöglicht das Monitoring " +#~ "über die REST API v4.x oder höher. " + +#~ msgid "monitor" +#~ msgstr "überwachen" + +#~ msgid "AWS account name" +#~ msgstr "AWS Kontoname" + +#~ msgid "Parallel plan groups" +#~ msgstr "Parallele Plangruppen" + +#~ msgid "" +#~ "The group execution interval must be greater than the sum of the " +#~ "individual plan runtime limits. The runtime limit of a plan is calculated " +#~ "as follows: limit_per_attempt x (1 + max_number_of_reexecutions)." +#~ msgstr "" +#~ "Das Gruppenausführungsintervall muss größer sein als die Summe der " +#~ "einzelnen Planlaufzeitgrenzen. Die Laufzeitgrenze eines Plans wird wie " +#~ "folgt berechnet: Limit_pro_Versuch x (1 + max_Anzahl_der_Wiederholungen)." + +#~ msgid "(not supported)" +#~ msgstr "(nicht unterstützt)" + +#~ msgid "Remove downtimes?" +#~ msgstr "Wartungszeiten entfernen?" + +#~ msgid "Schedule downtime?" +#~ msgstr "Wartungszeit planen?" + +#~ msgid "OVS bonding interface status" +#~ msgstr "Status der OVS Bonding-Schnittstelle" + #~ msgid "Common Name" #~ msgstr "Common Name" @@ -81750,11 +82604,6 @@ msgstr "© %s Checkmk GmbH. Alle Rechte vorbehalten." #~ msgid "Database for PostgreSQL" #~ msgstr "Datenbank für PostgreSQL" -#~ msgid " to get notified once the commercial release is available. " -#~ msgstr "" -#~ " um benachrichtigt zu werden, sobald die kommerzielle Version verfügbar " -#~ "ist. " - #~ msgid "Checkmk Cloud (SaaS) Beta" #~ msgstr "Checkmk Cloud (SaaS) Beta" @@ -81791,9 +82640,6 @@ msgstr "© %s Checkmk GmbH. Alle Rechte vorbehalten." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Verwendete Quota: Absolute oder relative Obergrenzen" -#~ msgid "Changes have been activated" -#~ msgstr "Änderungen wurden aktiviert" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Tablespaces" @@ -82084,10 +82930,6 @@ msgstr "© %s Checkmk GmbH. Alle Rechte vorbehalten." #~ msgid "%s operations" #~ msgstr "%s Operationen" -#, python-format -#~ msgid "%s requests" -#~ msgstr "%s Anfragen" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -82454,9 +83296,6 @@ msgstr "© %s Checkmk GmbH. Alle Rechte vorbehalten." #~ msgid "InfluxDB Queue Usage" #~ msgstr "InfluxDB Queue Usage" -#~ msgid "Kernel Version" -#~ msgstr "Kernel-Version" - #~ msgid "Levels Helper usage Check" #~ msgstr "Level der Hilfsprozessauslastung Check" diff --git a/locale/es/LC_MESSAGES/multisite.po b/locale/es/LC_MESSAGES/multisite.po index 2b0fb37c703..04fc6ba0609 100644 --- a/locale/es/LC_MESSAGES/multisite.po +++ b/locale/es/LC_MESSAGES/multisite.po @@ -405,6 +405,10 @@ msgstr "%d días" msgid "%d days ago" msgstr "%d días atrás" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Propiedades generales" + #, python-format msgid "%d errors occured:" msgstr "%d errores ocurridos:" @@ -567,6 +571,10 @@ msgstr "%s por host" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -688,6 +696,10 @@ msgstr "%s tasa" msgid "%s resulting notifications" msgstr "%s Notificaciones resultantes" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s solicitudes" + #, python-format msgid "%s running for %s" msgstr "%s corriendo por %s" @@ -802,9 +814,17 @@ msgstr "" "el versionado de la configuración. Por favor instale 'git' o deshabilite el " "seguimiento de la configuración mediante git en el setup." +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Entradas eliminadas" + msgid "(0 is current period)" msgstr "(0 es el período actual)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(sin entrada)" + msgid "(Edit presets)" msgstr "(Editar preajustes)" @@ -881,9 +901,6 @@ msgstr "(sin título)" msgid "(none)" msgstr "(ninguno)" -msgid "(not supported)" -msgstr "(no soportado)" - msgid "(nothing selected)" msgstr "(nada seleccionado)" @@ -992,6 +1009,10 @@ msgstr "1 cambio" msgid "1 row" msgstr "1 fila" +#, fuzzy +msgid "1 rule" +msgstr "regla" + msgid "1 year" msgstr "1 año" @@ -1179,6 +1200,30 @@ msgstr "percentil 95" msgid "99th percentile" msgstr "Percentil 99" +#, fuzzy +msgid "< Remove" +msgstr "Eliminar" + +#, fuzzy +msgid "<< Remove all" +msgstr "Eliminar todo" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Las " +"traducciones piggybackse realizan antes de que el conector piggyback " +"cree hosts. Utilícelo, por ejemplo, en una configuración con varios nodos " +"Docker para anteponer a los contenedores el nombre del nodo Docker " +"correspondiente. De lo contrario, pueden producirse colisiones de nombres si " +"existen contenedores con el mismo nombre en más de un nodo Docker." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Nota3: Para implementar este complemento en Solaris, se " @@ -1351,6 +1396,12 @@ msgstr "Advertencia: Hay %d trabajos incompatibles no reconocidos:" msgid "You do not have any roles." msgstr "Usted no tiene ningún rol." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1938,7 +1989,7 @@ msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" #, python-format @@ -2121,6 +2172,14 @@ msgstr "Un encabezado para los gráficos" msgid "A heading for the view" msgstr "Un encabezado para la vista" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Ya existe un host con el nombre %s en la carpeta
    %s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Añadir %s" + msgid "Add Aggregation" msgstr "Añadir agregación" @@ -3649,10 +3725,6 @@ msgstr "Añadir excepción" msgid "Add Group" msgstr "Añadir grupo" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"Añadir sección HTML encima de la tabla (por ejemplo, título, descripción...)" - msgid "Add LDAP connection" msgstr "Añadir conexión LDAP" @@ -3698,6 +3770,9 @@ msgstr "Añadir agregación" msgid "Add alert handler rule" msgstr "Añadir regla de gestión de alertas" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Añade a la monitorización todos los servicios detectados pero aún no " @@ -3801,6 +3876,10 @@ msgstr "Añade el elemento: %s" msgid "Add elements to your sidebar" msgstr "Añade elementos a tu barra lateral" +#, fuzzy +msgid "Add event" +msgstr "Añadir elemento" + msgid "Add exception" msgstr "Añadir excepción" @@ -3992,6 +4071,10 @@ msgstr "Añadir condición de etiqueta" msgid "Add new pattern" msgstr "Añadir un nuevo patrón" +#, fuzzy +msgid "Add new plan" +msgstr "Añadir un nuevo patrón" + msgid "Add new project" msgstr "Añadir un nuevo proyecto" @@ -4007,10 +4090,18 @@ msgstr "Añadir una nueva fila" msgid "Add new scalar" msgstr "Añadir nuevo escalar" +#, fuzzy +msgid "Add new sequence" +msgstr "Añadir un nuevo servicio" + #, fuzzy msgid "Add new service" msgstr "Añadir un nuevo servicio" +#, fuzzy +msgid "Add new smarthost" +msgstr "Añadir nueva macro" + msgid "Add new status" msgstr "Añadir un nuevo estado" @@ -4053,6 +4144,10 @@ msgstr "Añadir o modificar ejecutables" msgid "Add page element" msgstr "Añadir elemento de página" +#, fuzzy +msgid "Add parameter" +msgstr "Parámetros del modelo" + msgid "Add pattern" msgstr "Añadir patrón" @@ -4078,6 +4173,10 @@ msgstr "Añadir pre o postfix a TNSALIASes %s" msgid "Add random hosts" msgstr "Añadir hosts aleatorios" +#, fuzzy +msgid "Add recipient" +msgstr "Destinatario" + msgid "Add remote instance" msgstr "Añadir instancia remota" @@ -4327,6 +4426,10 @@ msgstr "Direcciones IPv6 adicionales" msgid "Additional agent labels to send during registration" msgstr "Etiquetas de agente adicionales para enviar durante el registro" +#, fuzzy +msgid "Additional details" +msgstr "Opciones adicionales" + msgid "Additional header lines" msgstr "Líneas de cabecera adicionales" @@ -4455,7 +4558,7 @@ msgid "Admin states to discover" msgstr "Estados de la administración para descubrir" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "Estados administrativos" msgid "Administrative port states to discover" @@ -5155,6 +5258,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "Configuración del gestor de alertas" +#, fuzzy +msgid "Alert handler execution" +msgstr "Ejecución de gestores de alertas" + msgid "Alert handler execution, failed" msgstr "Ejecución del gestor de alertas, fallida" @@ -5268,6 +5375,24 @@ msgstr "Estadísticas de alertas: Número de alertas desconocidas" msgid "Alert statistics: Number of warnings" msgstr "Estadísticas de alertas: Número de avisos" +#, fuzzy +msgid "Alert when a major version release is available" +msgstr "" +" para recibir una notificación cuando el lanzamiento comercial esté " +"disponible. " + +#, fuzzy +msgid "Alert when a minor version release is available" +msgstr "" +" para recibir una notificación cuando el lanzamiento comercial esté " +"disponible. " + +#, fuzzy +msgid "Alert when a patch version release is available" +msgstr "" +" para recibir una notificación cuando el lanzamiento comercial esté " +"disponible. " + msgid "Alerted" msgstr "Alerta" @@ -5375,6 +5500,10 @@ msgstr "Todas las colecciones" msgid "All components" msgstr "Todos los componentes" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Todos los contactos del objeto notificado" + msgid "All contacts of the notified object" msgstr "Todos los contactos del objeto notificado" @@ -5816,6 +5945,10 @@ msgstr "Permitir ver el icono %s en las vistas de host y servicio" msgid "Allow unencrypted legacy communication" msgstr "Permitir la comunicación heredada sin cifrar" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "permitir a los usuarios desactivar esta notificación" + msgid "Allowed Ciphers" msgstr "Cifras permitidas" @@ -6426,6 +6559,10 @@ msgstr "Ya se está ejecutando la sincronización de otro usuario: %s" msgid "AntiVirus last update age" msgstr "Edad de la última actualización del antivirus" +#, fuzzy +msgid "Any" +msgstr "cualquier" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6606,9 +6743,21 @@ msgstr "Resumen de aplicaciones" msgid "Applications, Processes & Services" msgstr "Aplicaciones, procesos y servicios" +#, fuzzy +msgid "Applied to" +msgstr "Solicitar a" + msgid "Apply" msgstr "Aplique" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Regla de gestión de alertas" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Eliminar esta regla de notificación" + #, fuzzy msgid "Apply Latency" msgstr "Latencia" @@ -6632,6 +6781,11 @@ msgstr "Aplicar condiciones" msgid "Apply filters" msgstr "Aplicar filtros" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Aplicar la hora de finalización" @@ -6769,6 +6923,10 @@ msgstr "Obtener registros de auditoría remotos" msgid "Archive event" msgstr "Archivo de eventos" +#, fuzzy +msgid "Archive event?" +msgstr "Archivo de eventos" + msgid "Archive events" msgstr "Archivo de eventos" @@ -6898,6 +7056,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Traducción de nombres de host para los hosts piggybacked" @@ -7345,10 +7508,10 @@ msgstr "Autoextensible" msgid "Automated environment setup (via RCC)" msgstr "" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Usar SSL para la conexión." msgid "Automatic" @@ -8717,6 +8880,10 @@ msgstr "Agentes horneados" msgid "Baked host specific agent" msgstr "Agente específico del huésped horneado" +#, fuzzy +msgid "Bakery rules" +msgstr "reglas de descubrimiento" + msgid "Baking Agents..." msgstr "Agentes de cocción..." @@ -9260,8 +9427,9 @@ msgstr "Importación masiva de hosts" msgid "Bulk move" msgstr "Movimiento en masa" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Notificaciones masivas con gráficos (por defecto: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Abrir notificaciones masivas" msgid "Bulk removal of explicit attributes" msgstr "Eliminación masiva de atributos explícitos" @@ -9627,14 +9795,6 @@ msgstr "" "personalizar las credenciales que se utilizarán al ponerse en contacto con " "hosts a través de SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Por defecto, todos los gráficos múltiples en los correos electrónicos se " -"muestran flotando cerca. Puede activar esta opción para mostrar los gráficos " -"entre sí." - msgid "By default all of the sections will be executed." msgstr "Por defecto se ejecutarán todas las secciones." @@ -9818,14 +9978,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" msgid "" @@ -9834,7 +9994,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" msgid "" @@ -10104,8 +10264,8 @@ msgstr "Todos los gráficos de un determinado host." msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11367,6 +11527,10 @@ msgstr "Conexión LDAP modificada %s" msgid "Changed alert handler rule %d" msgstr "Cambiada la regla de gestión de alertas %d" +#, fuzzy +msgid "Changed by" +msgstr "Cambiado" + msgid "Changed entries" msgstr "Entradas modificadas" @@ -11382,6 +11546,14 @@ msgstr[1] "Etiquetas de host modificadas: " msgid "Changed host selection has been saved." msgstr "Se ha guardado la selección de host modificada." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Regla de notificación modificada %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Regla de notificación modificada %d" + #, python-format msgid "Changed notification rule %d" msgstr "Regla de notificación modificada %d" @@ -11401,6 +11573,10 @@ msgstr "Cambio de posición de %s %d" msgid "Changed position of connection %s to %d" msgstr "Cambiada la posición de la conexión %s a %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "Posición modificada de la regla de notificación %d del usuario %s" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "Posición modificada de la regla de notificación %d del usuario %s" @@ -11460,6 +11636,10 @@ msgstr "" msgid "Changes" msgstr "Cambios" +#, fuzzy +msgid "Changes activated" +msgstr "Nunca se ha activado" + msgid "Changes since last dump" msgstr "Cambios desde el último volcado" @@ -12779,6 +12959,11 @@ msgstr "Haga clic aquí para ver el estado de activación por sitio." msgid "Click on 'Register %s' to enable two-factor authentication via %s." msgstr "Eliminar la autenticación de dos factores de %s" +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Haz clic para activar esta opción" @@ -12940,6 +13125,10 @@ msgstr "Clonar esta conexión para crear una nueva" msgid "Clone this element" msgstr "Clonar este elemento" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Objetos gestionados" + msgid "Clone this metric" msgstr "Clonar esta métrica" @@ -13507,6 +13696,10 @@ msgstr "Completar la restauración" msgid "Complete tree" msgstr "Árbol completo" +#, fuzzy +msgid "Complete variable list" +msgstr "Lista completa de variables (para las pruebas)" + msgid "Complete variable list (for testing)" msgstr "Lista completa de variables (para las pruebas)" @@ -13652,6 +13845,10 @@ msgstr "Archivos de configuración ('*.mk' o '*.conf') de etc/checkmk: %s" msgid "Configuration generation" msgstr "Generación de la configuración" +#, fuzzy +msgid "Configuration name" +msgstr "Configuración" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Configuración del componente de Business Intelligence de Checkmk" @@ -13724,6 +13921,10 @@ msgstr "Configurar" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Supervisión de Amazon Web Services (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Supervisión de Amazon Web Services (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "" "Configurar los ajustes relacionados con SNMP mediante conjuntos de reglas" @@ -13793,6 +13994,10 @@ msgstr "Dirección de correo de reserva del informe de colisión" msgid "Configure grouping of interfaces" msgstr "Configurar la agrupación de interfaces" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configuración" + #, fuzzy msgid "Configure host and regions" msgstr "Configuración" @@ -14021,6 +14226,10 @@ msgstr "" "Configurar el nombre de la variable de cabecera de la petición HTTP para " "leer de las peticiones HTTP entrantes" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configurar la detección de interfaces individuales" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -14053,20 +14262,6 @@ msgstr "" "la clave del usuario o grupo aquí. La clave puede obtenerse en el sitio web " "de Pushover." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configurar esto para que el plugin de notificaciones se conecte directamente " -"al servidor smtp. Esto tiene la ventaja de proporcionar mejores mensajes de " -"error en caso de un error, pero requiere más configuración y es " -"estrictamente sincrónico, por lo que aconsejamos su uso sólo en " -"instalaciones empresariales que utilicen el spooler de notificaciones." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14468,6 +14663,10 @@ msgstr "Contacte con" msgid "Contact Name" msgstr "Nombre de contacto" +#, fuzzy +msgid "Contact group" +msgstr "Grupos de contacto" + msgid "Contact group (effective)" msgstr "Grupo de contacto (efectivo)" @@ -14627,6 +14826,10 @@ msgstr "Información de contexto" msgid "Context information about this connection" msgstr "Información de contexto sobre esta conexión" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Información de contexto sobre esta norma" + msgid "Context information about this rule" msgstr "Información de contexto sobre esta norma" @@ -14880,6 +15083,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase: Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, fuzzy, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -15170,6 +15378,10 @@ msgstr "Crear una copia de esta conexión" msgid "Create a copy of this group" msgstr "Crear una copia de este grupo" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Crear una copia de esta regla de notificación" + msgid "Create a copy of this notification rule" msgstr "Crear una copia de esta regla de notificación" @@ -15255,6 +15467,11 @@ msgstr "Crear un servicio adicional para las solicitudes de IO Stats" msgid "Create additional service for system wait" msgstr "Crear un servicio adicional para la espera del sistema" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Crear una anotación para este periodo" @@ -15365,6 +15582,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Crear un calendario regular para este informe" +#, fuzzy +msgid "Create robot" +msgstr "Crear hosts en" + msgid "Create separate notification bulks based on" msgstr "Cree lotes de notificaciones separados en función de" @@ -15466,6 +15687,10 @@ msgstr "Creado nuevo host %s." msgid "Created new host tag group '%s'" msgstr "Se ha creado un nuevo grupo de etiquetas de host \"%s\"" +#, fuzzy +msgid "Created new notification parameter" +msgstr "Creada una nueva regla de notificación" + msgid "Created new notification rule" msgstr "Creada una nueva regla de notificación" @@ -15916,6 +16141,11 @@ msgstr "Diseño de GUI personalizado de %s" msgid "Custom Graph" msgstr "Gráfico personalizado" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "" +"Añadir sección HTML encima de la tabla (por ejemplo, título, descripción...)" + msgid "Custom Icons" msgstr "Iconos personalizados" @@ -16023,6 +16253,14 @@ msgstr "Localizaciones personalizadas" msgid "Custom logos" msgstr "Logotipos personalizados" +#, fuzzy +msgid "Custom macro" +msgstr "Macros de clientes" + +#, fuzzy +msgid "Custom macros" +msgstr "Macros de clientes" + #, python-format msgid "Custom notification table for user %s" msgstr "Tabla de notificaciones personalizada para el usuario %s" @@ -16037,9 +16275,15 @@ msgstr "Estado de la sonda personalizada" msgid "Custom profile" msgstr "Título personalizado" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Consulta de búsqueda personalizada" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Atributos de servicio personalizados" @@ -16886,9 +17130,6 @@ msgstr "Tarifa diaria" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Desactivar" - msgid "Deactivated" msgstr "Desactivado" @@ -17185,6 +17426,9 @@ msgstr "Perfil de usuario por defecto" msgid "Default value" msgstr "Valor por defecto" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "Antigüedad de archivos diferidos" @@ -17240,6 +17484,9 @@ msgstr "" "control, es decir, al resultado de la comprobación. Esto sobrescribe el " "mapeo por defecto utilizado por la comprobación." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Definir la asignación de host" @@ -17282,6 +17529,9 @@ msgstr "Definir niveles inferiores para el número de contenedores en espera" msgid "Define name of NetBIOS server" msgstr "Nombre NetBIOS del servidor" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17528,6 +17778,10 @@ msgstr "Borrar clave de seguridad #%d" msgid "Delete comments" msgstr "Comentario del evento" +#, fuzzy +msgid "Delete comments?" +msgstr "Comentario del evento" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Configuración por defecto" @@ -17596,6 +17850,14 @@ msgstr "Eliminar trabajo #%d" msgid "Delete last alert handler rule" msgstr "Eliminar la última regla de gestión de alertas" +#, fuzzy +msgid "Delete managed robot" +msgstr "Objetos gestionados" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Eliminar esta regla de notificación #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Eliminar esta regla de notificación #%d" @@ -17749,9 +18011,17 @@ msgstr "Borrar esta tecla" msgid "Delete this logo" msgstr "Eliminar este logotipo" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Eliminar este grupo de etiquetas" + msgid "Delete this metric" msgstr "Eliminar esta métrica" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Eliminar esta regla de notificación" + msgid "Delete this notification rule" msgstr "Eliminar esta regla de notificación" @@ -17849,6 +18119,10 @@ msgstr "Carpeta eliminada %s" msgid "Deleted host %s" msgstr "Host eliminado %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Eliminar esta regla de notificación #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Regla de notificación %d eliminada del usuario %s" @@ -18797,6 +19071,10 @@ msgstr "Desactivar la gestión del proxy" msgid "Disable remote configuration" msgstr "Desactivar la configuración remota" +#, fuzzy +msgid "Disable rule" +msgstr "Desactivar todo" + msgid "Disable service notifications" msgstr "Desactivar las notificaciones de servicio" @@ -19174,9 +19452,6 @@ msgstr "" "Mostrar una advertencia si un LUN no es de sólo lectura. Sin esta " "configuración, se mostrará una advertencia si un LUN es de sólo lectura." -msgid "Display additional information" -msgstr "Mostrar información adicional" - msgid "Display additional messages" msgstr "Mostrar mensajes adicionales" @@ -19202,9 +19477,6 @@ msgstr "" msgid "Display dashboard title" msgstr "Mostrar el título del panel de control" -msgid "Display graphs among each other" -msgstr "Visualizar los gráficos entre sí" - msgid "Display historic data since the last" msgstr "Mostrar los datos históricos desde la última" @@ -20107,6 +20379,10 @@ msgstr "Delta del recuento de documentos" msgid "Document count growth per minute" msgstr "Crecimiento del número de documentos por minuto" +#, fuzzy +msgid "Documentation" +msgstr "URL de la documentación" + msgid "Documentation URL" msgstr "URL de la documentación" @@ -20889,6 +21165,10 @@ msgstr "Editar" msgid "Edit %s" msgstr "Editar %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Editar regla de notificación %d" + #, python-format msgid "Edit %s: %s" msgstr "Editar %s: %s" @@ -21039,6 +21319,10 @@ msgstr "Editar el diseño" msgid "Edit layout only available if header is enabled" msgstr "Editar el diseño sólo está disponible si la cabecera está activada" +#, fuzzy +msgid "Edit managed robots" +msgstr "Objetos gestionados" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Editar la conexión del sitio %s" @@ -21199,6 +21483,14 @@ msgstr "Editar este elemento" msgid "Edit this host" msgstr "Editar este host" +#, fuzzy +msgid "Edit this managed robot" +msgstr "Estados administrativos" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Editar esta regla de notificación" + msgid "Edit this notification rule" msgstr "Editar esta regla de notificación" @@ -21270,6 +21562,9 @@ msgstr "Editado el perfil del usuario %s" msgid "Edition" msgstr "Edición" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "Estado efectivo" @@ -21455,6 +21750,14 @@ msgstr "" msgid "Email addresses to mail PDF reports to" msgstr "Direcciones de correo electrónico a las que enviar los informes en PDF" +#, fuzzy +msgid "Email body/content" +msgstr "Correo electrónico enviado" + +#, fuzzy +msgid "Email header" +msgstr "Dirección de correo electrónico" + msgid "Email sent" msgstr "Correo electrónico enviado" @@ -22480,6 +22783,10 @@ msgstr "Comentario del evento" msgid "Event console" msgstr "Consola de eventos" +#, fuzzy +msgid "Event console alerts" +msgstr "Alertas de la consola de eventos" + msgid "Event console performance" msgstr "Rendimiento de la consola de eventos" @@ -23714,10 +24021,6 @@ msgstr "No se ha podido mostrar el valor:" msgid "Failed to render value: %r" msgstr "Fallo en la representación del valor: %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Fallo en la obtención del certificado de pares (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -23828,6 +24131,10 @@ msgstr "" "resultado de los nodos adicionales provocará como mínimo un estado de " "ADVERTENCIA." +#, fuzzy +msgid "Failure" +msgstr "fallos" + msgid "Failures of the join launcher service" msgstr "Fallos en el servicio de lanzamiento de la unión" @@ -24127,6 +24434,10 @@ msgstr "Tamaño de archivo inferior" msgid "File size levels" msgstr "Niveles de tamaño de los archivos" +#, fuzzy +msgid "File upload" +msgstr "Bytes cargados" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -24254,6 +24565,10 @@ msgstr "" "Filtro para todas las agregaciones que se basan en la información de estado " "de ese host. Coincidencia exacta (sin expresión regular)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Tiempo de inactividad del host/servicio" + msgid "Filter group (see help)" msgstr "Grupo de filtros (ver ayuda)" @@ -24931,6 +25246,9 @@ msgstr "Redes" msgid "Form factor" msgstr "Factor de forma" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Formato" @@ -25573,6 +25891,11 @@ msgstr "Generar" msgid "Generate REST API specification" msgstr "Especificación del SLA" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + #, fuzzy msgid "Generate backup codes" msgstr "Regenerar los códigos de seguridad" @@ -25641,6 +25964,21 @@ msgstr "Tasa genérica" msgid "Generic string" msgstr "Cadena genérica" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Versión del núcleo" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Editar la conexión" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "Instancia de Jenkins a consultar." + msgid "Get file from SFTP server" msgstr "Obtener un archivo del servidor SFTP" @@ -25700,6 +26038,10 @@ msgstr "Norma de notificación global" msgid "Global notification rules" msgstr "reglas de notificación global" +#, fuzzy +msgid "Global services" +msgstr "Todos los servicios" + msgid "Global services to monitor" msgstr "Servicios globales para controlar" @@ -25726,6 +26068,10 @@ msgstr "Patrón de globo para los archivos de entrada" msgid "Go critical if all licenses are used" msgstr "Pasar al estado crítico si se utilizan todas las licencias" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Todos los hosts" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25738,6 +26084,12 @@ msgstr "Ir a la página principal" msgid "Go to rules of this InfluxDB connection" msgstr "Ir a las reglas de esta conexión InfluxDB" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "Acceder al Panel de Aministración de Saas" @@ -25900,18 +26252,12 @@ msgstr "Tarjetas gráficas" msgid "Graphs" msgstr "Gráficos" -msgid "Graphs are shown among each other" -msgstr "Los gráficos se muestran entre sí" - msgid "Graphs for averaged single-core utilizations" msgstr "Gráficos de utilización media de un solo núcleo" msgid "Graphs for individual cores" msgstr "Gráficos para núcleos individuales" -msgid "Graphs per notification (default: 5)" -msgstr "Gráficos por notificación (por defecto: 5)" - msgid "Graylog" msgstr "Graylog" @@ -26000,10 +26346,6 @@ msgstr "DN base del grupo" msgid "Group discovery and activation for up to" msgstr "Descubrimiento y activación de grupos de hasta" -#, fuzzy -msgid "Group execution interval" -msgstr "Intervalo de ejecución" - msgid "Group files based on a regular expression pattern." msgstr "Agrupar archivos en base a un patrón de expresión regular." @@ -26204,6 +26546,10 @@ msgstr "HPE StoreOnce vía REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: Memoria utilizada vía SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Parámetros del modelo" + #, fuzzy msgid "HTML email" msgstr "Correo electrónico HTML" @@ -27557,6 +27903,10 @@ msgstr "Ocultar los nombres de las variables de configuración" msgid "Hide notification bulks" msgstr "norma de notificación" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Enviar notificaciones por separado a cada destinatario" + msgid "Hide response from socket" msgstr "Ocultar la respuesta de la toma de corriente" @@ -27623,6 +27973,10 @@ msgstr "Historia" msgid "History Line Number" msgstr "Número de línea del historial" +#, fuzzy +msgid "History action type" +msgstr "Estado de registro" + msgid "History entries of one specific event" msgstr "Entradas del historial de un evento específico" @@ -29305,10 +29659,6 @@ msgstr "Resumen del host" msgid "Host parent/child topology" msgstr "Topología padre-hijo del host" -#, fuzzy -msgid "Host path" -msgstr "Alerta de anfitrión" - msgid "Host performance data" msgstr "Datos de rendimiento del host" @@ -30024,6 +30374,10 @@ msgstr "IP - región - ID de instancia" msgid "IP Address" msgstr "Dirección IP" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "Dirección IP del host" + msgid "IP address" msgstr "Dirección IP" @@ -32029,21 +32383,6 @@ msgstr "" "coincidan. Tenga en cuenta que esto afecta a todo lo que forma parte de los " "espacios de nombres coincidentes, como los pods, por ejemplo." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Advertencia

    Usted no ha configurado una " -"dirección de correo electrónico alternativa ni ha habilitado la " -"recepción de correos electrónicos alternativos para ningún usuario. Si su " -"supervisión produce una notificación que no coincide con ninguna de sus " -"reglas de notificación, la notificación no se enviará. Para evitarlo, " -"configure la configuración global o habilite la opción de contacto " -"alternativo para al menos uno de sus usuarios." - msgid "Ignore" msgstr "Ignora" @@ -33024,6 +33363,15 @@ msgstr "Índices a buscar, por defecto '*', que significa todos los índices." msgid "Indexspace wasted" msgstr "Espacio de índice desperdiciado" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Si el último descubrimiento masivo falló o no. Se establece como True una " +"vez que falla y se desestablece en caso de que un descubrimiento posterior " +"tenga éxito." + msgid "Indices" msgstr "Índices" @@ -33694,6 +34042,10 @@ msgstr "Certificado no válido" msgid "Invalid certificate file: %s" msgstr "Archivo de certificado inválido: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Parámetro inválido %r: %s" + msgid "Invalid check parameter" msgstr "Parámetro de comprobación no válido" @@ -36539,6 +36891,10 @@ msgstr "Inventario multirruta de Linux" msgid "Linux and Solaris Multipath Count" msgstr "Recuento de rutas múltiples en Linux y Solaris" +#, fuzzy +msgid "Linux bonding" +msgstr "Vinculación de Vswitch" + msgid "Linux bonding interface status" msgstr "Estado de la interfaz de enlace de Linux" @@ -37137,6 +37493,10 @@ msgstr "" "Registra el proceso de registro de agentes de las solicitudes entrantes " "mediante el comando de registro del controlador de agentes Checkmk." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Activar la eliminación automática de hosts" + msgid "Log: Details" msgstr "Registro: Detalles" @@ -37653,6 +38013,10 @@ msgstr "" "Número total de clientes pendientes en un nivel inferior de bloqueo de " "llamadas" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Lista de archivos de registro esperados" + msgid "Lowest: No notification, update badge number" msgstr "Lo más bajo: No se notifica, se actualiza el número de placa" @@ -38238,10 +38602,25 @@ msgstr "Gestionar los usuarios del sistema de vigilancia." msgid "Managed Robot" msgstr "Objetos gestionados" +#, fuzzy +msgid "Managed Robots" +msgstr "Objetos gestionados" + #, fuzzy msgid "Managed objects" msgstr "Objetos gestionados" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Objetos gestionados" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Objetos gestionados" + msgid "Management board" msgstr "Consejo de Administración" @@ -39822,14 +40201,14 @@ msgstr "Conexiones mínimas por segundo" msgid "Minimum error count" msgstr "Recuento mínimo de errores" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Niveles mínimos de tensión" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Niveles mínimos de carga en porcentaje" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Niveles mínimos de tensión" + msgid "Minimum levels if using magic factor" msgstr "Niveles mínimos si se utiliza el factor mágico" @@ -39938,6 +40317,10 @@ msgstr "Duración no programada (sólo DaemonSet)" msgid "Misscheduled replicas" msgstr "Réplicas no programadas" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Falta la variable siteid" + #, python-format msgid "Missing config file for agent %s%s" msgstr "Falta un archivo de configuración para el agente %s%s" @@ -41442,6 +41825,11 @@ msgstr "Resolución del nombre" msgid "Name your %s for easy recognition." msgstr "Ponle un nombre a tu %s para reconocerlo fácilmente." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -41456,13 +41844,13 @@ msgstr "Nombres" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects
    . Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" @@ -41875,6 +42263,29 @@ msgstr "Siguiente notificación" msgid "Next run" msgstr "Próxima carrera" +#, fuzzy +msgid "Next step: General properties" +msgstr "Propiedades generales" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugins de notificación" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Destinatario" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "conexiones pendientes" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Tipo de comentario (host/servicio)" + msgid "Nginx Server" msgstr "Servidor Nginx" @@ -41890,6 +42301,10 @@ msgstr "Niveles ágiles de IO" msgid "No" msgstr "No" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Configuración de host" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "No (Error: %s, Código: %d, Profundidad: %d)" @@ -41897,6 +42312,10 @@ msgstr "No (Error: %s, Código: %d, Profundidad: %d)" msgid "No API integrations, no Checkmk agent" msgstr "No hay integraciones API, ni agente Checkmk" +#, fuzzy +msgid "No AWS services found." +msgstr "No se han encontrado hosts/servicios." + msgid "No CSRF token received" msgstr "No se ha recibido ningún token CSRF" @@ -41907,6 +42326,10 @@ msgstr "Sin condiciones" msgid "No Configuration Quick setup for %s available" msgstr "Variable de configuración:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Regla de notificación modificada %d" + msgid "No IP" msgstr "Sin IP" @@ -41984,10 +42407,6 @@ msgstr "En esta vista no se pueden realizar comandos" msgid "No conditions" msgstr "Sin condiciones" -#, fuzzy -msgid "No configuration yet" -msgstr "Configuración de host" - msgid "No configured rules are affected" msgstr "Ninguna regla configurada se ve afectada" @@ -42044,6 +42463,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "no disponible" + +#, fuzzy +msgid "No elements selected" +msgstr "No seleccionado" + msgid "No entries" msgstr "No hay entradas" @@ -42177,6 +42604,10 @@ msgstr "No hay conexiones definidas" msgid "No need for syncing sites" msgstr "No es necesario sincronizar los sitios" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Regla de notificación modificada %d" + msgid "No object type" msgstr "Ningún tipo de objeto" @@ -42189,6 +42620,10 @@ msgstr "" msgid "No password provided" msgstr "Desde el almacén de contraseñas" +#, fuzzy +msgid "No password selected" +msgstr "Desde el almacén de contraseñas" + msgid "No pending changes" msgstr "No hay cambios pendientes" @@ -42268,6 +42703,10 @@ msgstr "No hay búsqueda" msgid "No search, specify list of arguments" msgstr "No buscar, especificar lista de argumentos" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthosts" + #, fuzzy msgid "No snapshot to restore available." msgstr "No hay información disponible" @@ -42731,6 +43170,9 @@ msgstr "Notificación" msgid "Notation: %s" msgstr "Anotaciones: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42898,6 +43340,18 @@ msgstr "Nivel de registro de notificaciones" msgid "Notification method" msgstr "Método de notificación" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "La colección de gráficos '%s' no existe" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugins de notificación" + +#, fuzzy +msgid "Notification parameter" +msgstr "Fase de notificación" + #, fuzzy msgid "Notification period" msgstr "Período de notificación" @@ -43350,6 +43804,14 @@ msgstr "Número de carpetas a crear en cada nivel" msgid "Number of goroutines" msgstr "Número de reintentos" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Gráficos por notificación (por defecto: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Gráficos por notificación (por defecto: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Número de hosts saludables niveles inferiores" @@ -44008,8 +44470,8 @@ msgid "OTLP endpoint" msgstr "Puntos finales" #, fuzzy -msgid "OVS bonding interface status" -msgstr "Interfaces de unión" +msgid "OVS bonding" +msgstr "Vinculación de Vswitch" msgid "Object" msgstr "Objeto" @@ -46064,6 +46526,10 @@ msgstr "Actualidad general" msgid "Overall latency" msgstr "Latencia global" +#, fuzzy +msgid "Overall response time" +msgstr "Tiempo medio de respuesta" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "Estado general de una máquina virtual (por ejemplo, ESX VMs)" @@ -46127,7 +46593,7 @@ msgstr "" "construcción" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Unidad de anulación del sensor" msgid "Override unit of sensor" @@ -46723,13 +47189,16 @@ msgstr "Carga de conexiones paralelas" msgid "Parallel pings to send" msgstr "Pings paralelos para enviar" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Ejecución del programa" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Paralizar la creación de la configuración del núcleo" +#, fuzzy +msgid "Parameter" +msgstr "Parámetros" + msgid "Parameter groups" msgstr "Grupos de parámetros" @@ -46739,6 +47208,10 @@ msgstr "Grupos de parámetros por región" msgid "Parameter name" msgstr "Nombre del parámetro" +#, fuzzy +msgid "Parameter properties" +msgstr "Propiedades del paquete" + msgid "Parameter rule set" msgstr "Conjunto de reglas de los parámetros" @@ -46763,6 +47236,10 @@ msgstr "" "puede insertar el valor real de los parámetros mediante $HOST$ y " "$INST$ (encerrados entre signos de dólar)." +#, fuzzy +msgid "Parameters for" +msgstr "Parámetros para %s" + #, python-format msgid "Parameters for %s" msgstr "Parámetros para %s" @@ -46770,6 +47247,10 @@ msgstr "Parámetros para %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parámetros para las fases de entrada de los SAIs y PDUs" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Parámetros para este host" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parámetros de las cargas de salida de los SAIs y PDUs" @@ -47822,6 +48303,10 @@ msgstr "Hacer ping a la dirección IP normal" msgid "Ping timeout" msgstr "Tiempo de espera de ping" +#, fuzzy +msgid "Placeholder" +msgstr "VMs de marcador de posición" + msgid "Placeholder VMs" msgstr "VMs de marcador de posición" @@ -47872,6 +48357,10 @@ msgid "" "be unique." msgstr "Mapa de combinaciones de estado operativo y de administración" +#, fuzzy +msgid "Plan settings" +msgstr "Configuración global" + msgid "Plans" msgstr "" @@ -47899,6 +48388,10 @@ msgstr "Por favor, añada al menos una columna a su vista." msgid "Please add at least one endpoint to monitor" msgstr "Por favor, añada al menos una columna a su vista." +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Por favor, añada al menos un nodo hijo." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47960,6 +48453,10 @@ msgstr "Por favor, elija una imagen PNG válida." msgid "Please choose an audit log to view:" msgstr "Por favor, elija un archivo para cargar." +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Elija un informe para programar" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Por favor, elija el plugin de verificación" @@ -48622,6 +49119,10 @@ msgstr "Plugins, comprobaciones locales y MRPE para usuarios no root" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Salida del plugin" + msgid "Plugins" msgstr "Plugins" @@ -48766,6 +49267,10 @@ msgstr "Coincidencia positiva (añadir los hosts coincidentes al conjunto)" msgid "Positive match (Add matching services to the set)" msgstr "Coincidencia positiva (Añadir servicios coincidentes al conjunto)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Coincidencia positiva (añadir los hosts coincidentes al conjunto)" + msgid "Postfix" msgstr "Postfix" @@ -48949,6 +49454,10 @@ msgstr "Texto del prefijo" msgid "Prepare AWS for Checkmk" msgstr "Inicialización de GIT para Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "Inicialización de GIT para Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Preagregar el prefijo del espacio de nombres para los hosts" @@ -49618,11 +50127,10 @@ msgstr "Ejecución del plugin del agente de Python (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" #, fuzzy @@ -49858,14 +50366,15 @@ msgstr "Leer average exe" msgid "RCC profile configuration" msgstr "Configuración remota" -#, fuzzy, python-format +#, fuzzy msgid "" -"RCC profile configuration (%s because Robotmk Core MKP has been installed)" +"RCC profile configuration (⚠ not available because Robotmk Core MKP " +"has been installed)" msgstr "Usar SSL para la conexión." msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" msgid "RCU" @@ -50473,6 +50982,10 @@ msgstr "Destinatario" msgid "Recipient email address" msgstr "Dirección de correo electrónico del destinatario" +#, fuzzy +msgid "Recipients" +msgstr "Destinatario" + #, python-format msgid "Recipients: %s" msgstr "Destinatarios: %s" @@ -50981,6 +51494,10 @@ msgstr "Vida restante" msgid "Remaining Open Slots" msgstr "Plazas libres restantes" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Días de validez restantes" + msgid "Remaining credits lower levels" msgstr "Créditos restantes niveles inferiores" @@ -51143,10 +51660,6 @@ msgstr "Eliminar todos los archivos y subdirectorios" msgid "Remove downtimes" msgstr "Eliminar los tiempos de inactividad" -#, fuzzy -msgid "Remove downtimes?" -msgstr "Eliminar los tiempos de inactividad" - msgid "Remove explicit attribute settings" msgstr "Eliminar la configuración explícita de atributos" @@ -51176,6 +51689,10 @@ msgstr "eliminar todos los tiempos de inactividad programados de " msgid "Remove service" msgstr "Eliminar el servicio" +#, fuzzy +msgid "Remove smarthost" +msgstr "Mover esta entrada" + #, fuzzy msgid "Remove style" msgstr "Eliminar todo" @@ -51767,6 +52284,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Solicita datos de una instancia de jenkins." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Solicita datos de una instancia de jenkins." @@ -51812,6 +52333,10 @@ msgstr "Puerto requerido" msgid "Required context filters" msgstr "Filtros de contexto necesarios" +#, fuzzy +msgid "Required field missing" +msgstr "Falta el sitio" + msgid "Required match (regular expression)" msgstr "Coincidencia obligatoria (expresión regular)" @@ -52137,6 +52662,10 @@ msgstr "" msgid "Restrict number of processed messages per cycle" msgstr "Restringir el número de mensajes procesados por ciclo" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Restringir la gravedad a lo peor" + msgid "Restrict runtime of logfile parsing" msgstr "Restringir el tiempo de ejecución del análisis de archivos de registro" @@ -52279,6 +52808,11 @@ msgstr "" "Recuperar información de procesos mediante WMI (Windows Management " "Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Reintentar" @@ -52306,6 +52840,10 @@ msgstr "Reintentar esta prueba" msgid "Retry time" msgstr "Tiempo de reintento" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "devuelve CRITICAL si se encuentra, OK si no" + msgid "Return code class 2xx (success)" msgstr "Código de retorno clase 2xx (éxito)" @@ -52324,7 +52862,12 @@ msgstr "" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -52347,10 +52890,19 @@ msgstr "Activar los cambios en el extranjero" msgid "Review and run preview service discovery" msgstr "Guardar & ejecutar la detección de servicios" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configuración remota" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Guardar & ejecutar la detección de servicios" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Revoluciones por minuto" @@ -52403,6 +52955,10 @@ msgstr "Marco de trabajo de los robots: %s" msgid "Robot Framework: Last log" msgstr "Marco del robot: Último registro" +#, fuzzy +msgid "Robot package" +msgstr "Retire el paquete" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -53517,12 +54073,14 @@ msgstr "Crear una copia de esta agregación" msgid "Save response" msgstr "Guardar respuesta" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Guarde este host y vaya a" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "" @@ -53575,10 +54133,6 @@ msgstr "Programar el tiempo de inactividad en el host" msgid "Schedule downtime on service" msgstr "Programar el tiempo de inactividad en el host" -#, fuzzy -msgid "Schedule downtime?" -msgstr "Programar los tiempos de inactividad" - msgid "Schedule downtimes" msgstr "Programar los tiempos de inactividad" @@ -53950,6 +54504,10 @@ msgstr "" msgid "Secret access key" msgstr "Clave secreta" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Clave secreta" + msgid "Secret key" msgstr "Clave secreta" @@ -54124,6 +54682,15 @@ msgstr "Seleccione un archivo iCalendar (*.ics) de su PC" msgid "Select and configure AWS services you would like to monitor" msgstr "Servicios Azure a supervisar" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Servicios Azure a supervisar" + +#, fuzzy +msgid "Select contact group" +msgstr "Grupos de contacto de las reglas" + #, fuzzy msgid "Select datasource" msgstr "Seleccione la fuente de datos" @@ -54325,6 +54892,10 @@ msgstr "Seleccione el tipo de elemento fijo de la página" msgid "Select type from list" msgstr "Seleccionar archivos individuales de la lista" +#, fuzzy +msgid "Select user" +msgstr "Borrar usuario" + msgid "Select view" msgstr "Seleccione la vista" @@ -54362,6 +54933,10 @@ msgstr "Los %s seleccionados han sido borrados." msgid "Selected credential has been deleted" msgstr "La credencial ha sido eliminada" +#, fuzzy +msgid "Selected options" +msgstr "Conexiones rechazadas" + msgid "Selected sections will not be executed by the agent." msgstr "Las secciones seleccionadas no serán ejecutadas por el agente." @@ -54432,6 +55007,10 @@ msgstr "Enviar datos HTTP POST" msgid "Send custom notification" msgstr "Enviar notificación personalizada" +#, fuzzy +msgid "Send custom notification?" +msgstr "Enviar notificación personalizada" + #, fuzzy msgid "Send data" msgstr "Datos mapeados" @@ -54476,9 +55055,7 @@ msgid "Send notifications to remote Event Console" msgstr "Enviar notificaciones a la Consola de Eventos remota" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "Ordenación de las notificaciones masivas" msgid "" @@ -54488,10 +55065,6 @@ msgstr "" "Enviar independientemente de las restricciones, por ejemplo, periodo de " "notificación o notificaciones desactivadas (forzado)" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Enviar notificaciones por separado a cada destinatario" - msgid "Send service metrics to Graphite" msgstr "Enviar métricas de servicio a Graphite" @@ -54534,6 +55107,10 @@ msgstr "Enviar por correo electrónico" msgid "Sending Power" msgstr "Envío de energía" +#, fuzzy +msgid "Sending conditions" +msgstr "Establecer condiciones" + msgid "Sending reply" msgstr "Envío de respuesta" @@ -54588,7 +55165,11 @@ msgid "September" msgstr "Septiembre" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Intervalo de ejecución" + +#, fuzzy +msgid "Sequence of plans" msgstr "Ejecución del programa" msgid "Serial" @@ -54831,6 +55412,10 @@ msgstr "Descubrimiento del servicio: Descripción del servicio" msgid "Service discovery: State" msgstr "Descubrimiento del servicio: Estado" +#, fuzzy +msgid "Service events" +msgstr "Nivel de servicio" + msgid "Service goes into critical state" msgstr "El servicio entra en estado crítico" @@ -55167,6 +55752,10 @@ msgstr "Servicios del sitio" msgid "Services per cluster" msgstr "Servicios por clúster" +#, fuzzy +msgid "Services per region" +msgstr "Servicios por región a controlar" + msgid "Services per region to monitor" msgstr "Servicios por región a controlar" @@ -55709,7 +56298,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -56086,6 +56675,10 @@ msgstr "Mostrar casillas de verificación" msgid "Show column headings" msgstr "Mostrar los títulos de las columnas" +#, fuzzy +msgid "Show contact groups" +msgstr "Acoger grupos de contacto" + msgid "Show context" msgstr "Mostrar contexto" @@ -56153,9 +56746,17 @@ msgstr "Mostrar pista en el menú \"Usuario" msgid "Show historic values" msgstr "Mostrar valores históricos" +#, fuzzy +msgid "Show host labels" +msgstr "Mostrar en las tablas de hosts" + msgid "Show host status" msgstr "Mostrar el estado del host" +#, fuzzy +msgid "Show host tags" +msgstr "Mostrar el estado del host" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Mostrar icono de enlace al editor de parámetros de configuración de los " @@ -56235,6 +56836,10 @@ msgstr "Mostrar más / Mostrar menos" msgid "Show notification bulks" msgstr "norma de notificación" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Ordenación de las notificaciones masivas" + msgid "Show number of groups" msgstr "Mostrar número de grupos" @@ -56299,6 +56904,10 @@ msgstr "Mostrar las reglas que utilizan este %s" msgid "Show separate result for each SLA period" msgstr "Mostrar el resultado por separado para cada período de SLA" +#, fuzzy +msgid "Show service labels" +msgstr "Etiquetas de servicio" + #, fuzzy msgid "Show service name" msgstr "El nombre del servicio" @@ -56689,6 +57298,11 @@ msgstr "" "el nodo que fue crucial para el resultado global (el preferido en caso de " "duda). Puede anular este automatismo especificando un nodo aquí." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -57628,6 +58242,10 @@ msgstr "Objetos específicos" msgid "Specific sites" msgstr "Sitios específicos" +#, fuzzy +msgid "Specific users" +msgstr "Sitios específicos" + msgid "Specific version" msgstr "Versión específica" @@ -57651,13 +58269,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Especifica el estilo de línea por defecto" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Especifica si se permite la autenticación con contraseña" @@ -57829,13 +58440,6 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -58289,6 +58893,11 @@ msgstr "" "Especifica lo que debemos hacer si el gráfico seleccionado falta o no se " "puede recuperar." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Especificar qué tipos de puertos no deben ser descubiertos" @@ -58506,6 +59115,10 @@ msgstr "Inicio del próximo año" msgid "Start or end of a scheduled downtime" msgstr "Inicio o fin de un tiempo de inactividad programado" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Inicio del tiempo de inactividad" + msgid "Start or end of flapping state" msgstr "Inicio o fin del estado de aleteo" @@ -58732,6 +59345,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Estado de la cadena esperada" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Advertencia sobre una interfaz activa inesperada" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Descubrimiento de servicios pendientes" + msgid "State if 'maintenance' services are found" msgstr "Indicar si se encuentran servicios de \"mantenimiento" @@ -59766,10 +60387,12 @@ msgstr "Nombre de la sección" msgid "Subject for bulk notifications" msgstr "Asunto de las notificaciones masivas" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Asunto para las notificaciones de los hosts" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Asunto de las notificaciones de servicio" msgid "Submit" @@ -60171,6 +60794,10 @@ msgstr "Sincrónico" msgid "Syncing" msgstr "Sincronización de" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "Certificado del router SAP" + msgid "Synology Updates" msgstr "Actualizaciones de Synology" @@ -60463,6 +61090,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "La autenticación TLS sin TLS no es posible" +#, fuzzy +msgid "TLS certificate verification" +msgstr "Verificación del certificado SSL" + #, fuzzy msgid "TLS processed bytes" msgstr "Bytes procesados por TLS" @@ -60687,6 +61318,16 @@ msgstr "" "Las etiquetas pueden utilizarse para clasificar los hosts y los servicios de " "forma flexible." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "No se ha definido ninguna fuente de datos." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Etiquetas de la alerta." @@ -60931,6 +61572,10 @@ msgstr "Crear una copia de esta regla de notificación" msgid "Test authentication" msgstr "Autenticación por token" +#, fuzzy +msgid "Test configuration" +msgstr "Configuración de host" + #, fuzzy msgid "Test connection" msgstr "Esta conexión" @@ -60965,6 +61610,9 @@ msgstr "última notificación" msgid "Test runtime" msgstr "Tiempo de ejecución del proceso" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + #, fuzzy msgid "Test verification" msgstr "Verificación de licencias" @@ -62217,6 +62865,10 @@ msgstr "" msgid "The central (%s) and remote site (%s) are not compatible. Reason: %s" msgstr "El sitio central (%s) y el remoto (%s) no son compatibles. Razón: %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "Nunca se ha activado" + #, python-format msgid "The character %s is not allowed here." msgstr "El carácter %s no está permitido aquí." @@ -62505,6 +63157,11 @@ msgstr "" "La conexión crea hosts en esta carpeta concreta. Una vez creado, puede " "elegir mover el host a otra carpeta." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "La conexión a este sitio ha sido desactivada." @@ -62773,25 +63430,6 @@ msgstr "El elemento no se encuentra en el cuadro de mandos." msgid "The element does not exist." msgstr "El elemento no existe." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"La dirección de correo electrónico y el nombre visible utilizados en la " -"cabecera De de los mensajes de notificación. Si no se especifica ninguna " -"dirección de correo electrónico, se utiliza la dirección por defecto " -"OMD_SITE@FQDN. Si la variable de entorno OMD_SITE no está " -"establecida, se utiliza por defecto checkmk." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"La dirección de correo electrónico y el nombre visible que se utiliza en la " -"cabecera Reply-To de los mensajes de notificación." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -63158,12 +63796,6 @@ msgstr "Falta la especificación del gráfico" msgid "The graph template id '%s' is disabled" msgstr "El identificador de la plantilla gráfica '%s' está desactivado" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -63399,13 +64031,6 @@ msgstr "" "El nombre de la instancia, el nombre de la base de datos y el nombre del " "tablespace combinados así db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -63789,6 +64414,12 @@ msgstr "" "que este servicio entre en alerta/crítico. Esta alarma solo se aplica al " "host de destino, no a los saltos intermedios." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "La longitud máxima del valor es de 256 caracteres." @@ -65441,6 +66072,20 @@ msgstr "" "Los umbrales para wait_duration_ms. Sobrescribirá el estado por defecto " "establecido anteriormente." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "Los datos estadísticos del intervalo de tiempo se guardan en el disco" @@ -65595,6 +66240,14 @@ msgid "The username returned by the %s connector is not of type string (%r)." msgstr "" "El nombre de usuario devuelto por el conector %s no es de tipo cadena (%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"El nombre de usuario que debe usarse para acceder a la API de Graylog. Tiene " +"que tener permisos de lectura al menos." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -65897,8 +66550,8 @@ msgstr "No hay ninguna instantánea de configuración que restaurar." msgid "There is no backup job configured" msgstr "No hay ningún trabajo de copia de seguridad configurado" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "No hay ninguna plantilla de gráfico con el id '%s'" msgid "There is no manpage for this check." @@ -66071,7 +66724,7 @@ msgstr "Estos nodos sólo están en la agregación congelada" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" msgid "" @@ -66399,6 +67052,9 @@ msgstr "" "cuyo caso también necesitas restablecer el controlador de agente en el host " "supervisado (consulta la `cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + #, fuzzy msgid "" "This active check sends out special emails to a defined mail address using " @@ -67156,7 +67812,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -68006,8 +68662,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Este permiso permite a los usuarios migrar a otros usuarios a otra conexión" @@ -68622,13 +69277,6 @@ msgstr "" "conducirá a cambios frecuentes en el inventario HW/SW, lo que puede llenar " "rápidamente el sistema de archivos temporales." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Esta regla permite la monitorización de VMware ESX a través de la API de " -"vSphere. Aquí puede configurar los ajustes de conexión." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -69316,15 +69964,6 @@ msgstr "" "Applainces en lugar del agente Checkmk normal y permite la supervisión a " "través de Web API. " -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Este conjunto de reglas selecciona el agente especial para HPE StoreOnce " -"Appliances en lugar del agente Checkmk normal y permite la supervisión a " -"través de REST API v4.x o superior. " - #, fuzzy msgid "" "This rule sets limits to the current number of connections through a Check " @@ -74161,9 +74800,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "Se ha intentado registrar un rulespec incompatible: %r" +#, fuzzy +msgid "Triggering events" +msgstr "Archivo de eventos" + msgid "Trivial change" msgstr "Cambio trivial" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -75374,6 +76020,14 @@ msgstr "Guardar respuesta" msgid "Upload verification response file" msgstr "Cargar respuesta de verificación" +#, fuzzy +msgid "Uploaded" +msgstr "Subir a" + +#, fuzzy +msgid "Uploaded by" +msgstr "Subir la clave" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "" @@ -76789,6 +77443,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">límite de eventos " "de la regla global" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Utilice esta opción para consultar un puerto diferente al puerto estándar " +"443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -76830,6 +77490,15 @@ msgstr "" "al siguiente servidor (fallback). La comprobación sólo emitirá datos del " "primer host que envíe una respuesta." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Utilice esta opción para establecer qué instancia debe ser comprobada por el " +"agente especial. Por favor, añada el nombre de host aquí, por ejemplo, " +"mi_graylog.com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -77235,7 +77904,8 @@ msgstr "Mensajes de los usuarios" msgid "User name" msgstr "Nombre de usuario" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Nombre de usuario en el sistema de almacenamiento. Los permisos de sólo " "lectura son suficientes." @@ -77332,6 +78002,10 @@ msgstr "Usuarios en el Directorio Activo" msgid "Users listed here are still allowed to modify things." msgstr "Los usuarios que aparecen aquí todavía pueden modificar cosas." +#, fuzzy +msgid "Users of contact groups" +msgstr "Miembros de los grupos de contacto" + msgid "Users using a cifs share" msgstr "Usuarios que utilizan un recurso compartido cifs" @@ -78378,6 +79052,10 @@ msgstr "Verificar los certificados" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Ignorar los errores de los certificados (no seguros)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Ignorar los errores de los certificados (no seguros)" + msgid "Verify certificates" msgstr "Verificar los certificados" @@ -78442,6 +79120,9 @@ msgstr "Versión del dispositivo PKI" msgid "Version of Server" msgstr "Versión del servidor" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Versiones: %s" @@ -78906,6 +79587,10 @@ msgstr "Conexiones en espera" msgid "Waiting containers" msgstr "Contenedores de espera" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Descubrimiento de puertos de Netapp" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -79296,6 +79981,9 @@ msgstr "¿Cuál es la ocasión?" msgid "What is the purpose?" msgstr "" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -80360,6 +81048,10 @@ msgstr "" msgid "Who" msgstr "Quién" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "permitir a los usuarios desactivar esta notificación" + msgid "WiFi connection types" msgstr "Tipos de conexión WiFi" @@ -80521,7 +81213,7 @@ msgstr "" msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -80841,6 +81533,13 @@ msgstr "" "adelante si se configura algún parámetro. Esto puede ser confuso.Esta regla sólo debe ser configurada en las primeras etapas." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -81775,6 +82474,14 @@ msgstr "No se puede eliminar la conexión con el sitio local." msgid "You can not delete this %s because it is in use." msgstr "No puede eliminar este %s porque está en uso." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"No puede eliminar este objetivo porque es utilizado por estos trabajos de " +"copia de seguridad: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -82606,6 +83313,10 @@ msgstr "" "Todavía no ha creado ninguna clave de firma de agente . " "Esto es necesario." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Parámetros para este host" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -84542,9 +85253,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "monitor" - msgid "month" msgstr "mes" @@ -85470,6 +86178,9 @@ msgstr "{actual} es demasiado alto. El valor máximo permitido es {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} es demasiado bajo. El valor mínimo permitido es {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -85478,6 +86189,138 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Todos los derechos reservados." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Usar SSL para la conexión." + +#~ msgid "API key from password store" +#~ msgstr "Clave API del almacén de contraseñas" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Alerta de anfitrión" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Fallo en la obtención del certificado de pares (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Advertencia

    Usted no ha configurado una " +#~ "dirección de correo electrónico alternativa ni ha habilitado la " +#~ "recepción de correos electrónicos alternativos para ningún usuario. Si su " +#~ "supervisión produce una notificación que no coincide con ninguna de sus " +#~ "reglas de notificación, la notificación no se enviará. Para evitarlo, " +#~ "configure la configuración global o habilite la opción de contacto " +#~ "alternativo para al menos uno de sus usuarios." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Notificaciones masivas con gráficos (por defecto: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Por defecto, todos los gráficos múltiples en los correos electrónicos se " +#~ "muestran flotando cerca. Puede activar esta opción para mostrar los " +#~ "gráficos entre sí." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configurar esto para que el plugin de notificaciones se conecte " +#~ "directamente al servidor smtp. Esto tiene la ventaja de proporcionar " +#~ "mejores mensajes de error en caso de un error, pero requiere más " +#~ "configuración y es estrictamente sincrónico, por lo que aconsejamos su " +#~ "uso sólo en instalaciones empresariales que utilicen el spooler de " +#~ "notificaciones." + +#~ msgid "Display additional information" +#~ msgstr "Mostrar información adicional" + +#~ msgid "Display graphs among each other" +#~ msgstr "Visualizar los gráficos entre sí" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Los gráficos se muestran entre sí" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "La dirección de correo electrónico y el nombre visible utilizados en la " +#~ "cabecera De de los mensajes de notificación. Si no se especifica ninguna " +#~ "dirección de correo electrónico, se utiliza la dirección por defecto " +#~ "OMD_SITE@FQDN. Si la variable de entorno OMD_SITE no " +#~ "está establecida, se utiliza por defecto checkmk." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "La dirección de correo electrónico y el nombre visible que se utiliza en " +#~ "la cabecera Reply-To de los mensajes de notificación." + +#~ msgid "Activate" +#~ msgstr "Activar" + +#~ msgid "Deactivate" +#~ msgstr "Desactivar" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Esta regla permite la monitorización de VMware ESX a través de la API de " +#~ "vSphere. Aquí puede configurar los ajustes de conexión." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Este conjunto de reglas selecciona el agente especial para HPE StoreOnce " +#~ "Appliances en lugar del agente Checkmk normal y permite la supervisión a " +#~ "través de REST API v4.x o superior. " + +#~ msgid "monitor" +#~ msgstr "monitor" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Nombre de la cuenta de almacenamiento" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Ejecución del programa" + +#~ msgid "(not supported)" +#~ msgstr "(no soportado)" + +#, fuzzy +#~ msgid "Remove downtimes?" +#~ msgstr "Eliminar los tiempos de inactividad" + +#, fuzzy +#~ msgid "Schedule downtime?" +#~ msgstr "Programar los tiempos de inactividad" + +#, fuzzy +#~ msgid "OVS bonding interface status" +#~ msgstr "Interfaces de unión" + #~ msgid "Common Name" #~ msgstr "Nombre común" @@ -85574,11 +86417,6 @@ msgstr "© %s Checkmk GmbH. Todos los derechos reservados." #~ msgid "Database for PostgreSQL" #~ msgstr "Base de datos para PostgreSQL" -#~ msgid " to get notified once the commercial release is available. " -#~ msgstr "" -#~ " para recibir una notificación cuando el lanzamiento comercial esté " -#~ "disponible. " - #, fuzzy #~ msgid "Checkmk Cloud (SaaS) Beta" #~ msgstr "Agente Checkmk" @@ -85612,10 +86450,6 @@ msgstr "© %s Checkmk GmbH. Todos los derechos reservados." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Cuota utilizada: Niveles superiores absolutos o relativos" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "Nunca se ha activado" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Espacios de mesa" @@ -85917,10 +86751,6 @@ msgstr "© %s Checkmk GmbH. Todos los derechos reservados." #~ msgid "%s operations" #~ msgstr "%s operaciones" -#, python-format -#~ msgid "%s requests" -#~ msgstr "%s solicitudes" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -86263,9 +87093,6 @@ msgstr "© %s Checkmk GmbH. Todos los derechos reservados." #~ msgid "InfluxDB Queue Usage" #~ msgstr "Uso de la cola InfluxDB" -#~ msgid "Kernel Version" -#~ msgstr "Versión del núcleo" - #~ msgid "Levels Helper usage Check" #~ msgstr "Niveles Comprobación de uso del ayudante" diff --git a/locale/fr/LC_MESSAGES/multisite.po b/locale/fr/LC_MESSAGES/multisite.po index 109824caf74..4ce29f76012 100644 --- a/locale/fr/LC_MESSAGES/multisite.po +++ b/locale/fr/LC_MESSAGES/multisite.po @@ -405,6 +405,10 @@ msgstr "%d jours" msgid "%d days ago" msgstr "Il y a %d jours" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Propriétés générales" + #, python-format msgid "%d errors occured:" msgstr "%d d'erreurs produites :" @@ -567,6 +571,10 @@ msgstr "%s par hôte" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -688,6 +696,10 @@ msgstr "taux de %s" msgid "%s resulting notifications" msgstr "%s notifications résultantes" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s Demandes" + #, python-format msgid "%s running for %s" msgstr "%s en cours d'exécution pour %s" @@ -806,9 +818,17 @@ msgstr "" "pour le visionnement de la configuration. Veuillez installer 'git' ou " "désactiver le suivi de la configuration git dans setup." +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Entrées supprimées" + msgid "(0 is current period)" msgstr "(0 est la période actuelle)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(pas d'entrée)" + msgid "(Edit presets)" msgstr "(Modifier les rapports)" @@ -884,9 +904,6 @@ msgstr "(sans titre)" msgid "(none)" msgstr "(aucun)" -msgid "(not supported)" -msgstr "(non pris en charge)" - msgid "(nothing selected)" msgstr "(rien de sélectionné)" @@ -999,6 +1016,10 @@ msgstr "1 changement" msgid "1 row" msgstr "1 rang" +#, fuzzy +msgid "1 rule" +msgstr "règle" + msgid "1 year" msgstr "1 an" @@ -1196,6 +1217,31 @@ msgstr "95ème percentile" msgid "99th percentile" msgstr "99ème percentile" +#, fuzzy +msgid "< Remove" +msgstr "Retirer" + +#, fuzzy +msgid "<< Remove all" +msgstr "Supprimer tout" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Piggybacktranslationssont effectuées avant que le connecteur piggyback ne crée des hôtes. " +"Utilisez ceci, par exemple, dans une configuration avec plusieurs nœuds " +"Docker pour préfixer les conteneurs avec le nom du nœud Docker " +"correspondant. Sinon, des collisions de noms peuvent se produire si des " +"conteneurs portant le même nom existent sur plus d'un nœud Docker." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Note3: Afin de déployer ce plugin sur Solaris, une " @@ -1370,6 +1416,12 @@ msgstr "Avertissement: Il y a %d werks incompatibles non reconnus :" msgid "You do not have any roles." msgstr "Vous n'avez aucun rôle." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1962,11 +2014,12 @@ msgstr "" "TNS_ADMIN à utiliser pour sqlnet.ora et tnsnames.ora %s" +#, fuzzy msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" "robot.yaml est le fichier de configuration principal du RCC. Il est " "spécifié par rapport au répertoire de base des projets Robot Framework. Ce " @@ -2152,6 +2205,14 @@ msgstr "Un titre pour les graphiques" msgid "A heading for the view" msgstr "Une rubrique pour la vue" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Un hôte portant le nom %s existe déjà dans le dossier
    %s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Ajouter %s" + msgid "Add Aggregation" msgstr "Ajouter l'agrégation" @@ -3666,11 +3744,6 @@ msgstr "Ajouter une exception" msgid "Add Group" msgstr "Ajouter un groupe" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"Ajouter une section HTML au-dessus du tableau (par exemple, titre, " -"description...)" - msgid "Add LDAP connection" msgstr "Ajouter une connexion LDAP" @@ -3716,6 +3789,9 @@ msgstr "Ajouter l'agrégation" msgid "Add alert handler rule" msgstr "Ajouter une règle de traitement des alertes" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Ajouter tous les services détectés mais pas encore surveillés à la " @@ -3819,6 +3895,10 @@ msgstr "Ajouter un élément : %s" msgid "Add elements to your sidebar" msgstr "Ajouter des éléments à votre barre latérale" +#, fuzzy +msgid "Add event" +msgstr "Ajouter un élément" + msgid "Add exception" msgstr "Ajouter une exception" @@ -4010,6 +4090,10 @@ msgstr "Ajouter une condition d'étiquetage" msgid "Add new pattern" msgstr "Ajouter un nouveau modèle" +#, fuzzy +msgid "Add new plan" +msgstr "Ajouter un nouveau modèle" + msgid "Add new project" msgstr "Ajouter un nouveau projet" @@ -4025,10 +4109,18 @@ msgstr "Ajouter une nouvelle règle" msgid "Add new scalar" msgstr "Ajouter un nouveau scalaire" +#, fuzzy +msgid "Add new sequence" +msgstr "Ajouter un nouveau service" + #, fuzzy msgid "Add new service" msgstr "Ajouter un nouveau service" +#, fuzzy +msgid "Add new smarthost" +msgstr "Ajouter une nouvelle macro" + msgid "Add new status" msgstr "Ajouter un nouveau statut" @@ -4071,6 +4163,10 @@ msgstr "Ajouter ou modifier des exécutables" msgid "Add page element" msgstr "Ajouter un élément de page" +#, fuzzy +msgid "Add parameter" +msgstr "Paramètres du modèle" + msgid "Add pattern" msgstr "Ajouter un motif" @@ -4096,6 +4192,10 @@ msgstr "Ajouter un pre ou postfix à TNSALIASes %s" msgid "Add random hosts" msgstr "Ajouter des hôtes aléatoires" +#, fuzzy +msgid "Add recipient" +msgstr "Bénéficiaire" + msgid "Add remote instance" msgstr "Ajouter une instance distante" @@ -4344,6 +4444,10 @@ msgid "Additional agent labels to send during registration" msgstr "" "Étiquettes supplémentaires à envoyer à l'agent lors de l'enregistrement" +#, fuzzy +msgid "Additional details" +msgstr "Options supplémentaires" + msgid "Additional header lines" msgstr "Lignes d'en-tête supplémentaires" @@ -4472,7 +4576,7 @@ msgid "Admin states to discover" msgstr "Des états administratifs à découvrir" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "États administratifs" msgid "Administrative port states to discover" @@ -5165,6 +5269,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "Configuration du gestionnaire d'alerte" +#, fuzzy +msgid "Alert handler execution" +msgstr "Exécution des gestionnaires d'alertes" + msgid "Alert handler execution, failed" msgstr "L'exécution du gestionnaire d'alerte a échoué" @@ -5280,6 +5388,15 @@ msgstr "Statistiques des alertes : Nombre d'alertes inconnues" msgid "Alert statistics: Number of warnings" msgstr "Statistiques d'alerte : Nombre d'alertes" +msgid "Alert when a major version release is available" +msgstr "" + +msgid "Alert when a minor version release is available" +msgstr "" + +msgid "Alert when a patch version release is available" +msgstr "" + msgid "Alerted" msgstr "Alerté" @@ -5386,6 +5503,10 @@ msgstr "Toutes les collections" msgid "All components" msgstr "Tous les composants" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Tous les contacts de l'objet notifié" + msgid "All contacts of the notified object" msgstr "Tous les contacts de l'objet notifié" @@ -5820,6 +5941,10 @@ msgstr "Permet de voir l'icône %s dans les vues des hôtes et des services" msgid "Allow unencrypted legacy communication" msgstr "Autoriser les communications non cryptées de l'héritage" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "permettre aux utilisateurs de désactiver cette notification" + msgid "Allowed Ciphers" msgstr "Ciphers autorisés" @@ -6434,6 +6559,10 @@ msgstr "Une autre synchronisation utilisateur est déjà en cours : %s" msgid "AntiVirus last update age" msgstr "Âge de la dernière mise à jour de l'antivirus" +#, fuzzy +msgid "Any" +msgstr "tout" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6613,9 +6742,21 @@ msgstr "Aperçu des applications" msgid "Applications, Processes & Services" msgstr "Applications, processus et services" +#, fuzzy +msgid "Applied to" +msgstr "Postulez à" + msgid "Apply" msgstr "Appliquer" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Règle de traitement des alertes" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Supprimer cette règle de notification" + #, fuzzy msgid "Apply Latency" msgstr "Latence" @@ -6639,6 +6780,11 @@ msgstr "Appliquer les conditions" msgid "Apply filters" msgstr "Appliquer les filtres" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Appliquer le temps de finition" @@ -6774,6 +6920,10 @@ msgstr "Obtenir les journaux d'audit à distance" msgid "Archive event" msgstr "Événements d'archives" +#, fuzzy +msgid "Archive event?" +msgstr "Événements d'archives" + msgid "Archive events" msgstr "Événements d'archives" @@ -6908,6 +7058,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Traduction du nom d'hôte pour les hôtes en ferroutage" @@ -7351,10 +7506,10 @@ msgstr "Auto-extensible" msgid "Automated environment setup (via RCC)" msgstr "" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Utiliser RCC pour l'exécution isolée (%s dans Robotmk Core)" msgid "Automatic" @@ -8720,6 +8875,10 @@ msgstr "Agents cuits" msgid "Baked host specific agent" msgstr "Agent spécifique de l'hôte cuit" +#, fuzzy +msgid "Bakery rules" +msgstr "Règles de découverte" + msgid "Baking Agents..." msgstr "Agents de cuisson..." @@ -9265,8 +9424,9 @@ msgstr "Importation groupée d'hôtes" msgid "Bulk move" msgstr "Déplacement en vrac" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Notifications en vrac avec graphiques (par défaut : 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Ouvrir les notifications groupées" msgid "Bulk removal of explicit attributes" msgstr "Suppression en bloc d'attributs explicites" @@ -9630,14 +9790,6 @@ msgstr "" "hôtes via SNMP v1/v2. Cette règle peut être utilisée pour personnaliser les " "informations d'identification à utiliser pour contacter les hôtes via SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Par défaut, tous les graphiques multiples dans les e-mails sont affichés de " -"manière flottante à proximité les uns des autres. Vous pouvez activer cette " -"option pour afficher les graphiques les uns à côté des autres." - msgid "By default all of the sections will be executed." msgstr "Par défaut, toutes les sections seront exécutées." @@ -9824,14 +9976,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" msgid "" @@ -9840,7 +9992,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" msgid "" @@ -10114,8 +10266,8 @@ msgstr "" msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11375,6 +11527,10 @@ msgstr "Modification de la connexion LDAP %s" msgid "Changed alert handler rule %d" msgstr "Modification de la règle de traitement des alertes %d" +#, fuzzy +msgid "Changed by" +msgstr "Modifié" + msgid "Changed entries" msgstr "Entrées modifiées" @@ -11390,6 +11546,14 @@ msgstr[1] "Étiquettes des hôtes modifiées : " msgid "Changed host selection has been saved." msgstr "La sélection d'hôte modifiée a été enregistrée." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Modification de la règle de notification %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Modification de la règle de notification %d" + #, python-format msgid "Changed notification rule %d" msgstr "Modification de la règle de notification %d" @@ -11409,6 +11573,11 @@ msgstr "Changement de la position de %s %d" msgid "Changed position of connection %s to %d" msgstr "Changement de la position de la connexion %s en %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "" +"Changement de la position de la règle de notification %d de l'utilisateur %s" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "" @@ -11468,6 +11637,10 @@ msgstr "" msgid "Changes" msgstr "Changements" +#, fuzzy +msgid "Changes activated" +msgstr "N'a jamais été activé" + msgid "Changes since last dump" msgstr "Changements depuis la dernière vidange" @@ -12788,6 +12961,11 @@ msgstr "" "Cliquez sur 'Enregistrer %s' pour activer l'authentification à deux facteurs " "via %s." +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Cliquez pour basculer ce paramètre" @@ -12947,6 +13125,10 @@ msgstr "Clonez cette connexion afin d'en créer une nouvelle" msgid "Clone this element" msgstr "Clonez cet élément" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Objets gérés" + msgid "Clone this metric" msgstr "Cloner cette métrique" @@ -13512,6 +13694,10 @@ msgstr "Terminez la restauration" msgid "Complete tree" msgstr "Arbre complet" +#, fuzzy +msgid "Complete variable list" +msgstr "Liste complète des variables (pour les tests)" + msgid "Complete variable list (for testing)" msgstr "Liste complète des variables (pour les tests)" @@ -13657,6 +13843,10 @@ msgstr "Fichiers de configuration ('*.mk' ou '*.conf') de etc/checkmk : %s" msgid "Configuration generation" msgstr "Génération de la configuration" +#, fuzzy +msgid "Configuration name" +msgstr "Configuration" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Configuration du composant Business Intelligence de Checkmk" @@ -13729,6 +13919,10 @@ msgstr "Configurer" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Surveillance des services Web d'Amazon (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Surveillance des services Web d'Amazon (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "Configurer les paramètres liés au SNMP à l'aide de jeux de règles" @@ -13796,6 +13990,10 @@ msgstr "Adresse de secours pour le rapport d'accident" msgid "Configure grouping of interfaces" msgstr "Configurer le regroupement des interfaces" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configuration" + #, fuzzy msgid "Configure host and regions" msgstr "Configuration" @@ -14023,6 +14221,10 @@ msgstr "" "Configurer le nom de la variable d'en-tête de la requête HTTP à lire à " "partir des requêtes HTTP entrantes" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configurer la découverte d'interfaces uniques" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -14055,20 +14257,6 @@ msgstr "" "fournissant la clé de l'utilisateur ou du groupe ici. La clé peut être " "obtenue sur le site web de Pushover." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configurer ceci pour que le plugin de notification se connecte directement " -"au serveur smtp. Cela a l'avantage de fournir de meilleurs messages d'erreur " -"en cas d'erreur mais cela nécessite plus de configuration et est strictement " -"synchrone, nous conseillons donc de l'utiliser uniquement sur les " -"installations d'entreprise utilisant le spooler de notification." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14471,6 +14659,10 @@ msgstr "Contact" msgid "Contact Name" msgstr "Nom du contact" +#, fuzzy +msgid "Contact group" +msgstr "Groupes de contact" + msgid "Contact group (effective)" msgstr "Groupe de contact (effectif)" @@ -14631,6 +14823,10 @@ msgstr "Informations sur le contexte" msgid "Context information about this connection" msgstr "Informations contextuelles sur cette connexion" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Informations contextuelles sur cette règle" + msgid "Context information about this rule" msgstr "Informations contextuelles sur cette règle" @@ -14895,6 +15091,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase : Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -15185,6 +15386,10 @@ msgstr "Créer une copie de cette connexion" msgid "Create a copy of this group" msgstr "Créer une copie de ce groupe" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Créer une copie de cette règle de notification" + msgid "Create a copy of this notification rule" msgstr "Créer une copie de cette règle de notification" @@ -15270,6 +15475,11 @@ msgstr "Créer un service supplémentaire pour les demandes de statistiques IO" msgid "Create additional service for system wait" msgstr "Créer un service supplémentaire pour le système d'attente" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Créer une annotation pour cette période" @@ -15380,6 +15590,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Créez un calendrier régulier pour ce rapport" +#, fuzzy +msgid "Create robot" +msgstr "Créer des hôtes" + msgid "Create separate notification bulks based on" msgstr "Créer des groupes de notification distincts en fonction de" @@ -15482,6 +15696,10 @@ msgstr "Création d'un nouvel hôte %s." msgid "Created new host tag group '%s'" msgstr "Création d'un nouveau groupe d'étiquettes d'hôte '%s'" +#, fuzzy +msgid "Created new notification parameter" +msgstr "Création d'une nouvelle règle de notification" + msgid "Created new notification rule" msgstr "Création d'une nouvelle règle de notification" @@ -15941,6 +16159,12 @@ msgstr "Conception personnalisée de l'interface graphique de %s" msgid "Custom Graph" msgstr "Graphique personnalisé" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "" +"Ajouter une section HTML au-dessus du tableau (par exemple, titre, " +"description...)" + msgid "Custom Icons" msgstr "Icônes personnalisées" @@ -16047,6 +16271,14 @@ msgstr "Localisations personnalisées" msgid "Custom logos" msgstr "Logos personnalisés" +#, fuzzy +msgid "Custom macro" +msgstr "Macros clients" + +#, fuzzy +msgid "Custom macros" +msgstr "Macros clients" + #, python-format msgid "Custom notification table for user %s" msgstr "Tableau de notification personnalisé pour l'utilisateur %s" @@ -16061,9 +16293,15 @@ msgstr "État de la sonde personnalisé" msgid "Custom profile" msgstr "Titre personnalisé" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Requête de recherche personnalisée" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Attributs de services personnalisés" @@ -16909,9 +17147,6 @@ msgstr "Tarif journalier" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Désactiver" - msgid "Deactivated" msgstr "Désactivé" @@ -17208,6 +17443,9 @@ msgstr "Profil utilisateur par défaut" msgid "Default value" msgstr "Valeur par défaut" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "Âge des dossiers différés" @@ -17263,6 +17501,9 @@ msgstr "" "surveillance, c'est-à-dire en résultat de la vérification. Ceci écrase le " "mappage par défaut utilisé par le contrôle." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Définir l'affectation des hôtes" @@ -17306,6 +17547,9 @@ msgstr "Définir des niveaux inférieurs pour le nombre de conteneurs en attente msgid "Define name of NetBIOS server" msgstr "Nom NetBIOS du serveur" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17552,6 +17796,10 @@ msgstr "Supprimer la clé de sauvegarde #%d" msgid "Delete comments" msgstr "Commentaire sur l'événement" +#, fuzzy +msgid "Delete comments?" +msgstr "Commentaire sur l'événement" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Configuration par défaut" @@ -17619,6 +17867,14 @@ msgstr "Supprimer le travail %d" msgid "Delete last alert handler rule" msgstr "Supprimer la dernière règle de traitement des alertes" +#, fuzzy +msgid "Delete managed robot" +msgstr "Objets gérés" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Supprimer la règle de notification #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Supprimer la règle de notification #%d" @@ -17772,9 +18028,17 @@ msgstr "Supprimer cette touche" msgid "Delete this logo" msgstr "Supprimer ce logo" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Supprimer ce groupe de tags" + msgid "Delete this metric" msgstr "Supprimer cette métrique" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Supprimer cette règle de notification" + msgid "Delete this notification rule" msgstr "Supprimer cette règle de notification" @@ -17872,6 +18136,10 @@ msgstr "Dossier supprimé %s" msgid "Deleted host %s" msgstr "Hôte supprimé %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Supprimer la règle de notification #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Règle de notification supprimée %d de l'utilisateur %s" @@ -18808,6 +19076,10 @@ msgstr "Désactiver la gestion du proxy" msgid "Disable remote configuration" msgstr "Désactiver la configuration à distance" +#, fuzzy +msgid "Disable rule" +msgstr "Désactivé" + msgid "Disable service notifications" msgstr "Désactiver les notifications de service" @@ -19185,9 +19457,6 @@ msgstr "" "Afficher un avertissement si un LUN n'est pas en lecture seule. Sans ce " "paramètre, un avertissement sera affiché si un LUN est en lecture seule." -msgid "Display additional information" -msgstr "Afficher des informations supplémentaires" - msgid "Display additional messages" msgstr "Afficher des messages supplémentaires" @@ -19213,9 +19482,6 @@ msgstr "" msgid "Display dashboard title" msgstr "Afficher le titre du tableau de bord" -msgid "Display graphs among each other" -msgstr "Afficher les graphiques entre eux" - msgid "Display historic data since the last" msgstr "Afficher les données historiques depuis la dernière" @@ -20118,6 +20384,10 @@ msgstr "delta du nombre de documents" msgid "Document count growth per minute" msgstr "Croissance du nombre de documents par minute" +#, fuzzy +msgid "Documentation" +msgstr "URL de la documentation" + msgid "Documentation URL" msgstr "URL de la documentation" @@ -20914,6 +21184,10 @@ msgstr "Modifier" msgid "Edit %s" msgstr "Modifier %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Modifier la règle de notification %d" + #, python-format msgid "Edit %s: %s" msgstr "Modifier %s : %s" @@ -21066,6 +21340,10 @@ msgstr "" "La modification de la mise en page n'est disponible que si l'en-tête est " "activé" +#, fuzzy +msgid "Edit managed robots" +msgstr "Objets gérés" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Modifier la connexion du site %s" @@ -21223,6 +21501,14 @@ msgstr "Modifier cet élément" msgid "Edit this host" msgstr "Modifier cet hôte" +#, fuzzy +msgid "Edit this managed robot" +msgstr "États administratifs" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Modifier cette règle de notification" + msgid "Edit this notification rule" msgstr "Modifier cette règle de notification" @@ -21294,6 +21580,9 @@ msgstr "Modification du profil de l'utilisateur %s" msgid "Edition" msgstr "Edition" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "État efficace" @@ -21481,6 +21770,14 @@ msgstr "Adresse électronique utilisée pour l'identification du compte" msgid "Email addresses to mail PDF reports to" msgstr "Adresses e-mail pour l'envoi de rapports PDF" +#, fuzzy +msgid "Email body/content" +msgstr "Courriel envoyé" + +#, fuzzy +msgid "Email header" +msgstr "Adresse électronique" + msgid "Email sent" msgstr "Courriel envoyé" @@ -22497,6 +22794,10 @@ msgstr "Commentaire sur l'événement" msgid "Event console" msgstr "Console d'événement" +#, fuzzy +msgid "Event console alerts" +msgstr "Alertes de la console d'événements" + msgid "Event console performance" msgstr "Performances de la console d'événements" @@ -23737,10 +24038,6 @@ msgstr "Échec du rendu de la valeur :" msgid "Failed to render value: %r" msgstr "Échec du rendu de la valeur : %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Échec de la récupération du certificat du pair (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -23850,6 +24147,10 @@ msgstr "" "cluster. Cependant, un seul nœud est censé envoyer des données, les " "résultats de tout nœud supplémentaire déclencheront au moins un état WARNING." +#, fuzzy +msgid "Failure" +msgstr "défaillances" + msgid "Failures of the join launcher service" msgstr "Défaillances du service de lancement de jointures" @@ -24148,6 +24449,10 @@ msgstr "Taille du fichier ci-dessous" msgid "File size levels" msgstr "Niveaux de taille des fichiers" +#, fuzzy +msgid "File upload" +msgstr "Octets téléchargés" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -24276,6 +24581,10 @@ msgstr "" "Filtre pour toutes les agrégations qui se basent sur les informations d'état " "de cet hôte. Correspondance exacte (pas d'expression régulière)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Temps d'arrêt de l'hôte/service" + msgid "Filter group (see help)" msgstr "Groupe de filtres (voir aide)" @@ -24955,6 +25264,9 @@ msgstr "Réseaux" msgid "Form factor" msgstr "Facteur de forme" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Format" @@ -25592,6 +25904,11 @@ msgstr "Générer" msgid "Generate REST API specification" msgstr "Spécification SLA" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + #, fuzzy msgid "Generate backup codes" msgstr "Régénérer les codes de sauvegarde" @@ -25657,6 +25974,21 @@ msgstr "Taux générique" msgid "Generic string" msgstr "Chaîne générique" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Version du noyau" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Modifier la connexion" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "Instance Jenkins à interroger." + msgid "Get file from SFTP server" msgstr "Obtenir un fichier du serveur SFTP" @@ -25717,6 +26049,10 @@ msgstr "Règle de notification globale" msgid "Global notification rules" msgstr "Règles de notification globale" +#, fuzzy +msgid "Global services" +msgstr "Tous les services" + msgid "Global services to monitor" msgstr "Des services mondiaux pour surveiller" @@ -25743,6 +26079,10 @@ msgstr "Modèle de globalisation pour les fichiers d'entrée" msgid "Go critical if all licenses are used" msgstr "Devenir critique si toutes les licences sont utilisées" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Tous les hôtes" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25755,6 +26095,12 @@ msgstr "Aller à la page principale" msgid "Go to rules of this InfluxDB connection" msgstr "Aller aux règles de cette connexion InfluxDB" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "" @@ -25917,18 +26263,12 @@ msgstr "Cartes graphiques" msgid "Graphs" msgstr "Graphiques" -msgid "Graphs are shown among each other" -msgstr "Les graphiques sont affichés entre eux" - msgid "Graphs for averaged single-core utilizations" msgstr "Graphiques de l'utilisation moyenne d'un seul cœur" msgid "Graphs for individual cores" msgstr "Graphiques pour les cœurs individuels" -msgid "Graphs per notification (default: 5)" -msgstr "Graphiques par notification (par défaut : 5)" - msgid "Graylog" msgstr "Graylog" @@ -26017,10 +26357,6 @@ msgstr "Base du groupe DN" msgid "Group discovery and activation for up to" msgstr "Découverte et activation de groupes jusqu'à" -#, fuzzy -msgid "Group execution interval" -msgstr "Intervalle d'exécution" - msgid "Group files based on a regular expression pattern." msgstr "" "Regroupement de fichiers sur la base d'un modèle d'expression régulière." @@ -26222,6 +26558,10 @@ msgstr "HPE StoreOnce via l'API REST 4.x" msgid "HR: Used memory via SNMP" msgstr "HR : Mémoire utilisée via SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Paramètres du modèle" + #, fuzzy msgid "HTML email" msgstr "Courriel HTML" @@ -27594,6 +27934,10 @@ msgstr "Cacher les noms des variables de configuration" msgid "Hide notification bulks" msgstr "règle de notification" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Envoyer des notifications distinctes à chaque destinataire" + msgid "Hide response from socket" msgstr "Cacher la réponse du socket" @@ -27661,6 +28005,10 @@ msgstr "Histoire" msgid "History Line Number" msgstr "Numéro de la ligne d'histoire" +#, fuzzy +msgid "History action type" +msgstr "État d'enregistrement" + msgid "History entries of one specific event" msgstr "Entrées de l'histoire d'un événement spécifique" @@ -29344,10 +29692,6 @@ msgstr "Aperçu de l'hôte" msgid "Host parent/child topology" msgstr "Topologie hôte parent/enfant" -#, fuzzy -msgid "Host path" -msgstr "Alerte de l'hôte" - msgid "Host performance data" msgstr "Données sur les performances de l'hôte" @@ -30063,6 +30407,10 @@ msgstr "IP - région - ID de l'instance" msgid "IP Address" msgstr "Adresse IP" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "Adresse IP de l'hôte" + msgid "IP address" msgstr "Adresse IP" @@ -32075,21 +32423,6 @@ msgstr "" "surveillés. Notez que cela concerne tout ce qui fait partie des espaces de " "noms correspondants, comme les pods par exemple." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Avertissement

    Vous n'avez pas configuré une adresse e-mail de repli ni activé la réception d'e-mails de repli " -"pour aucun utilisateur. Si votre surveillance produit une notification qui " -"ne correspond à aucune de vos règles de notification, la notification ne " -"sera pas envoyée. Pour éviter cela, veuillez configurer le paramètre global " -"ou activer l'option de contact de secours pour au moins un de vos " -"utilisateurs." - msgid "Ignore" msgstr "Ignorer" @@ -33075,6 +33408,15 @@ msgstr "" msgid "Indexspace wasted" msgstr "L'espace d'indexation est gaspillé" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Indique si la dernière découverte en vrac a échoué ou non. Il prend la " +"valeur True en cas d'échec et est désactivé si une découverte ultérieure " +"réussit." + msgid "Indices" msgstr "Indices" @@ -33745,6 +34087,10 @@ msgstr "Certificat invalide" msgid "Invalid certificate file: %s" msgstr "Fichier de certificat invalide : %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Paramètre invalide %r : %s" + msgid "Invalid check parameter" msgstr "Paramètre de contrôle non valide" @@ -36585,6 +36931,10 @@ msgstr "Inventaire de Linux Multipath" msgid "Linux and Solaris Multipath Count" msgstr "Compteur de trajets multiples Linux et Solaris" +#, fuzzy +msgid "Linux bonding" +msgstr "Collage de Vswitch" + msgid "Linux bonding interface status" msgstr "Statut de l'interface de liaison Linux" @@ -37183,6 +37533,10 @@ msgstr "" "Enregistrez le processus d'enregistrement de l'agent des demandes entrantes " "par la commande d'enregistrement du contrôleur d'agent Checkmk." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Activer la suppression automatique des hôtes" + msgid "Log: Details" msgstr "Journal : Détails" @@ -37693,6 +38047,10 @@ msgid "Lower levels on the total number of clients pending on a blocking call" msgstr "" "Nombre total de clients en attente d'un appel bloquant niveau inférieur" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Liste des fichiers journaux attendus" + msgid "Lowest: No notification, update badge number" msgstr "Plus bas : Pas de notification, mise à jour du numéro de badge" @@ -38273,10 +38631,25 @@ msgstr "Gérer les utilisateurs du système de surveillance." msgid "Managed Robot" msgstr "Objets gérés" +#, fuzzy +msgid "Managed Robots" +msgstr "Objets gérés" + #, fuzzy msgid "Managed objects" msgstr "Objets gérés" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Objets gérés" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Objets gérés" + msgid "Management board" msgstr "Conseil d'administration" @@ -39855,14 +40228,14 @@ msgstr "Connexions minimales par seconde" msgid "Minimum error count" msgstr "Nombre minimal d'erreurs" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Niveaux minimaux de tension" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Niveaux minimaux de charge en pourcentage" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Niveaux minimaux de tension" + msgid "Minimum levels if using magic factor" msgstr "Niveaux minimums si vous utilisez le facteur magique" @@ -39972,6 +40345,10 @@ msgstr "Durée non planifiée (DaemonSet uniquement)" msgid "Misscheduled replicas" msgstr "Répliques non programmées" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Variable manquante siteid" + #, python-format msgid "Missing config file for agent %s%s" msgstr "Fichier de configuration manquant pour l'agent %s%s" @@ -41469,6 +41846,11 @@ msgstr "Résolution du nom" msgid "Name your %s for easy recognition." msgstr "Nommez votre %s pour qu'il soit facilement reconnaissable." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -41483,13 +41865,13 @@ msgstr "Noms" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" @@ -41906,6 +42288,29 @@ msgstr "Avis suivant" msgid "Next run" msgstr "Prochain cycle" +#, fuzzy +msgid "Next step: General properties" +msgstr "Propriétés générales" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugins de notification" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Bénéficiaire" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "connexions en attente" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Type de commentaire (hôte/service)" + msgid "Nginx Server" msgstr "Serveur Nginx" @@ -41921,6 +42326,10 @@ msgstr "Niveaux d'entrée/sortie souples" msgid "No" msgstr "Non" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Configuration de l'hôte" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "Non (Erreur : %s, Code : %d, Profondeur : %d)" @@ -41928,6 +42337,10 @@ msgstr "Non (Erreur : %s, Code : %d, Profondeur : %d)" msgid "No API integrations, no Checkmk agent" msgstr "Pas d'intégrations API, pas d'agent Checkmk" +#, fuzzy +msgid "No AWS services found." +msgstr "Aucun hôte/service trouvé." + msgid "No CSRF token received" msgstr "Aucun jeton CSRF reçu" @@ -41938,6 +42351,10 @@ msgstr "Pas de conditions" msgid "No Configuration Quick setup for %s available" msgstr "Variable de configuration :" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Modification de la règle de notification %d" + msgid "No IP" msgstr "Pas d'IP" @@ -42016,10 +42433,6 @@ msgstr "Aucune commande n'est possible dans cette vue" msgid "No conditions" msgstr "Pas de conditions" -#, fuzzy -msgid "No configuration yet" -msgstr "Configuration de l'hôte" - msgid "No configured rules are affected" msgstr "Aucune règle configurée n'est affectée" @@ -42076,6 +42489,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "non disponible" + +#, fuzzy +msgid "No elements selected" +msgstr "Non sélectionné" + msgid "No entries" msgstr "Aucune entrée" @@ -42208,6 +42629,10 @@ msgstr "Aucune connexion définie" msgid "No need for syncing sites" msgstr "Pas besoin de synchroniser les sites" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Modification de la règle de notification %d" + msgid "No object type" msgstr "Aucun type d'objet" @@ -42218,6 +42643,10 @@ msgstr "" msgid "No password provided" msgstr "Depuis le magasin de mots de passe" +#, fuzzy +msgid "No password selected" +msgstr "Depuis le magasin de mots de passe" + msgid "No pending changes" msgstr "Aucun changement en cours" @@ -42296,6 +42725,10 @@ msgstr "Pas de recherche" msgid "No search, specify list of arguments" msgstr "Pas de recherche, spécifier la liste des arguments" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthosts" + msgid "No snapshot to restore available." msgstr "" @@ -42763,6 +43196,9 @@ msgstr "Notification" msgid "Notation: %s" msgstr "Annotation : %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42929,6 +43365,18 @@ msgstr "Niveau du journal de notification" msgid "Notification method" msgstr "Méthode de notification" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "La collection de graphiques '%s' n'existe pas" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugins de notification" + +#, fuzzy +msgid "Notification parameter" +msgstr "Phase de notification" + #, fuzzy msgid "Notification period" msgstr "Période de notification" @@ -43375,6 +43823,14 @@ msgstr "Nombre de dossiers à créer dans chaque niveau" msgid "Number of goroutines" msgstr "Nombre de tentatives" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Graphiques par notification (par défaut : 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Graphiques par notification (par défaut : 5)" + msgid "Number of healthy hosts lower levels" msgstr "Nombre d'hôtes sains niveaux inférieurs" @@ -44031,8 +44487,8 @@ msgid "OTLP endpoint" msgstr "Point d'accès" #, fuzzy -msgid "OVS bonding interface status" -msgstr "Interfaces de liaison" +msgid "OVS bonding" +msgstr "Collage de Vswitch" msgid "Object" msgstr "Objet" @@ -46086,6 +46542,10 @@ msgstr "L'actualité en général" msgid "Overall latency" msgstr "Latence globale" +#, fuzzy +msgid "Overall response time" +msgstr "Temps de réponse moyen" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "État général d'une machine virtuelle (par exemple les VM ESX)" @@ -46149,7 +46609,7 @@ msgstr "" "construction" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Unité d'annulation du capteur" msgid "Override unit of sensor" @@ -46746,13 +47206,16 @@ msgstr "Charge des connexions parallèles" msgid "Parallel pings to send" msgstr "Pings parallèles à envoyer" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Exécution du programme" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Paralléliser la création de la configuration du noyau" +#, fuzzy +msgid "Parameter" +msgstr "Paramètres" + msgid "Parameter groups" msgstr "Groupes de paramètres" @@ -46762,6 +47225,10 @@ msgstr "Groupes de paramètres par région" msgid "Parameter name" msgstr "Nom du paramètre" +#, fuzzy +msgid "Parameter properties" +msgstr "Propriétés du paquet" + msgid "Parameter rule set" msgstr "Jeu de règles de paramétrage" @@ -46787,6 +47254,10 @@ msgstr "" "insérer la valeur réelle des paramètres par $HOST$ et $INST$ (entourés de signes de dollar)." +#, fuzzy +msgid "Parameters for" +msgstr "Paramètres pour %s" + #, python-format msgid "Parameters for %s" msgstr "Paramètres pour %s" @@ -46794,6 +47265,10 @@ msgstr "Paramètres pour %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Paramètres pour les phases d'entrée des UPS et PDUs" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Paramètres pour cet hôte" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Paramètres pour les charges de sortie des UPS et PDUs" @@ -47852,6 +48327,10 @@ msgstr "Ping de l'adresse IP normale" msgid "Ping timeout" msgstr "Délai d'attente pour le ping" +#, fuzzy +msgid "Placeholder" +msgstr "VMs de remplacement" + msgid "Placeholder VMs" msgstr "VMs de remplacement" @@ -47903,6 +48382,10 @@ msgstr "" "Les identifiants des plans (combinaisons de noms d'applications, de noms de " "suites et de variantes) doivent être uniques." +#, fuzzy +msgid "Plan settings" +msgstr "Paramètres globaux" + msgid "Plans" msgstr "" @@ -47929,6 +48412,10 @@ msgstr "Veuillez ajouter au moins une colonne à votre vue." msgid "Please add at least one endpoint to monitor" msgstr "" +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Veuillez ajouter au moins un nœud enfant." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47992,6 +48479,10 @@ msgstr "Veuillez choisir une image PNG valide." msgid "Please choose an audit log to view:" msgstr "" +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Veuillez choisir un rapport à programmer" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Veuillez choisir le plugin de vérification" @@ -48651,6 +49142,10 @@ msgstr "Plugins, vérifications locales et MRPE pour les utilisateurs non-roots" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Sortie du plugin" + msgid "Plugins" msgstr "Plugins" @@ -48796,6 +49291,10 @@ msgid "Positive match (Add matching services to the set)" msgstr "" "Correspondance positive (ajout de services correspondants à l'ensemble)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Correspondance positive (ajoute les hôtes correspondants à l'ensemble)" + msgid "Postfix" msgstr "Postfix" @@ -48982,6 +49481,10 @@ msgstr "Texte du préfixe" msgid "Prepare AWS for Checkmk" msgstr "Initialisation de GIT pour Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "Initialisation de GIT pour Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Préfixe d'espace de nom pour les hôtes" @@ -49651,11 +50154,10 @@ msgstr "Exécution du plugin d'agent Python (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" #, fuzzy @@ -49890,14 +50392,15 @@ msgstr "Lire l'exe moyen" msgid "RCC profile configuration" msgstr "Configuration à distance" -#, fuzzy, python-format +#, fuzzy msgid "" -"RCC profile configuration (%s because Robotmk Core MKP has been installed)" +"RCC profile configuration (⚠ not available because Robotmk Core MKP " +"has been installed)" msgstr "Utiliser RCC pour l'exécution isolée (%s dans Robotmk Core)" msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" msgid "RCU" @@ -50504,6 +51007,10 @@ msgstr "Bénéficiaire" msgid "Recipient email address" msgstr "Adresse électronique du destinataire" +#, fuzzy +msgid "Recipients" +msgstr "Bénéficiaire" + #, python-format msgid "Recipients: %s" msgstr "Destinataires : %s" @@ -51017,6 +51524,10 @@ msgstr "Durée de vie restante" msgid "Remaining Open Slots" msgstr "Créneaux horaires ouverts restants" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Jours de validité restants" + msgid "Remaining credits lower levels" msgstr "Crédits restants niveaux inférieurs" @@ -51179,9 +51690,6 @@ msgstr "Supprimer tous les fichiers et sous-répertoires" msgid "Remove downtimes" msgstr "Supprimer les temps d'arrêt" -msgid "Remove downtimes?" -msgstr "Supprimer les temps d'arrêt ?" - msgid "Remove explicit attribute settings" msgstr "Supprimer les paramètres explicites des attributs" @@ -51210,6 +51718,10 @@ msgstr "Supprimer les temps d'arrêt programmés ?" msgid "Remove service" msgstr "Supprimer le service" +#, fuzzy +msgid "Remove smarthost" +msgstr "Déplacez cette entrée" + #, fuzzy msgid "Remove style" msgstr "Supprimer tout" @@ -51799,6 +52311,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Demande des données à une instance de Jenkins." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Demande des données à une instance de Jenkins." @@ -51845,6 +52361,10 @@ msgstr "Port requis" msgid "Required context filters" msgstr "Filtres contextuels requis" +#, fuzzy +msgid "Required field missing" +msgstr "Le site est absent" + msgid "Required match (regular expression)" msgstr "Correspondance requise (expression régulière)" @@ -52171,6 +52691,10 @@ msgstr "Restreindre les services de surveillance par l'une de ces balises AWS" msgid "Restrict number of processed messages per cycle" msgstr "Limiter le nombre de messages traités par cycle" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Limiter la sévérité au pire" + msgid "Restrict runtime of logfile parsing" msgstr "Restreindre le temps d'exécution de l'analyse du fichier journal" @@ -52311,6 +52835,11 @@ msgstr "" "Récupérer des informations sur les processus à l'aide de WMI (Windows " "Management Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Réessayer" @@ -52336,6 +52865,10 @@ msgstr "Recommencer ce test" msgid "Retry time" msgstr "Temps de répétition" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "retourne CRITIQUE si trouvé, OK sinon" + msgid "Return code class 2xx (success)" msgstr "Code de retour classe 2xx (succès)" @@ -52353,7 +52886,12 @@ msgstr "Retour des temps de traitement dans les données de performance" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -52375,10 +52913,19 @@ msgstr "Activer les changements étrangers" msgid "Review and run preview service discovery" msgstr "Sauvegarder & ; lancer la découverte des services" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configuration à distance" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Sauvegarder & ; lancer la découverte des services" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Révolutions par minute" @@ -52431,6 +52978,10 @@ msgstr "Robot Framework : %s" msgid "Robot Framework: Last log" msgstr "Robot Framework : Dernier journal" +#, fuzzy +msgid "Robot package" +msgstr "Retirer l'emballage" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -53545,12 +54096,14 @@ msgstr "Créer une copie de cette agrégation" msgid "Save response" msgstr "Sauvegarder la réponse" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Sauvegardez cet hôte et allez à" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "" @@ -53602,9 +54155,6 @@ msgstr "Planifier les temps d'arrêt sur l'hôte" msgid "Schedule downtime on service" msgstr "Planifier les temps d'arrêt sur l'hôte" -msgid "Schedule downtime?" -msgstr "Planifier un temps d'arrêt ?" - msgid "Schedule downtimes" msgstr "Planifier les temps d'arrêt" @@ -53981,6 +54531,10 @@ msgstr "" msgid "Secret access key" msgstr "Clé secrète" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Clé secrète" + msgid "Secret key" msgstr "Clé secrète" @@ -54155,6 +54709,15 @@ msgstr "Sélectionnez un fichier iCalendar (*.ics) sur votre PC" msgid "Select and configure AWS services you would like to monitor" msgstr "Services Azure à surveiller" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Services Azure à surveiller" + +#, fuzzy +msgid "Select contact group" +msgstr "Groupes de contacts de règles" + #, fuzzy msgid "Select datasource" msgstr "Sélectionner la source de données" @@ -54358,6 +54921,10 @@ msgstr "Sélectionnez le type d'élément de page fixe" msgid "Select type from list" msgstr "Sélectionner des fichiers individuels dans la liste" +#, fuzzy +msgid "Select user" +msgstr "Supprimer un utilisateur" + msgid "Select view" msgstr "Sélectionner la vue" @@ -54396,6 +54963,10 @@ msgstr "Les %s sélectionnés ont été supprimés." msgid "Selected credential has been deleted" msgstr "L'accréditation a été supprimée" +#, fuzzy +msgid "Selected options" +msgstr "Connexions rejetées" + msgid "Selected sections will not be executed by the agent." msgstr "Les sections sélectionnées ne seront pas exécutées par l'agent." @@ -54467,6 +55038,10 @@ msgstr "Envoyer des données HTTP POST" msgid "Send custom notification" msgstr "Envoyer une notification personnalisée" +#, fuzzy +msgid "Send custom notification?" +msgstr "Envoyer une notification personnalisée" + #, fuzzy msgid "Send data" msgstr "Fichier de l'agent" @@ -54513,9 +55088,7 @@ msgid "Send notifications to remote Event Console" msgstr "Envoyer des notifications à la console d'événements distante" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "Ordre de tri des notifications pour les notifications groupées" msgid "" @@ -54523,10 +55096,6 @@ msgid "" "notifications (forced)" msgstr "" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Envoyer des notifications distinctes à chaque destinataire" - msgid "Send service metrics to Graphite" msgstr "Envoi des mesures de service à Graphite" @@ -54568,6 +55137,10 @@ msgstr "Envoyer par courriel" msgid "Sending Power" msgstr "Puissance d'envoi" +#, fuzzy +msgid "Sending conditions" +msgstr "Définir les conditions" + msgid "Sending reply" msgstr "Envoi de la réponse" @@ -54621,7 +55194,11 @@ msgid "September" msgstr "Septembre" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Intervalle d'exécution" + +#, fuzzy +msgid "Sequence of plans" msgstr "Exécution du programme" msgid "Serial" @@ -54863,6 +55440,10 @@ msgstr "Découverte de services : Description du service" msgid "Service discovery: State" msgstr "Découverte des services : État" +#, fuzzy +msgid "Service events" +msgstr "Niveau de service" + msgid "Service goes into critical state" msgstr "Le service passe en état critique" @@ -55199,6 +55780,10 @@ msgstr "Services du site" msgid "Services per cluster" msgstr "Services par cluster" +#, fuzzy +msgid "Services per region" +msgstr "Services par région à surveiller" + msgid "Services per region to monitor" msgstr "Services par région à surveiller" @@ -55740,7 +56325,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -56116,6 +56701,10 @@ msgstr "Afficher les cases à cocher" msgid "Show column headings" msgstr "Afficher les en-têtes de colonne" +#, fuzzy +msgid "Show contact groups" +msgstr "Accueillir des groupes de contact" + msgid "Show context" msgstr "Montrer le contexte" @@ -56183,9 +56772,17 @@ msgstr "Afficher les conseils dans le menu \"Utilisateur" msgid "Show historic values" msgstr "Montrer les valeurs historiques" +#, fuzzy +msgid "Show host labels" +msgstr "Afficher dans les tableaux des hôtes" + msgid "Show host status" msgstr "Afficher l'état de l'hôte" +#, fuzzy +msgid "Show host tags" +msgstr "Afficher l'état de l'hôte" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Afficher l'icône permettant d'accéder à l'éditeur de paramètres de " @@ -56265,6 +56862,10 @@ msgstr "Afficher plus / Afficher moins" msgid "Show notification bulks" msgstr "règle de notification" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Ordre de tri des notifications pour les notifications groupées" + msgid "Show number of groups" msgstr "Afficher le nombre de groupes" @@ -56329,6 +56930,10 @@ msgstr "Afficher les règles utilisant ce %s" msgid "Show separate result for each SLA period" msgstr "Afficher un résultat distinct pour chaque période de SLA" +#, fuzzy +msgid "Show service labels" +msgstr "Étiquettes de service" + #, fuzzy msgid "Show service name" msgstr "Le nom du service" @@ -56720,6 +57325,11 @@ msgstr "" "le nœud qui a été crucial pour le résultat global (le nœud préféré en cas de " "doute). Vous pouvez contourner cet automatisme en spécifiant un nœud ici." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -57656,6 +58266,10 @@ msgstr "Objets spécifiques" msgid "Specific sites" msgstr "Sites spécifiques" +#, fuzzy +msgid "Specific users" +msgstr "Sites spécifiques" + msgid "Specific version" msgstr "Version spécifique" @@ -57679,13 +58293,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Spécifie le style de ligne par défaut" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Spécifie si l'authentification par mot de passe est autorisée" @@ -57858,13 +58465,6 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -58314,6 +58914,11 @@ msgstr "" "Indiquez ce que nous devons faire si le graphique sélectionné est manquant " "ou ne peut être récupéré." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Spécifier les types de port qui ne doivent pas être découverts" @@ -58533,6 +59138,10 @@ msgstr "Début de l'année prochaine" msgid "Start or end of a scheduled downtime" msgstr "Début ou fin d'un temps d'arrêt programmé" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Début du temps d'arrêt" + msgid "Start or end of flapping state" msgstr "Début ou fin de l'état de battement" @@ -58756,6 +59365,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "État pour la non-concordance de la chaîne attendue" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Avertissement sur une interface active inattendue" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Découverte de services en attente" + msgid "State if 'maintenance' services are found" msgstr "Indiquer si des services de \"maintenance\" ont été trouvés" @@ -59790,10 +60407,12 @@ msgstr "Nom de la section" msgid "Subject for bulk notifications" msgstr "Objet des notifications groupées" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Objet des notifications des hôtes" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Objet des notifications de service" msgid "Submit" @@ -60195,6 +60814,10 @@ msgstr "Synchrone" msgid "Syncing" msgstr "Synchroniser" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "Certificat de routeur SAP" + msgid "Synology Updates" msgstr "Mises à jour de Synology" @@ -60487,6 +61110,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLS L'authentification sans TLS n'est pas possible" +#, fuzzy +msgid "TLS certificate verification" +msgstr "Vérification du certificat SSL" + #, fuzzy msgid "TLS processed bytes" msgstr "Octets traités par TLS" @@ -60712,6 +61339,16 @@ msgstr "" "Les balises peuvent être utilisées pour classer les hôtes et les services de " "manière flexible." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "Aucune source de données définie." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Tags de l'alerte." @@ -60954,6 +61591,10 @@ msgstr "" msgid "Test authentication" msgstr "Authentification par jeton" +#, fuzzy +msgid "Test configuration" +msgstr "Configuration de l'hôte" + #, fuzzy msgid "Test connection" msgstr "Cette connexion" @@ -60988,6 +61629,9 @@ msgstr "dernière notification" msgid "Test runtime" msgstr "Durée d'exécution du processus" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + #, fuzzy msgid "Test verification" msgstr "Vérification de la licence" @@ -62256,6 +62900,10 @@ msgstr "" "Le site central (%s) et le site distant (%s) ne sont pas compatibles. " "Raison : %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "N'a jamais été activé" + #, python-format msgid "The character %s is not allowed here." msgstr "Le caractère %s n'est pas autorisé ici." @@ -62547,6 +63195,11 @@ msgstr "" "La connexion crée des hôtes dans ce dossier particulier. Une fois créé, vous " "pouvez choisir de déplacer l'hôte dans un autre dossier." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "La connexion à ce site a été désactivée." @@ -62813,25 +63466,6 @@ msgstr "L'élément ne peut être trouvé sur le tableau de bord." msgid "The element does not exist." msgstr "L'élément n'existe pas." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"L'adresse email et le nom visible utilisés dans l'en-tête From des messages " -"de notifications. Si aucune adresse électronique n'est spécifiée, l'adresse " -"par défaut OMD_SITE@FQDN est utilisée. Si la variable " -"d'environnement OMD_SITE n'est pas définie, elle prend par défaut " -"la valeur checkmk." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"L'adresse électronique et le nom visible utilisés dans l'en-tête \"Reply-To" -"\" des messages de notification." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -63195,12 +63829,6 @@ msgstr "La spécification du graphe est manquante" msgid "The graph template id '%s' is disabled" msgstr "L'id du modèle de graphique '%s' est désactivé" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -63436,13 +64064,6 @@ msgstr "" "Le nom de l'instance, le nom de la base de données et le nom du tablespace " "combinés comme ceci db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -63828,6 +64449,12 @@ msgstr "" "ne passe en alerte/critique. Cette alarme ne s'applique qu'à l'hôte cible, " "pas aux sauts entre les deux." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "La longueur maximale de la valeur est de 256 caractères." @@ -65488,6 +66115,20 @@ msgstr "" "Les seuils pour wait_duration_ms. Remplacera l'état par défaut défini ci-" "dessus." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "" "L'intervalle de temps pendant lequel les données statistiques sont " @@ -65645,6 +66286,14 @@ msgstr "" "Le nom d'utilisateur renvoyé par le connecteur %s n'est pas de type string " "(%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"Le nom d'utilisateur qui doit être utilisé pour accéder à l'API de Graylog. " +"Il doit avoir des droits de lecture au moins." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -65954,8 +66603,8 @@ msgstr "Il n'y a pas d'instantané de configuration à restaurer." msgid "There is no backup job configured" msgstr "Il n'y a pas de tâche de sauvegarde configurée" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "Il n'y a pas de modèle de graphique avec l'id '%s'" msgid "There is no manpage for this check." @@ -66127,7 +66776,7 @@ msgstr "Ces nœuds se trouvent uniquement dans l'agrégation gelée" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" msgid "" @@ -66450,6 +67099,9 @@ msgstr "" "réinitialiser le contrôleur d'agent sur l'hôte surveillé (référez-vous à " "`cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + #, fuzzy msgid "" "This active check sends out special emails to a defined mail address using " @@ -67208,7 +67860,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -68063,8 +68715,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Cette autorisation permet aux utilisateurs de migrer d'autres utilisateurs " "vers une autre connexion" @@ -68682,13 +69333,6 @@ msgstr "" "entraînera des changements fréquents dans l'inventaire HW/SW, ce qui peut " "rapidement remplir le système de fichiers temporaires." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Cette règle permet de surveiller VMware ESX via l'API vSphere. Vous pouvez " -"configurer vos paramètres de connexion ici." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -69379,15 +70023,6 @@ msgstr "" "Ce jeu de règles sélectionne l'agent spécial NetApp au lieu de l'agent " "Checkmk normal et permet la surveillance via le NetApp Ontap REST API." -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Cet ensemble de règles sélectionne l'agent spécial pour les appliances HPE " -"StoreOnce au lieu de l'agent Checkmk normal et permet la surveillance via " -"l'API REST v4.x ou supérieure. " - #, fuzzy msgid "" "This rule sets limits to the current number of connections through a Check " @@ -74245,9 +74880,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "A essayé d'enregistrer des règles incompatibles : %r" +#, fuzzy +msgid "Triggering events" +msgstr "Événements d'archives" + msgid "Trivial change" msgstr "Changement trivial" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -75452,6 +76094,14 @@ msgstr "Télécharger la réponse" msgid "Upload verification response file" msgstr "Télécharger la réponse de vérification" +#, fuzzy +msgid "Uploaded" +msgstr "Télécharger" + +#, fuzzy +msgid "Uploaded by" +msgstr "Clé de téléchargement" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "Téléchargement du logo GUI personnalisé : %s" @@ -76879,6 +77529,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">limite d'événement " "de la règle globale" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Utilisez cette option pour demander un port qui est différent du port " +"standard 443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -76920,6 +77576,15 @@ msgstr "" "interrogé (fallback). La vérification ne produira que les données du premier " "hôte qui envoie une réponse." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Utilisez cette option pour définir quelle instance doit être vérifiée par " +"l'agent spécial. Veuillez ajouter le nom d'hôte ici, par exemple mon_graylog." +"com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -77325,7 +77990,8 @@ msgstr "Messages des utilisateurs" msgid "User name" msgstr "Nom de l'utilisateur" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Nom d'utilisateur sur le système de stockage. Des autorisations de lecture " "seule sont suffisantes." @@ -77429,6 +78095,10 @@ msgstr "" "Les utilisateurs répertoriés ici sont toujours autorisés à modifier les " "choses." +#, fuzzy +msgid "Users of contact groups" +msgstr "Membres des groupes de contact" + msgid "Users using a cifs share" msgstr "Utilisateurs utilisant un partage cifs" @@ -78481,6 +79151,10 @@ msgstr "Vérifier les certificats" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Ignorer les erreurs de certificat (non sécurisé)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Ignorer les erreurs de certificat (non sécurisé)" + msgid "Verify certificates" msgstr "Vérifier les certificats" @@ -78545,6 +79219,9 @@ msgstr "Version de l'appliance PKI" msgid "Version of Server" msgstr "Version du serveur" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Version : %s" @@ -79010,6 +79687,10 @@ msgstr "Connexions en attente" msgid "Waiting containers" msgstr "Conteneurs d'attente" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Découverte des ports Netapp" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -79399,6 +80080,9 @@ msgstr "" msgid "What is the purpose?" msgstr "" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -80483,6 +81167,10 @@ msgstr "" msgid "Who" msgstr "Qui" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "permettre aux utilisateurs de désactiver cette notification" + msgid "WiFi connection types" msgstr "Types de connexion WiFi" @@ -80645,7 +81333,7 @@ msgstr "" msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -80970,6 +81658,13 @@ msgstr "" "sont configurés. Cela peut prêter à confusion.Cette règle ne " "devrait être configurée que dans les premières étapes." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -81924,6 +82619,14 @@ msgstr "" "Vous ne pouvez pas supprimer ce %s car il est en cours " "d'utilisation." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"Vous ne pouvez pas supprimer cette cible car elle est utilisée par ces " +"travaux de sauvegarde : %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -82772,6 +83475,10 @@ msgstr "" "Vous n'avez pas encore créé de clés de " "signature d'agent. C'est nécessaire." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Paramètres pour cet hôte" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -84696,9 +85403,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "moniteur" - msgid "month" msgstr "mois" @@ -85622,6 +86326,9 @@ msgstr "{actual} est trop élevée. La valeur maximale autorisée est {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} est trop faible. La valeur minimale autorisée est de {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -85630,6 +86337,136 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Tous droits réservés." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Utiliser RCC pour l'exécution isolée (%s dans Robotmk Core)" + +#~ msgid "API key from password store" +#~ msgstr "Clé API du magasin de mots de passe" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Alerte de l'hôte" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Échec de la récupération du certificat du pair (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Avertissement

    Vous n'avez pas configuré une adresse e-mail de repli ni activé la réception d'e-mails de repli " +#~ "pour aucun utilisateur. Si votre surveillance produit une notification " +#~ "qui ne correspond à aucune de vos règles de notification, la notification " +#~ "ne sera pas envoyée. Pour éviter cela, veuillez configurer le paramètre " +#~ "global ou activer l'option de contact de secours pour au moins un de vos " +#~ "utilisateurs." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Notifications en vrac avec graphiques (par défaut : 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Par défaut, tous les graphiques multiples dans les e-mails sont affichés " +#~ "de manière flottante à proximité les uns des autres. Vous pouvez activer " +#~ "cette option pour afficher les graphiques les uns à côté des autres." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configurer ceci pour que le plugin de notification se connecte " +#~ "directement au serveur smtp. Cela a l'avantage de fournir de meilleurs " +#~ "messages d'erreur en cas d'erreur mais cela nécessite plus de " +#~ "configuration et est strictement synchrone, nous conseillons donc de " +#~ "l'utiliser uniquement sur les installations d'entreprise utilisant le " +#~ "spooler de notification." + +#~ msgid "Display additional information" +#~ msgstr "Afficher des informations supplémentaires" + +#~ msgid "Display graphs among each other" +#~ msgstr "Afficher les graphiques entre eux" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Les graphiques sont affichés entre eux" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "L'adresse email et le nom visible utilisés dans l'en-tête From des " +#~ "messages de notifications. Si aucune adresse électronique n'est " +#~ "spécifiée, l'adresse par défaut OMD_SITE@FQDN est utilisée. Si " +#~ "la variable d'environnement OMD_SITE n'est pas définie, elle " +#~ "prend par défaut la valeur checkmk." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "L'adresse électronique et le nom visible utilisés dans l'en-tête \"Reply-" +#~ "To\" des messages de notification." + +#~ msgid "Activate" +#~ msgstr "Activez" + +#~ msgid "Deactivate" +#~ msgstr "Désactiver" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Cette règle permet de surveiller VMware ESX via l'API vSphere. Vous " +#~ "pouvez configurer vos paramètres de connexion ici." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Cet ensemble de règles sélectionne l'agent spécial pour les appliances " +#~ "HPE StoreOnce au lieu de l'agent Checkmk normal et permet la surveillance " +#~ "via l'API REST v4.x ou supérieure. " + +#~ msgid "monitor" +#~ msgstr "moniteur" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Nom du compte de stockage" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Exécution du programme" + +#~ msgid "(not supported)" +#~ msgstr "(non pris en charge)" + +#~ msgid "Remove downtimes?" +#~ msgstr "Supprimer les temps d'arrêt ?" + +#~ msgid "Schedule downtime?" +#~ msgstr "Planifier un temps d'arrêt ?" + +#, fuzzy +#~ msgid "OVS bonding interface status" +#~ msgstr "Interfaces de liaison" + #~ msgid "Common Name" #~ msgstr "Nom commun" @@ -85758,10 +86595,6 @@ msgstr "© %s Checkmk GmbH. Tous droits réservés." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Quota utilisé : Niveaux supérieurs absolus ou relatifs" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "N'a jamais été activé" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Tablespaces" @@ -86060,10 +86893,6 @@ msgstr "© %s Checkmk GmbH. Tous droits réservés." #~ msgid "%s operations" #~ msgstr "%s opérations" -#, fuzzy, python-format -#~ msgid "%s requests" -#~ msgstr "%s Demandes" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -86396,9 +87225,6 @@ msgstr "© %s Checkmk GmbH. Tous droits réservés." #~ msgid "InfluxDB Queue Usage" #~ msgstr "Utilisation de la file d'attente InfluxDB" -#~ msgid "Kernel Version" -#~ msgstr "Version du noyau" - #~ msgid "Levels Helper usage Check" #~ msgstr "Vérification de l'utilisation de l'aide aux niveaux" diff --git a/locale/it/LC_MESSAGES/multisite.po b/locale/it/LC_MESSAGES/multisite.po index 3d6fe201f12..dd67e345f00 100644 --- a/locale/it/LC_MESSAGES/multisite.po +++ b/locale/it/LC_MESSAGES/multisite.po @@ -402,6 +402,10 @@ msgstr "%d giorni" msgid "%d days ago" msgstr "%d giorni fa" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Proprietà generali" + #, python-format msgid "%d errors occured:" msgstr "Si sono verificati %d errori:" @@ -564,6 +568,10 @@ msgstr "%s da host" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -683,6 +691,10 @@ msgstr "%s tasso" msgid "%s resulting notifications" msgstr "%s notifiche risultanti" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s Richieste" + #, python-format msgid "%s running for %s" msgstr "%s in esecuzione per %s" @@ -794,9 +806,17 @@ msgid "" "configuration tracking in setup." msgstr "" +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Voci rimosse" + msgid "(0 is current period)" msgstr "(0 è il periodo corrente)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(nessuna voce)" + msgid "(Edit presets)" msgstr "(Modifica delle preimpostazioni)" @@ -872,9 +892,6 @@ msgstr "(nessun titolo)" msgid "(none)" msgstr "(nessuno)" -msgid "(not supported)" -msgstr "(non supportato)" - msgid "(nothing selected)" msgstr "(niente di selezionato)" @@ -982,6 +999,10 @@ msgstr "1 cambio" msgid "1 row" msgstr "1 fila" +#, fuzzy +msgid "1 rule" +msgstr "regola" + msgid "1 year" msgstr "1 anno" @@ -1179,6 +1200,30 @@ msgstr "95° percentile" msgid "99th percentile" msgstr "99° percentile" +#, fuzzy +msgid "< Remove" +msgstr "Rimuovi" + +#, fuzzy +msgid "<< Remove all" +msgstr "Rimuovere tutti" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Le traduzioni piggybackvengono eseguite prima che " +"il connettore piggyback crei gli host. Utilizzarlo, ad esempio, in una " +"configurazione con più nodi Docker per anteporre ai contenitori il nome del " +"nodo Docker corrispondente. Altrimenti, possono verificarsi collisioni di " +"nomi se i contenitori con lo stesso nome esistono su più di un nodo Docker." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Nota3: Per distribuire questo plugin su Solaris, è " @@ -1342,6 +1387,12 @@ msgstr "Avviso: Ci sono %d manufatti incompatibili non riconosciuti:" msgid "You do not have any roles." msgstr "Non hai alcun ruolo." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1922,7 +1973,7 @@ msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" #, python-format @@ -2104,6 +2155,14 @@ msgstr "Un titolo per i grafici" msgid "A heading for the view" msgstr "Una voce per la vista" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Un host con il nome %s esiste già nella cartella
    %s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Aggiungi %s" + msgid "Add Aggregation" msgstr "Aggiungi aggregazione" @@ -3602,10 +3678,6 @@ msgstr "Aggiungi eccezione" msgid "Add Group" msgstr "Aggiungi gruppo" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"Aggiungere una sezione HTML sopra la tabella (ad es. titolo, descrizione...)" - msgid "Add LDAP connection" msgstr "Aggiungere la connessione LDAP" @@ -3651,6 +3723,9 @@ msgstr "Aggiungere l'aggregazione" msgid "Add alert handler rule" msgstr "Aggiungere la regola del gestore degli avvisi" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Aggiungi tutti i servizi rilevati ma non ancora monitorati al monitoraggio." @@ -3751,6 +3826,10 @@ msgstr "Aggiungere elemento: %s" msgid "Add elements to your sidebar" msgstr "Aggiungi elementi alla tua barra laterale" +#, fuzzy +msgid "Add event" +msgstr "Aggiungere elemento" + msgid "Add exception" msgstr "Aggiungere un'eccezione" @@ -3937,6 +4016,10 @@ msgstr "Aggiungere una nuova condizione al nodo" msgid "Add new pattern" msgstr "Aggiungi un nuovo modello" +#, fuzzy +msgid "Add new plan" +msgstr "Aggiungi un nuovo modello" + msgid "Add new project" msgstr "Aggiungere un nuovo progetto" @@ -3952,10 +4035,18 @@ msgstr "Aggiungi una nuova riga" msgid "Add new scalar" msgstr "Aggiungere un nuovo scalare" +#, fuzzy +msgid "Add new sequence" +msgstr "Aggiungere un nuovo servizio" + #, fuzzy msgid "Add new service" msgstr "Aggiungere un nuovo servizio" +#, fuzzy +msgid "Add new smarthost" +msgstr "Aggiungere una nuova macro" + msgid "Add new status" msgstr "Aggiungere un nuovo stato" @@ -3997,6 +4088,10 @@ msgstr "Aggiungere o modificare gli eseguibili" msgid "Add page element" msgstr "Aggiungere l'elemento della pagina" +#, fuzzy +msgid "Add parameter" +msgstr "Parametri del modello" + msgid "Add pattern" msgstr "Aggiungere il modello" @@ -4022,6 +4117,10 @@ msgstr "Aggiungere pre o postfix a TNSALIAS %s" msgid "Add random hosts" msgstr "Aggiungere host casuali" +#, fuzzy +msgid "Add recipient" +msgstr "Destinatario" + msgid "Add remote instance" msgstr "Aggiungere un'istanza remota" @@ -4269,6 +4368,10 @@ msgid "Additional agent labels to send during registration" msgstr "" "Etichette aggiuntive per gli agenti da inviare durante la registrazione" +#, fuzzy +msgid "Additional details" +msgstr "Opzioni aggiuntive" + msgid "Additional header lines" msgstr "Linee di intestazione aggiuntive" @@ -4397,7 +4500,7 @@ msgid "Admin states to discover" msgstr "Stati Admin da scoprire" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "Stati amministrativi" msgid "Administrative port states to discover" @@ -5082,6 +5185,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "Configurazione del gestore degli avvisi" +#, fuzzy +msgid "Alert handler execution" +msgstr "Esecuzioni dei gestori di allarmi" + msgid "Alert handler execution, failed" msgstr "Esecuzione del gestore di allarme, fallita" @@ -5195,6 +5302,15 @@ msgstr "Statistiche di allarme: Numero di allarmi sconosciuti" msgid "Alert statistics: Number of warnings" msgstr "Statistiche degli avvisi: Numero di avvisi" +msgid "Alert when a major version release is available" +msgstr "" + +msgid "Alert when a minor version release is available" +msgstr "" + +msgid "Alert when a patch version release is available" +msgstr "" + msgid "Alerted" msgstr "Allertato" @@ -5301,6 +5417,10 @@ msgstr "Tutte le collezioni" msgid "All components" msgstr "Tutti i componenti" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Tutti i contatti dell'oggetto notificato" + msgid "All contacts of the notified object" msgstr "Tutti i contatti dell'oggetto notificato" @@ -5730,6 +5850,10 @@ msgstr "Permettere di vedere l'icona %s nelle viste dell'host e del servizio" msgid "Allow unencrypted legacy communication" msgstr "Consentire la comunicazione legacy non crittografata" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "permettere agli utenti di disattivare questa notifica" + msgid "Allowed Ciphers" msgstr "Cifre consentite" @@ -6333,6 +6457,10 @@ msgstr "Un'altra sincronizzazione utente è già in esecuzione: %s" msgid "AntiVirus last update age" msgstr "Età dell'ultimo aggiornamento dell'AntiVirus" +#, fuzzy +msgid "Any" +msgstr "qualsiasi" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6507,9 +6635,21 @@ msgstr "Panoramica delle applicazioni" msgid "Applications, Processes & Services" msgstr "Applicazioni, processi e servizi" +#, fuzzy +msgid "Applied to" +msgstr "Applicare a" + msgid "Apply" msgstr "Applica" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Regola del gestore degli avvisi" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Elimina questa regola di notifica" + #, fuzzy msgid "Apply Latency" msgstr "Latenza" @@ -6532,6 +6672,11 @@ msgstr "Applicare le condizioni" msgid "Apply filters" msgstr "Applicare i filtri" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Applicare il tempo di finitura" @@ -6663,6 +6808,10 @@ msgstr "Archiviare il registro di audit corrente" msgid "Archive event" msgstr "Archivio eventi" +#, fuzzy +msgid "Archive event?" +msgstr "Archivio eventi" + msgid "Archive events" msgstr "Archivio eventi" @@ -6792,6 +6941,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Assegnare il risultato all'host piggyback" @@ -7221,10 +7375,10 @@ msgstr "Autoestensibile" msgid "Automated environment setup (via RCC)" msgstr "" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Usa SSL per la connessione." msgid "Automatic" @@ -8583,6 +8737,10 @@ msgstr "Agenti al forno" msgid "Baked host specific agent" msgstr "Agente specifico per l'ospite al forno" +#, fuzzy +msgid "Bakery rules" +msgstr "Regole di scoperta" + msgid "Baking Agents..." msgstr "Agenti di cottura..." @@ -9113,8 +9271,9 @@ msgstr "Importazione di massa di host" msgid "Bulk move" msgstr "Spostamento di massa" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Notifiche di massa con grafici (predefinito: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Aprire le notifiche di massa" msgid "Bulk removal of explicit attributes" msgstr "Rimozione in blocco di attributi espliciti" @@ -9468,14 +9627,6 @@ msgstr "" "personalizzare le credenziali da usare quando si contattano gli host via " "SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Per impostazione predefinita, tutti i grafici multipli nelle e-mail vengono " -"visualizzati vicini e fluttuanti. Puoi abilitare questa opzione per mostrare " -"i grafici tra di loro." - msgid "By default all of the sections will be executed." msgstr "Per default tutte le sezioni saranno eseguite." @@ -9659,14 +9810,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" msgid "" @@ -9675,7 +9826,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" msgid "" @@ -9942,8 +10093,8 @@ msgstr "Bypassare il proxy per alcuni host" msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11186,6 +11337,10 @@ msgstr "Connessione LDAP modificata %s" msgid "Changed alert handler rule %d" msgstr "Modificata regola di gestione degli avvisi %d" +#, fuzzy +msgid "Changed by" +msgstr "Cambiato" + msgid "Changed entries" msgstr "Voci modificate" @@ -11201,6 +11356,14 @@ msgstr[1] "Modifica delle etichette degli host: " msgid "Changed host selection has been saved." msgstr "La selezione dell'host modificata è stata salvata." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Regola di notifica modificata %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Regola di notifica modificata %d" + #, python-format msgid "Changed notification rule %d" msgstr "Regola di notifica modificata %d" @@ -11220,6 +11383,10 @@ msgstr "Posizione modificata di %s %d" msgid "Changed position of connection %s to %d" msgstr "Modificata la posizione della connessione %s in %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "Modificata la posizione della regola di notifica %d dell'utente %s" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "Modificata la posizione della regola di notifica %d dell'utente %s" @@ -11275,6 +11442,10 @@ msgstr "Cambiata la variabile di configurazione specifica del sito %s in %s." msgid "Changes" msgstr "Cambiamenti" +#, fuzzy +msgid "Changes activated" +msgstr "Non è mai stato attivato" + msgid "Changes since last dump" msgstr "Cambiamenti dall'ultimo dump" @@ -12569,6 +12740,11 @@ msgstr "" "Cliccare su \"Registra %s\" per abilitare l'autenticazione a due fattori " "tramite %s." +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Fare clic per attivare questa impostazione" @@ -12727,6 +12903,10 @@ msgstr "Clonare questa connessione per crearne una nuova" msgid "Clone this element" msgstr "Clona questo elemento" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Oggetti gestiti" + msgid "Clone this metric" msgstr "Clona questa metrica" @@ -13276,6 +13456,10 @@ msgstr "Completare il ripristino" msgid "Complete tree" msgstr "Albero completo" +#, fuzzy +msgid "Complete variable list" +msgstr "Elenco completo delle variabili (per i test)" + msgid "Complete variable list (for testing)" msgstr "Elenco completo delle variabili (per i test)" @@ -13417,6 +13601,10 @@ msgstr "File di configurazione ('*.mk' o '*.conf') da etc/checkmk: %s" msgid "Configuration generation" msgstr "Generazione della configurazione" +#, fuzzy +msgid "Configuration name" +msgstr "Configurazione" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Configurazione del componente Business Intelligence di Checkmk" @@ -13488,6 +13676,10 @@ msgstr "Configurare" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Monitoraggio dei servizi Amazon Web (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Monitoraggio dei servizi Amazon Web (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "Configurare le impostazioni relative a SNMP usando i set di regole" @@ -13553,6 +13745,10 @@ msgstr "Crash report fallback mail address" msgid "Configure grouping of interfaces" msgstr "Configurare il raggruppamento delle interfacce" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configurazione" + #, fuzzy msgid "Configure host and regions" msgstr "Configurazione" @@ -13777,6 +13973,10 @@ msgstr "" "Configura il nome della variabile dell'intestazione della richiesta HTTP da " "leggere dalle richieste HTTP in arrivo" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configurare il rilevamento di singole interfacce" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13809,20 +14009,6 @@ msgstr "" "chiave dell'utente o del gruppo. La chiave può essere ottenuta dal sito web " "di Pushover." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configurare questo per far sì che il plugin di notifica si connetta " -"direttamente al server smtp. Questo ha il vantaggio di fornire migliori " -"messaggi di errore in caso di errore, ma richiede più configurazione ed è " -"strettamente sincrono, quindi si consiglia l'uso solo su installazioni " -"aziendali che utilizzano lo spooler di notifica." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14222,6 +14408,10 @@ msgstr "Contatta" msgid "Contact Name" msgstr "Nome del contatto" +#, fuzzy +msgid "Contact group" +msgstr "Gruppi di contatto" + msgid "Contact group (effective)" msgstr "Gruppo di contatto (effettivo)" @@ -14379,6 +14569,10 @@ msgstr "Informazioni sul contesto" msgid "Context information about this connection" msgstr "Informazioni di contesto su questa connessione" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Informazioni di contesto su questa regola" + msgid "Context information about this rule" msgstr "Informazioni di contesto su questa regola" @@ -14632,6 +14826,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase: Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, fuzzy, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -14912,6 +15111,10 @@ msgstr "Creare una copia di questa connessione" msgid "Create a copy of this group" msgstr "Creare una copia di questo gruppo" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Crea una copia di questa regola di notifica" + msgid "Create a copy of this notification rule" msgstr "Crea una copia di questa regola di notifica" @@ -14996,6 +15199,11 @@ msgstr "Creare un servizio aggiuntivo per le richieste di statistiche IO" msgid "Create additional service for system wait" msgstr "Creare un servizio aggiuntivo per l'attesa del sistema" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Creare un'annotazione per questo periodo" @@ -15106,6 +15314,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Creare un orario regolare per questo rapporto" +#, fuzzy +msgid "Create robot" +msgstr "Creare host in" + msgid "Create separate notification bulks based on" msgstr "Creare gruppi di notifica separati in base a" @@ -15207,6 +15419,10 @@ msgstr "Creato nuovo host %s." msgid "Created new host tag group '%s'" msgstr "Creato nuovo gruppo di tag host '%s'" +#, fuzzy +msgid "Created new notification parameter" +msgstr "Creata nuova regola di notifica" + msgid "Created new notification rule" msgstr "Creata nuova regola di notifica" @@ -15650,6 +15866,11 @@ msgstr "Design GUI personalizzato di %s" msgid "Custom Graph" msgstr "Grafico personalizzato" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "" +"Aggiungere una sezione HTML sopra la tabella (ad es. titolo, descrizione...)" + msgid "Custom Icons" msgstr "Icone personalizzate" @@ -15755,6 +15976,14 @@ msgstr "Localizzazioni personalizzate" msgid "Custom logos" msgstr "Loghi personalizzati" +#, fuzzy +msgid "Custom macro" +msgstr "Macro di clienti" + +#, fuzzy +msgid "Custom macros" +msgstr "Macro di clienti" + #, python-format msgid "Custom notification table for user %s" msgstr "Tabella di notifica personalizzata per l'utente %s" @@ -15768,9 +15997,15 @@ msgstr "Stato della sonda personalizzata" msgid "Custom profile" msgstr "Profilo personalizzato" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Query di ricerca personalizzata" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Attributi di servizio personalizzati" @@ -16603,9 +16838,6 @@ msgstr "Tariffa giornaliera" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Disattivare" - msgid "Deactivated" msgstr "Disattivato" @@ -16889,6 +17121,9 @@ msgstr "Profilo utente predefinito" msgid "Default value" msgstr "Valore predefinito" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "File differiti Età" @@ -16945,6 +17180,9 @@ msgstr "" "monitoraggio, cioè al risultato del controllo. Questo sovrascrive la " "mappatura predefinita utilizzata dal controllo." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Definire l'assegnazione dell'host" @@ -16985,6 +17223,9 @@ msgstr "Definire livelli inferiori per il numero di contenitori in attesa" msgid "Define name of NetBIOS server" msgstr "Definire il nome del server NetBIOS" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17227,6 +17468,10 @@ msgstr "Creare la chiave di backup #%d" msgid "Delete comments" msgstr "Cancellare i commenti" +#, fuzzy +msgid "Delete comments?" +msgstr "Cancellare i commenti" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Configurazione predefinita" @@ -17294,6 +17539,14 @@ msgstr "Cancellare il lavoro #%d" msgid "Delete last alert handler rule" msgstr "Cancellare l'ultima regola di gestione degli avvisi" +#, fuzzy +msgid "Delete managed robot" +msgstr "Oggetti gestiti" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Elimina regola di notifica #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Elimina regola di notifica #%d" @@ -17446,9 +17699,17 @@ msgstr "Cancellare questo tasto" msgid "Delete this logo" msgstr "Cancellare questo logo" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Elimina questo gruppo di tag" + msgid "Delete this metric" msgstr "Cancella questa metrica" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Elimina questa regola di notifica" + msgid "Delete this notification rule" msgstr "Elimina questa regola di notifica" @@ -17546,6 +17807,10 @@ msgstr "Cartella eliminata %s" msgid "Deleted host %s" msgstr "Host cancellato %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Elimina regola di notifica #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Regola di notifica cancellata %d dell'utente %s" @@ -18477,6 +18742,10 @@ msgstr "Disattivare la gestione dei proxy" msgid "Disable remote configuration" msgstr "Disattivare la configurazione remota" +#, fuzzy +msgid "Disable rule" +msgstr "Disabile tutti" + msgid "Disable service notifications" msgstr "Disattivare le notifiche di servizio" @@ -18849,9 +19118,6 @@ msgstr "" "Visualizza un avviso se un LUN non è di sola lettura. Senza questa " "impostazione verrà visualizzato un avviso se un LUN è di sola lettura." -msgid "Display additional information" -msgstr "Visualizzazione di informazioni aggiuntive" - msgid "Display additional messages" msgstr "Visualizzare messaggi aggiuntivi" @@ -18877,9 +19143,6 @@ msgstr "" msgid "Display dashboard title" msgstr "Visualizza il titolo del cruscotto" -msgid "Display graphs among each other" -msgstr "Visualizzare i grafici tra di loro" - msgid "Display historic data since the last" msgstr "Visualizza i dati storici dall'ultimo" @@ -19773,6 +20036,10 @@ msgstr "Delta del conteggio dei documenti" msgid "Document count growth per minute" msgstr "Crescita del numero di documenti al minuto" +#, fuzzy +msgid "Documentation" +msgstr "URL della documentazione" + msgid "Documentation URL" msgstr "URL della documentazione" @@ -20545,6 +20812,10 @@ msgstr "Modifica" msgid "Edit %s" msgstr "Modifica %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Modifica la regola di notifica %d" + #, python-format msgid "Edit %s: %s" msgstr "Modifica %s: %s" @@ -20693,6 +20964,10 @@ msgstr "Modifica del layout" msgid "Edit layout only available if header is enabled" msgstr "Modifica del layout disponibile solo se l'intestazione è abilitata" +#, fuzzy +msgid "Edit managed robots" +msgstr "Oggetti gestiti" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Modifica la connessione al sito %s" @@ -20852,6 +21127,14 @@ msgstr "Modifica questo elemento" msgid "Edit this host" msgstr "Modifica questo host" +#, fuzzy +msgid "Edit this managed robot" +msgstr "Stati amministrativi" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Modifica questa regola di notifica" + msgid "Edit this notification rule" msgstr "Modifica questa regola di notifica" @@ -20923,6 +21206,9 @@ msgstr "Modificato il profilo utente per l'utente %s" msgid "Edition" msgstr "Edizione" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "Stato effettivo" @@ -21105,6 +21391,14 @@ msgstr "Indirizzo e-mail utilizzato per l'identificazione dell'account" msgid "Email addresses to mail PDF reports to" msgstr "Indirizzi e-mail a cui inviare i rapporti PDF" +#, fuzzy +msgid "Email body/content" +msgstr "Email inviata" + +#, fuzzy +msgid "Email header" +msgstr "Indirizzo e-mail" + msgid "Email sent" msgstr "Email inviata" @@ -22097,6 +22391,10 @@ msgstr "Commento dell'evento" msgid "Event console" msgstr "Console degli eventi" +#, fuzzy +msgid "Event console alerts" +msgstr "Avvisi della console eventi" + msgid "Event console performance" msgstr "Prestazioni della console degli eventi" @@ -23319,10 +23617,6 @@ msgstr "Fallito il rendering del valore:" msgid "Failed to render value: %r" msgstr "Fallito il rendering del valore: %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Fallito il recupero del certificato peer (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -23432,6 +23726,10 @@ msgstr "" "cluster. Tuttavia, si suppone che solo un nodo invii i dati, qualsiasi altro " "nodo che abbia ottenuto un risultato negativo attiverà uno stato di WARNING." +#, fuzzy +msgid "Failure" +msgstr "fallimenti" + msgid "Failures of the join launcher service" msgstr "Guasti del servizio join launcher" @@ -23727,6 +24025,10 @@ msgstr "Dimensione del file sotto" msgid "File size levels" msgstr "Livelli di dimensione dei file" +#, fuzzy +msgid "File upload" +msgstr "Byte caricati" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -23855,6 +24157,10 @@ msgstr "" "Filtro per tutte le aggregazioni che si basano sulle informazioni di stato " "di quell'host. Corrispondenza esatta (nessuna espressione regolare)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Tempo di inattività per l'host/servizio" + msgid "Filter group (see help)" msgstr "Gruppo di filtri (vedi aiuto)" @@ -24519,6 +24825,9 @@ msgstr "Reti" msgid "Form factor" msgstr "Fattore di forma" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Formato" @@ -25144,6 +25453,11 @@ msgstr "Genera" msgid "Generate REST API specification" msgstr "Generare le specifiche API REST" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + msgid "Generate backup codes" msgstr "Generare codici di backup" @@ -25206,6 +25520,21 @@ msgstr "Tasso generico" msgid "Generic string" msgstr "Stringa generica" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Versione del kernel" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Modifica connessione" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "istanza di Jenkins da interrogare." + msgid "Get file from SFTP server" msgstr "Ottenere file dal server SFTP" @@ -25263,6 +25592,10 @@ msgstr "Regola di notifica globale" msgid "Global notification rules" msgstr "Regole di notifica globale" +#, fuzzy +msgid "Global services" +msgstr "Tutti i servizi" + msgid "Global services to monitor" msgstr "Servizi globali per monitorare" @@ -25289,6 +25622,10 @@ msgstr "Modello di globbing per i file di input" msgid "Go critical if all licenses are used" msgstr "Diventa critico se tutte le licenze sono utilizzate" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Tutti gli host" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25301,6 +25638,12 @@ msgstr "Vai alla pagina principale" msgid "Go to rules of this InfluxDB connection" msgstr "Vai alle regole di questa connessione InfluxDB" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "" @@ -25463,18 +25806,12 @@ msgstr "Schede grafiche" msgid "Graphs" msgstr "Grafici" -msgid "Graphs are shown among each other" -msgstr "I grafici sono mostrati tra di loro" - msgid "Graphs for averaged single-core utilizations" msgstr "Grafici per l'utilizzo medio di un singolo core" msgid "Graphs for individual cores" msgstr "Grafici per i singoli core" -msgid "Graphs per notification (default: 5)" -msgstr "Grafici per notifica (predefinito: 5)" - msgid "Graylog" msgstr "Graylog" @@ -25563,9 +25900,6 @@ msgstr "Gruppo base DN" msgid "Group discovery and activation for up to" msgstr "Rilevamento e attivazione di gruppi fino a" -msgid "Group execution interval" -msgstr "Intervallo di esecuzione del gruppo" - msgid "Group files based on a regular expression pattern." msgstr "Raggruppa i file in base a un modello di espressione regolare." @@ -25768,6 +26102,10 @@ msgstr "HPE StoreOnce via REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: memoria utilizzata tramite SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Parametri del modello" + #, fuzzy msgid "HTML email" msgstr "Email HTML" @@ -27092,6 +27430,10 @@ msgstr "Nascondere i nomi delle variabili di configurazione" msgid "Hide notification bulks" msgstr "regole di notifica" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Inviare notifiche separate ad ogni destinatario" + msgid "Hide response from socket" msgstr "Nascondere la risposta dalla presa" @@ -27157,6 +27499,10 @@ msgstr "Storia" msgid "History Line Number" msgstr "Numero di linea della storia" +#, fuzzy +msgid "History action type" +msgstr "Stato di registrazione" + msgid "History entries of one specific event" msgstr "Voci della storia di un evento specifico" @@ -28830,10 +29176,6 @@ msgstr "Panoramica dell'host" msgid "Host parent/child topology" msgstr "Topologia genitore/figlio dell'host" -#, fuzzy -msgid "Host path" -msgstr "Allarme ospite" - msgid "Host performance data" msgstr "Dati sulle prestazioni dell'host" @@ -29538,6 +29880,10 @@ msgstr "IP - regione - ID istanza" msgid "IP Address" msgstr "Indirizzo IP" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "Indirizzo IP dell'host" + msgid "IP address" msgstr "Indirizzo IP" @@ -31506,20 +31852,6 @@ msgstr "" "che questo riguarda tutto ciò che fa parte degli spazi dei nomi " "corrispondenti, come ad esempio i pod." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Avviso

    Non hai configurato un indirizzo email " -"di ripiego né hai abilitato la ricezione di email di ripiego per nessun " -"utente. Se il tuo monitoraggio produce una notifica che non corrisponde a " -"nessuna delle tue regole di notifica, la notifica non sarà inviata. Per " -"evitare ciò, configura l'impostazione globale o attiva l'opzione di contatto " -"di ripiego per almeno uno dei tuoi utenti." - msgid "Ignore" msgstr "Ignora" @@ -32489,6 +32821,15 @@ msgstr "" msgid "Indexspace wasted" msgstr "Spazio indicizzato sprecato" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Se l'ultimo rilevamento di massa è fallito o meno. Viene impostato su True " +"quando fallisce e viene deselezionato nel caso in cui un rilevamento " +"successivo abbia successo." + msgid "Indices" msgstr "Indici" @@ -33147,6 +33488,10 @@ msgstr "Certificato non valido" msgid "Invalid certificate file: %s" msgstr "File di certificato non valido: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Parametro non valido %r: %s" + msgid "Invalid check parameter" msgstr "Parametro di controllo non valido" @@ -35948,6 +36293,10 @@ msgstr "Inventario Linux Multipath" msgid "Linux and Solaris Multipath Count" msgstr "Conteggio multiplo di Linux e Solaris" +#, fuzzy +msgid "Linux bonding" +msgstr "Collegamento Vswitch" + msgid "Linux bonding interface status" msgstr "Stato dell'interfaccia di bonding di Linux" @@ -36536,6 +36885,10 @@ msgstr "" "Registrare il processo di registrazione dell'agente delle richieste in " "arrivo tramite il comando Checkmk agent controller registration." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Abilita la rimozione automatica degli host" + msgid "Log: Details" msgstr "Registro: Dettagli" @@ -37038,6 +37391,10 @@ msgstr "" "Numero totale di clienti in attesa di una chiamata bloccante livello " "inferiore" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Elenco dei file di log attesi" + msgid "Lowest: No notification, update badge number" msgstr "Più basso: Nessuna notifica, aggiornamento del numero di badge" @@ -37603,10 +37960,25 @@ msgstr "Gestire gli utenti del sistema di monitoraggio." msgid "Managed Robot" msgstr "Oggetti gestiti" +#, fuzzy +msgid "Managed Robots" +msgstr "Oggetti gestiti" + #, fuzzy msgid "Managed objects" msgstr "Oggetti gestiti" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Oggetti gestiti" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Oggetti gestiti" + msgid "Management board" msgstr "Consiglio di amministrazione" @@ -39153,14 +39525,14 @@ msgstr "Connessioni minime al secondo" msgid "Minimum error count" msgstr "Conteggio minimo degli errori" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Livelli minimi di tensione" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Livelli minimi di carico in percentuale" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Livelli minimi di tensione" + msgid "Minimum levels if using magic factor" msgstr "Livelli minimi se si usa il fattore magico" @@ -39267,6 +39639,10 @@ msgstr "Durata non programmata (solo DaemonSet)" msgid "Misscheduled replicas" msgstr "Repliche non programmate" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Variabile mancante siteid" + #, python-format msgid "Missing config file for agent %s%s" msgstr "File di configurazione mancante per l'agente %s%s" @@ -40744,6 +41120,11 @@ msgstr "Risoluzione del nome" msgid "Name your %s for easy recognition." msgstr "Date un nome al vostro %s per facilitarne il riconoscimento." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -40758,13 +41139,13 @@ msgstr "Nomi" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" @@ -41168,6 +41549,29 @@ msgstr "Prossima notifica" msgid "Next run" msgstr "Prossima corsa" +#, fuzzy +msgid "Next step: General properties" +msgstr "Proprietà generali" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugin di notifica" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Destinatario" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "connessioni in sospeso" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Tipo di commento (host/servizio)" + msgid "Nginx Server" msgstr "Server Nginx" @@ -41183,6 +41587,10 @@ msgstr "Livelli agili di IO" msgid "No" msgstr "No" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Configurazione dell'host" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "No (errore: %s, codice: %d, profondità: %d)" @@ -41190,6 +41598,10 @@ msgstr "No (errore: %s, codice: %d, profondità: %d)" msgid "No API integrations, no Checkmk agent" msgstr "Nessuna integrazione API, nessun agente Checkmk" +#, fuzzy +msgid "No AWS services found." +msgstr "Nessun host/servizio trovato." + msgid "No CSRF token received" msgstr "Nessun token CSRF ricevuto" @@ -41200,6 +41612,10 @@ msgstr "Nessuna condizione" msgid "No Configuration Quick setup for %s available" msgstr "Variabile di configurazione:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Regola di notifica modificata %d" + msgid "No IP" msgstr "Nessun IP" @@ -41274,10 +41690,6 @@ msgstr "Nessun comando è possibile in questa vista" msgid "No conditions" msgstr "Nessuna condizione" -#, fuzzy -msgid "No configuration yet" -msgstr "Configurazione dell'host" - msgid "No configured rules are affected" msgstr "Nessuna regola configurata è interessata" @@ -41333,6 +41745,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "Non disponibile" + +#, fuzzy +msgid "No elements selected" +msgstr "Non selezionato" + msgid "No entries" msgstr "Nessuna voce" @@ -41465,6 +41885,10 @@ msgstr "Nessuna connessione definita" msgid "No need for syncing sites" msgstr "Non è necessario sincronizzare i siti" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Regola di notifica modificata %d" + msgid "No object type" msgstr "Nessun tipo di oggetto" @@ -41475,6 +41899,10 @@ msgstr "" msgid "No password provided" msgstr "Dal negozio di password" +#, fuzzy +msgid "No password selected" +msgstr "Dal negozio di password" + msgid "No pending changes" msgstr "Nessun cambiamento in sospeso" @@ -41550,6 +41978,10 @@ msgstr "Nessuna ricerca" msgid "No search, specify list of arguments" msgstr "Nessuna ricerca, specificare l'elenco degli argomenti" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthosts" + msgid "No snapshot to restore available." msgstr "Non è disponibile alcuna istantanea da ripristinare." @@ -42006,6 +42438,9 @@ msgstr "Notifica" msgid "Notation: %s" msgstr "Annotazioni: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42171,6 +42606,18 @@ msgstr "Livello del registro delle notifiche" msgid "Notification method" msgstr "Metodo di notifica" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "La collezione di grafici '%s' non esiste" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugin di notifica" + +#, fuzzy +msgid "Notification parameter" +msgstr "Fase di notifica" + #, fuzzy msgid "Notification period" msgstr "Periodo di notifica" @@ -42612,6 +43059,14 @@ msgstr "Numero di cartelle da creare in ogni livello" msgid "Number of goroutines" msgstr "Numero di tentativi" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Grafici per notifica (predefinito: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Grafici per notifica (predefinito: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Numero di ospiti sani livelli inferiori" @@ -43248,8 +43703,9 @@ msgstr "Attenuazione laser OSN" msgid "OTLP endpoint" msgstr "Endpoints" -msgid "OVS bonding interface status" -msgstr "Stato dell'interfaccia di bonding OVS" +#, fuzzy +msgid "OVS bonding" +msgstr "Collegamento Vswitch" msgid "Object" msgstr "Oggetto" @@ -45276,6 +45732,10 @@ msgstr "Eventi attuali in generale" msgid "Overall latency" msgstr "Latenza complessiva" +#, fuzzy +msgid "Overall response time" +msgstr "Tempo medio di risposta" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "Stato generale di una macchina virtuale (per esempio le VM ESX)" @@ -45339,7 +45799,7 @@ msgstr "" "costruzione" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Unità di override del sensore" msgid "Override unit of sensor" @@ -45932,13 +46392,16 @@ msgstr "Carico delle connessioni parallele" msgid "Parallel pings to send" msgstr "Ping paralleli da inviare" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Gruppi di esecuzione della suite" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Parallelizzare la creazione della configurazione del nucleo" +#, fuzzy +msgid "Parameter" +msgstr "Parametri" + msgid "Parameter groups" msgstr "Gruppi di parametri" @@ -45948,6 +46411,10 @@ msgstr "Gruppi di parametri per regione" msgid "Parameter name" msgstr "Nome del parametro" +#, fuzzy +msgid "Parameter properties" +msgstr "Proprietà del pacchetto" + msgid "Parameter rule set" msgstr "Set di regole per i parametri" @@ -45972,6 +46439,10 @@ msgstr "" "dei servizi, è possibile inserire il valore effettivo dei parametri con " "$HOST$ e $INST$ (racchiusi nel segno del dollaro)." +#, fuzzy +msgid "Parameters for" +msgstr "Parametri per %s" + #, python-format msgid "Parameters for %s" msgstr "Parametri per %s" @@ -45979,6 +46450,10 @@ msgstr "Parametri per %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parametri per le fasi di ingresso di UPS e PDU" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Parametri per questo host" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parametri per i carichi di uscita di UPS e PDU" @@ -47015,6 +47490,10 @@ msgstr "Ping dell'indirizzo IP normale" msgid "Ping timeout" msgstr "Timeout del ping" +#, fuzzy +msgid "Placeholder" +msgstr "VM segnaposto" + msgid "Placeholder VMs" msgstr "VM segnaposto" @@ -47065,6 +47544,10 @@ msgid "" "be unique." msgstr "Mappare le combinazioni di stato operativo e amministrativo" +#, fuzzy +msgid "Plan settings" +msgstr "Impostazioni globali" + msgid "Plans" msgstr "" @@ -47091,6 +47574,10 @@ msgstr "Aggiungete almeno una colonna alla vostra vista." msgid "Please add at least one endpoint to monitor" msgstr "Aggiungere almeno un endpoint da monitorare" +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Si prega di aggiungere almeno un nodo figlio." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47149,6 +47636,10 @@ msgstr "Per favore scegli un'immagine PNG valida." msgid "Please choose an audit log to view:" msgstr "Scegliere un registro di audit da visualizzare:" +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Scegli un rapporto da programmare" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Scegliere il plugin di controllo" @@ -47788,6 +48279,10 @@ msgstr "Plugin, controlli locali e MRPE per utenti non root" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Uscita del plugin" + msgid "Plugins" msgstr "Plugin" @@ -47935,6 +48430,10 @@ msgid "Positive match (Add matching services to the set)" msgstr "" "Corrispondenza positiva (Aggiungere i servizi corrispondenti all'insieme)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Corrispondenza positiva (aggiunge gli host corrispondenti all'insieme)" + msgid "Postfix" msgstr "Postfix" @@ -48113,6 +48612,10 @@ msgstr "Testo del prefisso" msgid "Prepare AWS for Checkmk" msgstr "Inizializzato GIT per Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "Inizializzato GIT per Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Prependere il prefisso dello spazio dei nomi per gli host" @@ -48769,11 +49272,10 @@ msgstr "Esecuzione del plugin dell'agente Python (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" #, fuzzy @@ -49004,14 +49506,15 @@ msgstr "RAM utilizzata (media)" msgid "RCC profile configuration" msgstr "Configurazione del profilo RCC" -#, fuzzy, python-format +#, fuzzy msgid "" -"RCC profile configuration (%s because Robotmk Core MKP has been installed)" +"RCC profile configuration (⚠ not available because Robotmk Core MKP " +"has been installed)" msgstr "Usa SSL per la connessione." msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" msgid "RCU" @@ -49613,6 +50116,10 @@ msgstr "Destinatario" msgid "Recipient email address" msgstr "Destinatario Indirizzo e-mail" +#, fuzzy +msgid "Recipients" +msgstr "Destinatario" + #, python-format msgid "Recipients: %s" msgstr "Destinatario: %s" @@ -50109,6 +50616,10 @@ msgstr "Vita rimanente" msgid "Remaining Open Slots" msgstr "Slot rimanenti aperti" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Tempo di validità residuo" + msgid "Remaining credits lower levels" msgstr "Crediti rimanenti livelli inferiori" @@ -50268,9 +50779,6 @@ msgstr "Rimuovere tutti i file e le sottodirectory" msgid "Remove downtimes" msgstr "Rimuovere i tempi morti" -msgid "Remove downtimes?" -msgstr "Eliminare i tempi di inattività?" - msgid "Remove explicit attribute settings" msgstr "Rimuovere le impostazioni esplicite degli attributi" @@ -50299,6 +50807,10 @@ msgstr "Eliminare i tempi di inattività programmati?" msgid "Remove service" msgstr "Rimuovere il servizio" +#, fuzzy +msgid "Remove smarthost" +msgstr "Rimuovi questa voce" + msgid "Remove style" msgstr "Rimuovere lo stile" @@ -50878,6 +51390,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Richiede dati da un'istanza di Jenkins." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Richiede dati da un'istanza di Jenkins." @@ -50921,6 +51437,10 @@ msgstr "Porta richiesta" msgid "Required context filters" msgstr "Filtri di contesto richiesti" +#, fuzzy +msgid "Required field missing" +msgstr "Manca il sito" + msgid "Required match (regular expression)" msgstr "Corrispondenza richiesta (espressione regolare)" @@ -51235,6 +51755,10 @@ msgstr "Limitare i servizi di monitoraggio con uno di questi tag AWS" msgid "Restrict number of processed messages per cycle" msgstr "Limita il numero di messaggi elaborati per ciclo" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Limitare la gravità al peggio" + msgid "Restrict runtime of logfile parsing" msgstr "Limitare il tempo di esecuzione dell'analisi dei file di log" @@ -51375,6 +51899,11 @@ msgstr "" "Recuperare informazioni sul processo usando WMI (Windows Management " "Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Riprova" @@ -51399,6 +51928,10 @@ msgstr "Riprova questo test" msgid "Retry time" msgstr "Tempo di riprova" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "restituisce CRITICAL se trovato, OK altrimenti" + msgid "Return code class 2xx (success)" msgstr "Codice di ritorno classe 2xx (successo)" @@ -51416,7 +51949,12 @@ msgstr "Tempi di processo di ritorno all'interno dei dati di performance" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -51437,10 +51975,19 @@ msgstr "Attivare i cambiamenti stranieri" msgid "Review and run preview service discovery" msgstr "Salvare & eseguire il rilevamento dei servizi" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configurazione remota" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Salvare & eseguire il rilevamento dei servizi" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Giri al minuto" @@ -51491,6 +52038,10 @@ msgstr "Struttura del robot: %s" msgid "Robot Framework: Last log" msgstr "Robot Framework: Ultimo log" +#, fuzzy +msgid "Robot package" +msgstr "Rimuovere il pacchetto" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -52592,12 +53143,14 @@ msgstr "Salvare come nuovo layout per questa aggregazione" msgid "Save response" msgstr "Salva la risposta" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Salva questo host e vai a" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "Salvata la configurazione di controllo dell'host '%s' con %d servizi" @@ -52646,9 +53199,6 @@ msgstr "Programmare il tempo di inattività sull'host" msgid "Schedule downtime on service" msgstr "Programmare i tempi di inattività del servizio" -msgid "Schedule downtime?" -msgstr "Programmare i tempi di inattività?" - msgid "Schedule downtimes" msgstr "Programmare i tempi di inattività" @@ -53015,6 +53565,10 @@ msgstr "" msgid "Secret access key" msgstr "Chiave segreta" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Chiave segreta" + msgid "Secret key" msgstr "Chiave segreta" @@ -53183,6 +53737,15 @@ msgstr "Seleziona un file iCalendar (*.ics) dal tuo PC" msgid "Select and configure AWS services you would like to monitor" msgstr "Servizi Azure da monitorare" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Servizi Azure da monitorare" + +#, fuzzy +msgid "Select contact group" +msgstr "Regola gruppi di contatto" + #, fuzzy msgid "Select datasource" msgstr "Seleziona sorgente di dati" @@ -53381,6 +53944,10 @@ msgstr "Seleziona il tipo di elemento della pagina fissa" msgid "Select type from list" msgstr "Selezionare il tipo dall'elenco" +#, fuzzy +msgid "Select user" +msgstr "Cancellare gli utenti" + msgid "Select view" msgstr "Seleziona la vista" @@ -53417,6 +53984,10 @@ msgstr "Il sito %s è stato eliminato." msgid "Selected credential has been deleted" msgstr "La credenziale selezionata è stata eliminata" +#, fuzzy +msgid "Selected options" +msgstr "Connessioni rifiutate" + msgid "Selected sections will not be executed by the agent." msgstr "Le sezioni selezionate non saranno eseguite dall'agente." @@ -53487,6 +54058,10 @@ msgstr "Inviare dati HTTP POST" msgid "Send custom notification" msgstr "Inviare una notifica personalizzata" +#, fuzzy +msgid "Send custom notification?" +msgstr "Inviare una notifica personalizzata" + #, fuzzy msgid "Send data" msgstr "Dati mappati" @@ -53531,9 +54106,7 @@ msgid "Send notifications to remote Event Console" msgstr "Inviare notifiche alla console degli eventi remota" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "" "Inviare le notifiche secondo le regole di notifica (deselezionare per " "evitare lo spam)" @@ -53543,10 +54116,6 @@ msgid "" "notifications (forced)" msgstr "" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Inviare notifiche separate ad ogni destinatario" - msgid "Send service metrics to Graphite" msgstr "Inviare le metriche del servizio a Graphite" @@ -53588,6 +54157,10 @@ msgstr "Inviare via e-mail" msgid "Sending Power" msgstr "Invio di potenza" +#, fuzzy +msgid "Sending conditions" +msgstr "Impostare le condizioni" + msgid "Sending reply" msgstr "Invio della risposta" @@ -53641,7 +54214,11 @@ msgid "September" msgstr "Settembre" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Intervallo di esecuzione del gruppo" + +#, fuzzy +msgid "Sequence of plans" msgstr "Esecuzione del programma" msgid "Serial" @@ -53876,6 +54453,10 @@ msgstr "Scoperta del servizio: Descrizione del servizio" msgid "Service discovery: State" msgstr "Scoperta del servizio: Stato" +#, fuzzy +msgid "Service events" +msgstr "Livelli di servizio" + msgid "Service goes into critical state" msgstr "Il servizio va in stato critico" @@ -54207,6 +54788,10 @@ msgstr "Servizi del sito" msgid "Services per cluster" msgstr "Servizi per cluster" +#, fuzzy +msgid "Services per region" +msgstr "Servizi per regione da monitorare" + msgid "Services per region to monitor" msgstr "Servizi per regione da monitorare" @@ -54731,7 +55316,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -55099,6 +55684,10 @@ msgstr "Mostra le caselle di controllo" msgid "Show column headings" msgstr "Mostra le intestazioni delle colonne" +#, fuzzy +msgid "Show contact groups" +msgstr "Ospitare gruppi di contatto" + msgid "Show context" msgstr "Mostra il contesto" @@ -55165,9 +55754,17 @@ msgstr "Mostra il suggerimento nel menu 'Utente'" msgid "Show historic values" msgstr "Mostra i valori storici" +#, fuzzy +msgid "Show host labels" +msgstr "Mostra nelle tabelle dell'host" + msgid "Show host status" msgstr "Mostra lo stato dell'host" +#, fuzzy +msgid "Show host tags" +msgstr "Mostra lo stato dell'host" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Mostra l'icona che collega all'editor dei parametri di Setup per i servizi" @@ -55243,6 +55840,10 @@ msgstr "Mostra di più / Mostra di meno" msgid "Show notification bulks" msgstr "regole di notifica" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Ordinamento delle notifiche per le notifiche di massa" + msgid "Show number of groups" msgstr "Mostra il numero di gruppi" @@ -55305,6 +55906,10 @@ msgstr "Mostra le regole usando questo %s" msgid "Show separate result for each SLA period" msgstr "Mostra un risultato separato per ogni periodo SLA" +#, fuzzy +msgid "Show service labels" +msgstr "Etichette di servizio" + #, fuzzy msgid "Show service name" msgstr "Il nome del servizio" @@ -55692,6 +56297,11 @@ msgstr "" "preferito). È possibile annullare questo automatismo specificando un nodo " "qui." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -56619,6 +57229,10 @@ msgstr "Oggetti specifici" msgid "Specific sites" msgstr "Siti specifici" +#, fuzzy +msgid "Specific users" +msgstr "Siti specifici" + msgid "Specific version" msgstr "Versione specifica" @@ -56641,13 +57255,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Specifica lo stile di linea predefinito" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Specifica se l'autenticazione con password è permessa" @@ -56818,13 +57425,6 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -57265,6 +57865,11 @@ msgstr "" "Specifica cosa fare se il grafico selezionato manca o non può essere " "recuperato." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Specificare quali tipi di porta non devono essere scoperti" @@ -57476,6 +58081,10 @@ msgstr "Inizio del prossimo anno" msgid "Start or end of a scheduled downtime" msgstr "Inizio o fine di un tempo di inattività programmato" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Inizio del periodo di inattività" + msgid "Start or end of flapping state" msgstr "Inizio o fine dello stato di flapping" @@ -57696,6 +58305,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Stato per modalità di legame specifiche" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Avvertire su un'interfaccia attiva inaspettata" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Scoperta del servizio in sospeso" + msgid "State if 'maintenance' services are found" msgstr "Dichiarare se i servizi di \"manutenzione\" si trovano" @@ -58719,10 +59336,12 @@ msgstr "Nome della sezione" msgid "Subject for bulk notifications" msgstr "Soggetto per le notifiche di massa" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Soggetto per le notifiche dell'host" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Soggetto per le notifiche di servizio" msgid "Submit" @@ -59114,6 +59733,10 @@ msgstr "Sincrono" msgid "Syncing" msgstr "Sincronizzazione" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "Certificato router SAP" + msgid "Synology Updates" msgstr "Aggiornamenti Synology" @@ -59395,6 +60018,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLS L'autenticazione senza TLS non è possibile" +#, fuzzy +msgid "TLS certificate verification" +msgstr "Verifica del certificato SSL" + msgid "TLS processed bytes" msgstr "Byte elaborati TLS" @@ -59613,6 +60240,16 @@ msgstr "" "I tag possono essere utilizzati per classificare host e servizi in modo " "flessibile." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "Nessuna fonte di dati definita." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Tag dell'allarme." @@ -59850,6 +60487,10 @@ msgstr "Testate una notifica autodefinita rispetto al vostro set di regole." msgid "Test authentication" msgstr "Test di autenticazione" +#, fuzzy +msgid "Test configuration" +msgstr "Configurazione dell'host" + msgid "Test connection" msgstr "Collegamento di prova" @@ -59879,6 +60520,9 @@ msgstr "Notifiche di prova su" msgid "Test runtime" msgstr "Tempo di esecuzione del test" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + msgid "Test verification" msgstr "Verifica del test" @@ -61121,6 +61765,10 @@ msgid "The central (%s) and remote site (%s) are not compatible. Reason: %s" msgstr "" "Il sito centrale (%s) e quello remoto (%s) non sono compatibili. Motivo: %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "Non è mai stato attivato" + #, python-format msgid "The character %s is not allowed here." msgstr "Il carattere %s non è permesso qui." @@ -61409,6 +62057,11 @@ msgstr "" "La connessione crea gli host in questa particolare cartella. Una volta " "creato, è possibile scegliere di spostare l'host in un'altra cartella." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "La connessione a questo sito è stata disabilitata." @@ -61671,24 +62324,6 @@ msgstr "L'elemento non può essere trovato sul cruscotto." msgid "The element does not exist." msgstr "L'elemento non esiste." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"L'indirizzo email e il nome visibile usati nell'intestazione From dei " -"messaggi di notifica. Se non viene specificato alcun indirizzo email, viene " -"utilizzato l'indirizzo predefinito OMD_SITE@FQDN. Se la variabile " -"d'ambiente OMD_SITE non è impostata, il default è checkmk." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"L'indirizzo e-mail e il nome visibile usati nell'intestazione Reply-To dei " -"messaggi di notifica." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -62041,12 +62676,6 @@ msgstr "Manca la specifica del grafico" msgid "The graph template id '%s' is disabled" msgstr "Il modello di grafico id '%s' è disabilitato" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -62280,13 +62909,6 @@ msgstr "" "Il nome dell'istanza, il nome del database e il nome del tablespace " "combinati in questo modo db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -62668,6 +63290,12 @@ msgstr "" "questo servizio vada in allarme/critico. Questo allarme si applica solo " "all'host di destinazione, non alle tappe intermedie." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "La lunghezza massima del valore è di 256 caratteri." @@ -64310,6 +64938,20 @@ msgstr "" "Le soglie per wait_duration_ms. Sovrascriverà lo stato predefinito impostato " "sopra." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "I dati statistici dell'intervallo di tempo vengono salvati su disco" @@ -64465,6 +65107,14 @@ msgid "The username returned by the %s connector is not of type string (%r)." msgstr "" "Il nome utente restituito dal connettore %s non è di tipo stringa (%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"Il nome utente che dovrebbe essere usato per accedere all'API Graylog. Deve " +"avere almeno i permessi di lettura." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -64766,8 +65416,8 @@ msgstr "Non c'è nessuna istantanea di Setup da ripristinare." msgid "There is no backup job configured" msgstr "Non c'è nessun lavoro di backup configurato" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "Non esiste un modello di grafico con l'id '%s'" msgid "There is no manpage for this check." @@ -64939,7 +65589,7 @@ msgstr "Questi nodi sono presenti solo nell'aggregazione congelata" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" msgid "" @@ -65259,6 +65909,9 @@ msgstr "" "dell'agente sull'host monitorato (fare riferimento a `cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + msgid "" "This active check sends out special emails to a defined mail address using " "either the SMTP protocol or an EWS connection and then tries to receive " @@ -65976,10 +66629,11 @@ msgid "" "service in the following table." msgstr "" +#, fuzzy msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -66825,8 +67479,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Questa autorizzazione consente agli utenti di migrare altri utenti a " "un'altra connessione" @@ -67437,13 +68090,6 @@ msgstr "" "questi parametri porterà a frequenti cambiamenti nell'inventario HW/SW, che " "possono riempire rapidamente il file system temporaneo." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Questa regola consente il monitoraggio di VMware ESX tramite l'API di " -"vSphere. È possibile configurare le impostazioni di connessione qui." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -68124,15 +68770,6 @@ msgstr "" "Questo set di regole seleziona l'agente speciale NetApp invece del normale " "agente Checkmk e consente il monitoraggio tramite l'API REST di NetApp Ontap." -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Questo set di regole seleziona l'agente speciale per le appliance HPE " -"StoreOnce invece del normale agente Checkmk e consente il monitoraggio " -"tramite REST API v4.x o superiore. " - msgid "" "This rule sets limits to the current number of connections through a Check " "Point firewall." @@ -72861,9 +73498,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "Si è cercato di registrare un rulespec incompatibile: %r" +#, fuzzy +msgid "Triggering events" +msgstr "Archivio eventi" + msgid "Trivial change" msgstr "Cambiamento banale" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -74058,6 +74702,14 @@ msgstr "Carica la risposta" msgid "Upload verification response file" msgstr "Caricare il file di risposta alla verifica" +#, fuzzy +msgid "Uploaded" +msgstr "Carica" + +#, fuzzy +msgid "Uploaded by" +msgstr "Carica la chiave" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "Caricato un logo GUI personalizzato: %s" @@ -75436,6 +76088,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">limite globale " "degli eventi delle regole" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Usate questa opzione per interrogare una porta diversa dalla porta standard " +"443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -75477,6 +76135,14 @@ msgstr "" "interrogato il server successivo (fallback). Il controllo emetterà solo dati " "dal primo host che invia una risposta." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Usa questa opzione per impostare quale istanza dovrebbe essere controllata " +"dall'agente speciale. Aggiungi qui l'hostname, ad esempio my_graylog.com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -75875,7 +76541,8 @@ msgstr "Messaggi dell'utente" msgid "User name" msgstr "Nome utente" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Nome utente sul sistema di archiviazione. I permessi di sola lettura sono " "sufficienti." @@ -75971,6 +76638,10 @@ msgstr "Utenti in Active Directory" msgid "Users listed here are still allowed to modify things." msgstr "Gli utenti elencati qui sono ancora autorizzati a modificare le cose." +#, fuzzy +msgid "Users of contact groups" +msgstr "Membri di gruppi di contatto" + msgid "Users using a cifs share" msgstr "Utenti che usano una condivisione cifs" @@ -77011,6 +77682,10 @@ msgstr "Verifica dei certificati" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Ignorare gli errori del certificato (non sicuro)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Ignorare gli errori del certificato (non sicuro)" + msgid "Verify certificates" msgstr "Verifica dei certificati" @@ -77073,6 +77748,9 @@ msgstr "Versione del dispositivo PKI" msgid "Version of Server" msgstr "Versione del server" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Versioni: %s" @@ -77530,6 +78208,10 @@ msgstr "Connessioni in attesa" msgid "Waiting containers" msgstr "Contenitori in attesa" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Scoperta della porta Netapp" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -77909,6 +78591,9 @@ msgstr "" msgid "What is the purpose?" msgstr "" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -78963,6 +79648,10 @@ msgstr "" msgid "Who" msgstr "Chi" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "permettere agli utenti di disattivare questa notifica" + msgid "WiFi connection types" msgstr "Tipi di connessione WiFi" @@ -79124,7 +79813,7 @@ msgstr "" msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -79442,6 +80131,13 @@ msgstr "" "Questo potrebbe confondere.Questa regola dovrebbe essere " "configurata solo nelle fasi iniziali." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -80366,6 +81062,14 @@ msgstr "Non è possibile eliminare la connessione al sito locale." msgid "You can not delete this %s because it is in use." msgstr "Non puoi cancellare questo %s perché è in uso." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"Non puoi eliminare questa destinazione perché è usata da questi processi di " +"backup: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -81184,6 +81888,10 @@ msgstr "" "Non è ancora stato creato alcun agente chiavi " "di firma. È necessario." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Parametri per questo host" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -83077,9 +83785,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "monitorare" - msgid "month" msgstr "mese" @@ -83989,6 +84694,9 @@ msgstr "{actual} è troppo alto. Il valore massimo consentito è {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} è troppo basso. Il valore minimo consentito è {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -83997,6 +84705,133 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Tutti i diritti riservati." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Usa SSL per la connessione." + +#~ msgid "API key from password store" +#~ msgstr "Chiave API dal negozio di password" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Allarme ospite" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Fallito il recupero del certificato peer (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Avviso

    Non hai configurato un indirizzo " +#~ "email di ripiego né hai abilitato la ricezione di email di ripiego " +#~ "per nessun utente. Se il tuo monitoraggio produce una notifica che non " +#~ "corrisponde a nessuna delle tue regole di notifica, la notifica non sarà " +#~ "inviata. Per evitare ciò, configura l'impostazione globale o attiva " +#~ "l'opzione di contatto di ripiego per almeno uno dei tuoi utenti." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Notifiche di massa con grafici (predefinito: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Per impostazione predefinita, tutti i grafici multipli nelle e-mail " +#~ "vengono visualizzati vicini e fluttuanti. Puoi abilitare questa opzione " +#~ "per mostrare i grafici tra di loro." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configurare questo per far sì che il plugin di notifica si connetta " +#~ "direttamente al server smtp. Questo ha il vantaggio di fornire migliori " +#~ "messaggi di errore in caso di errore, ma richiede più configurazione ed è " +#~ "strettamente sincrono, quindi si consiglia l'uso solo su installazioni " +#~ "aziendali che utilizzano lo spooler di notifica." + +#~ msgid "Display additional information" +#~ msgstr "Visualizzazione di informazioni aggiuntive" + +#~ msgid "Display graphs among each other" +#~ msgstr "Visualizzare i grafici tra di loro" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "I grafici sono mostrati tra di loro" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "L'indirizzo email e il nome visibile usati nell'intestazione From dei " +#~ "messaggi di notifica. Se non viene specificato alcun indirizzo email, " +#~ "viene utilizzato l'indirizzo predefinito OMD_SITE@FQDN. Se la " +#~ "variabile d'ambiente OMD_SITE non è impostata, il default è " +#~ "checkmk." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "L'indirizzo e-mail e il nome visibile usati nell'intestazione Reply-To " +#~ "dei messaggi di notifica." + +#~ msgid "Activate" +#~ msgstr "Attivare" + +#~ msgid "Deactivate" +#~ msgstr "Disattivare" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Questa regola consente il monitoraggio di VMware ESX tramite l'API di " +#~ "vSphere. È possibile configurare le impostazioni di connessione qui." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Questo set di regole seleziona l'agente speciale per le appliance HPE " +#~ "StoreOnce invece del normale agente Checkmk e consente il monitoraggio " +#~ "tramite REST API v4.x o superiore. " + +#~ msgid "monitor" +#~ msgstr "monitorare" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Nome dell'account di archiviazione" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Gruppi di esecuzione della suite" + +#~ msgid "(not supported)" +#~ msgstr "(non supportato)" + +#~ msgid "Remove downtimes?" +#~ msgstr "Eliminare i tempi di inattività?" + +#~ msgid "Schedule downtime?" +#~ msgstr "Programmare i tempi di inattività?" + +#~ msgid "OVS bonding interface status" +#~ msgstr "Stato dell'interfaccia di bonding OVS" + #~ msgid "Common Name" #~ msgstr "Nome comune" @@ -84125,10 +84960,6 @@ msgstr "© %s Checkmk GmbH. Tutti i diritti riservati." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Quota utilizzata: Livelli superiori assoluti o relativi" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "Non è mai stato attivato" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Spazi per la tavola" @@ -84420,10 +85251,6 @@ msgstr "© %s Checkmk GmbH. Tutti i diritti riservati." #~ msgid "%s operations" #~ msgstr "%s operazioni" -#, fuzzy, python-format -#~ msgid "%s requests" -#~ msgstr "%s Richieste" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -84753,9 +85580,6 @@ msgstr "© %s Checkmk GmbH. Tutti i diritti riservati." #~ msgid "InfluxDB Queue Usage" #~ msgstr "Utilizzo della coda di InfluxDB" -#~ msgid "Kernel Version" -#~ msgstr "Versione del kernel" - #~ msgid "Levels Helper usage Check" #~ msgstr "Livelli di utilizzo dell'aiutante Controllo" diff --git a/locale/ja/LC_MESSAGES/multisite.po b/locale/ja/LC_MESSAGES/multisite.po index 66e826b9b35..0f174534b2b 100644 --- a/locale/ja/LC_MESSAGES/multisite.po +++ b/locale/ja/LC_MESSAGES/multisite.po @@ -400,6 +400,10 @@ msgstr "%d日間" msgid "%d days ago" msgstr "%d 日前" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "一般的なプロパティ" + #, python-format msgid "%d errors occured:" msgstr "%d エラーが発生しました:" @@ -560,6 +564,10 @@ msgstr "ホスト別の %s" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -681,6 +689,10 @@ msgstr "%sレート" msgid "%s resulting notifications" msgstr "%s 結果の通知" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s リクエスト" + #, python-format msgid "%s running for %s" msgstr "%s は %sで実行されています" @@ -797,9 +809,17 @@ msgstr "" "のバージョン管理には必要です。'git'をインストールするかセットアップでgitコン" "フィギュレーション・トラッキングを無効にしてください。" +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "削除されたエントリ" + msgid "(0 is current period)" msgstr "(0は現在の期間です)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(ノーエントリ)" + msgid "(Edit presets)" msgstr "(プリセットを編集する)" @@ -875,9 +895,6 @@ msgstr "(タイトルなし)" msgid "(none)" msgstr "(無し)" -msgid "(not supported)" -msgstr "(サポートされていません)" - msgid "(nothing selected)" msgstr "(何も選択されていません)" @@ -985,6 +1002,10 @@ msgstr "1つの変更" msgid "1 row" msgstr "1行" +#, fuzzy +msgid "1 rule" +msgstr "ルール" + msgid "1 year" msgstr "1年" @@ -1172,6 +1193,29 @@ msgstr "95パーセンタイル" msgid "99th percentile" msgstr "99パーセンタイル" +#, fuzzy +msgid "< Remove" +msgstr "削除する" + +#, fuzzy +msgid "<< Remove all" +msgstr "すべて削除する" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"ピギーバッ" +"ク翻訳はpiggybackコネクタがホストを作成する前に実行されます。これは、例え" +"ば複数のDockerノードがあるセットアップで、コンテナの前に対応するDockerノード" +"の名前を付けるために使用します。そうしないと同じ名前のコンテナが複数のDocker" +"ノードに存在する場合、名前の衝突が発生する可能性があります。" + msgid "" "Piggybacktranslations注意: htpasswdコネクタに移行した場合、ユーザーは次回ログイン時" "にパスワードを変更する必要があります。" +#, fuzzy msgid "" "Note3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "注意3: このプラグインをSolarisにデプロイするには、ターゲッ" @@ -1330,6 +1375,12 @@ msgstr "警告:%dの未確認の互換性のないwerksがあります:" msgid "You do not have any roles." msgstr "あなたには役割がありません。" +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1871,11 +1922,12 @@ msgid "" msgstr "" "sqlnet.oratnsnames.ora %sに使用するTNS_ADMIN" +#, fuzzy msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" "robot.yamlRCCのメイン設定ファイルです。これはRobot Frameworkプロジェ" "クトのベースディレクトリからの相対パスで指定します。このファイルは conda." @@ -2045,6 +2097,14 @@ msgstr "グラフの見出し" msgid "A heading for the view" msgstr "ビューの見出し" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"%sという名前のホストは、フォルダー
    %sに既に" +"存在します。" + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "%sを追加" + msgid "Add Aggregation" msgstr "集計を追加" @@ -3486,9 +3563,6 @@ msgstr "例外を追加" msgid "Add Group" msgstr "グループを追加" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "テーブル上にHTMLセクションを追加する(例:タイトル、説明文...)" - msgid "Add LDAP connection" msgstr "LDAP接続を追加します" @@ -3534,6 +3608,9 @@ msgstr "集計を追加" msgid "Add alert handler rule" msgstr "アラートハンドラールールを追加する" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "検出されたがまだ監視されていないすべてのサービスを監視に追加します。" @@ -3633,6 +3710,10 @@ msgstr "エレメントを追加:%s" msgid "Add elements to your sidebar" msgstr "サイドバーに要素を追加する" +#, fuzzy +msgid "Add event" +msgstr "エレメントを追加" + msgid "Add exception" msgstr "例外を追加" @@ -3819,6 +3900,10 @@ msgstr "新しいノード条件を追加" msgid "Add new pattern" msgstr "新しいパターンを追加する" +#, fuzzy +msgid "Add new plan" +msgstr "新しいパターンを追加する" + msgid "Add new project" msgstr "新しいプロジェクトを追加する" @@ -3834,9 +3919,17 @@ msgstr "グループを追加" msgid "Add new scalar" msgstr "新しいスカラーを追加する" +#, fuzzy +msgid "Add new sequence" +msgstr "新しいサービスを追加する" + msgid "Add new service" msgstr "新しいサービスを追加する" +#, fuzzy +msgid "Add new smarthost" +msgstr "新しいマクロを追加" + msgid "Add new status" msgstr "ステータスを追加" @@ -3878,6 +3971,10 @@ msgstr "実行可能ファイルの追加と変更" msgid "Add page element" msgstr "ページ要素を追加" +#, fuzzy +msgid "Add parameter" +msgstr "モデルパラメータ" + msgid "Add pattern" msgstr "パターンを追加する" @@ -3901,6 +3998,10 @@ msgstr "%sTNSALIASに前置または後置を追加" msgid "Add random hosts" msgstr "ランダムなホストを追加する" +#, fuzzy +msgid "Add recipient" +msgstr "受信者" + msgid "Add remote instance" msgstr "リモートインスタンスを追加します" @@ -4142,6 +4243,10 @@ msgstr "追加のIPv6アドレス" msgid "Additional agent labels to send during registration" msgstr "登録時に送信するエージェントラベルの追加" +#, fuzzy +msgid "Additional details" +msgstr "追加オプション" + msgid "Additional header lines" msgstr "追加のヘッダー行" @@ -4262,7 +4367,7 @@ msgid "Admin states to discover" msgstr "管理者は発見するように述べています" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "管理状態" msgid "Administrative port states to discover" @@ -4894,6 +4999,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "アラートハンドラーの構成" +#, fuzzy +msgid "Alert handler execution" +msgstr "アラートハンドラーの実行" + msgid "Alert handler execution, failed" msgstr "アラートハンドラーの実行に失敗しました" @@ -5000,6 +5109,18 @@ msgstr "アラート統計: 不明なアラートの数" msgid "Alert statistics: Number of warnings" msgstr "アラート統計:警告の数" +#, fuzzy +msgid "Alert when a major version release is available" +msgstr " 商業リリースが可能になり次第、通知を受け取る。 " + +#, fuzzy +msgid "Alert when a minor version release is available" +msgstr " 商業リリースが可能になり次第、通知を受け取る。 " + +#, fuzzy +msgid "Alert when a patch version release is available" +msgstr " 商業リリースが可能になり次第、通知を受け取る。 " + msgid "Alerted" msgstr "警告" @@ -5102,6 +5223,10 @@ msgstr "すべてのコレクション" msgid "All components" msgstr "すべてのコンポーネント" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "通知されたオブジェクトのすべての連絡先" + msgid "All contacts of the notified object" msgstr "通知されたオブジェクトのすべての連絡先" @@ -5505,6 +5630,10 @@ msgstr "ホストビューとサービスビューでアイコン %s を表示 msgid "Allow unencrypted legacy communication" msgstr "暗号化されていないレガシー通信を許可する" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "ユーザーがこの通知を非アクティブ化できるようにする" + msgid "Allowed Ciphers" msgstr "許可された暗号" @@ -6082,6 +6211,10 @@ msgstr "別のユーザー同期がすでに実行されています:%s" msgid "AntiVirus last update age" msgstr "アンチウイルスの最終更新期間" +#, fuzzy +msgid "Any" +msgstr "どれか" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6256,9 +6389,21 @@ msgstr "アプリケーションの概要" msgid "Applications, Processes & Services" msgstr "アプリケーション、プロセスとサービス" +#, fuzzy +msgid "Applied to" +msgstr "に適用する" + msgid "Apply" msgstr "適用する" +#, fuzzy +msgid "Apply & create another rule" +msgstr "アラートハンドラールール" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "この通知ルールを削除します" + #, fuzzy msgid "Apply Latency" msgstr "レイテンシー" @@ -6281,6 +6426,11 @@ msgstr "条件を適用する" msgid "Apply filters" msgstr "フィルタを適用する" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + msgid "Apply finish time" msgstr "終了時間を適用する" @@ -6404,6 +6554,10 @@ msgstr "最近のリモート監査ログを取得" msgid "Archive event" msgstr "イベントのアーカイブ" +#, fuzzy +msgid "Archive event?" +msgstr "イベントのアーカイブ" + msgid "Archive events" msgstr "イベントのアーカイブ" @@ -6534,6 +6688,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + msgid "Assign plan/test result to piggyback host" msgstr "プラン/テスト結果をピギーバックホストに割り当てる" @@ -6951,10 +7110,10 @@ msgstr "自動拡張可能" msgid "Automated environment setup (via RCC)" msgstr "自動環境セットアップ(RCC経由)" -#, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "動環境設定(RCC経由、Robotmk Core MKPがインストールされているので%s)" msgid "Automatic" @@ -8287,6 +8446,10 @@ msgstr "ベーキングエージェント" msgid "Baked host specific agent" msgstr "ベイクされたホストの特定エージェント" +#, fuzzy +msgid "Bakery rules" +msgstr "ディスカバリールール" + msgid "Baking Agents..." msgstr "ベーキングエージェント..." @@ -8798,8 +8961,9 @@ msgstr "ホストの一括インポート" msgid "Bulk move" msgstr "一括移動" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "グラフ付きの一括通知(デフォルト: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "一括通知を開く" msgid "Bulk removal of explicit attributes" msgstr "明示的な属性の一括削除" @@ -9129,13 +9293,6 @@ msgstr "" "に接続します。このルールを使用して、SNMPを介してホストに接続するときに使用す" "る資格情報をカスタマイズできます。" -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"デフォルトでは、電子メール内のすべての複数のグラフが近くに浮かんで表示されま" -"す。このオプションを有効にすると、グラフを相互に表示できます。" - msgid "By default all of the sections will be executed." msgstr "デフォルトでは、すべてのセクションが実行されます。" @@ -9308,6 +9465,7 @@ msgstr "" "バージョンのいずれかの使用を強制できます。
    さらに、Pythonプラグインの実行" "に使用されるコマンドを提供できます。" +#, fuzzy msgid "" "By default, Robot Framework will execute every test.
    But sometimes " "tests are interdependent - in the event of a failed login, for example, it " @@ -9315,14 +9473,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" "デフォルトでは、Robot Frameworkはすべてのテストを実行します。
    しか" "し、テストが相互に依存している場合もあります。例えば、ログインに失敗した場" @@ -9338,13 +9496,14 @@ msgstr "" "case-fails\" target=\"_blank\">How to stop a suite when the first test " "fails\"も参照のこと。 " +#, fuzzy msgid "" "By default, Robotmk executes all plans in the user context of the Checkmk " "agent, which does not have access to the desktop of the Windows computer. To " "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" "デフォルトでは、Robotmk はすべての計画を Checkmk エージェントのユーザコンテキ" "ストで実行します。Windows GUI アプリケーションのテストを実行するには、デスク" @@ -9599,10 +9758,11 @@ msgstr "" msgid "Bypass Proxy for certain hosts" msgstr "特定のホストのプロキシをバイパスする" +#, fuzzy msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -10820,6 +10980,10 @@ msgstr "LDAP接続 %s を変更しました" msgid "Changed alert handler rule %d" msgstr "アラートハンドラルール%dを変更しました" +#, fuzzy +msgid "Changed by" +msgstr "変更" + msgid "Changed entries" msgstr "変更されたエントリ" @@ -10834,6 +10998,14 @@ msgstr[0] "変更されたホストラベル: " msgid "Changed host selection has been saved." msgstr "変更されたホストの選択が保存されました。" +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "通知ルール %d を変更しました" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "通知ルール %d を変更しました" + #, python-format msgid "Changed notification rule %d" msgstr "通知ルール %d を変更しました" @@ -10853,6 +11025,10 @@ msgstr "%s %dの位置を変更しました" msgid "Changed position of connection %s to %d" msgstr "接続%sの位置を%dに変更しました" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "ユーザー%dの通知ルール%sの位置を変更しました" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "ユーザー%dの通知ルール%sの位置を変更しました" @@ -10907,6 +11083,10 @@ msgstr "サイト固有の構成変数 %s を %sに変更しました。" msgid "Changes" msgstr "変更" +#, fuzzy +msgid "Changes activated" +msgstr "アクティベートされたことがない" + msgid "Changes since last dump" msgstr "前回ダンプ時からの変更点" @@ -12122,6 +12302,11 @@ msgstr "" msgid "Click on 'Register %s' to enable two-factor authentication via %s." msgstr "「%sを登録」をクリックし、%sによる2要素認証を有効にする。" +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "クリックで設定を切り替える" @@ -12278,6 +12463,10 @@ msgstr "新しい接続を作成するには、この接続のクローンを作 msgid "Clone this element" msgstr "この要素のクローンを作成します" +#, fuzzy +msgid "Clone this managed robot" +msgstr "管理対象オブジェクト" + msgid "Clone this metric" msgstr "このメトリックのクローンを作成します" @@ -12812,6 +13001,10 @@ msgstr "復元を完了します" msgid "Complete tree" msgstr "完全なツリー" +#, fuzzy +msgid "Complete variable list" +msgstr "完全な変数リスト(テスト用)" + msgid "Complete variable list (for testing)" msgstr "完全な変数リスト(テスト用)" @@ -12953,6 +13146,10 @@ msgstr "構成ファイル ('*.mk' or '*.conf') from etc/checkmk: %s" msgid "Configuration generation" msgstr "構成の生成" +#, fuzzy +msgid "Configuration name" +msgstr "コンフィギュレーション" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Checkmkのビジネスインテリジェンスコンポーネントの設定" @@ -13022,6 +13219,10 @@ msgstr "設定" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Amazon Web Services (AWS)監視" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Amazon Web Services (AWS)監視" + msgid "Configure SNMP related settings using rulesets" msgstr "ルールセットを使用してSNMP関連の設定を設定する" @@ -13082,6 +13283,10 @@ msgstr "クラッシュレポートのフォールバックメールアドレス msgid "Configure grouping of interfaces" msgstr "インターフェイスのグループ化を構成します" +#, fuzzy +msgid "Configure host and authority" +msgstr "コンフィギュレーション" + #, fuzzy msgid "Configure host and regions" msgstr "コンフィギュレーション" @@ -13290,6 +13495,10 @@ msgid "" msgstr "" "着信HTTPリクエストから読み取るHTTPリクエストヘッダー変数の名前を構成します" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "単一インターフェースの検出を構成します" + #, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13319,18 +13528,6 @@ msgstr "" "たはグループを構成します。キーはプッシュオーバーのウェブサイトから入手できま" "す。" -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"通知プラグインが直接smtpサーバーに接続するように設定します。これはエラー発生" -"時により良いエラーメッセージを提供するという利点があります。しかし、より多く" -"の設定が必要であり、厳密な同期です。そのため、通知スプーラを使用する商用版の" -"インストール時のみ使用することをお勧めします。" - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -13709,6 +13906,10 @@ msgstr "連絡先" msgid "Contact Name" msgstr "連絡先" +#, fuzzy +msgid "Contact group" +msgstr "連絡先グループ" + msgid "Contact group (effective)" msgstr "連絡先グループ(有効)" @@ -13860,6 +14061,10 @@ msgstr "コンテキスト情報" msgid "Context information about this connection" msgstr "この接続に関するコンテキスト情報" +#, fuzzy +msgid "Context information about this parameter" +msgstr "このルールに関するコンテキスト情報" + msgid "Context information about this rule" msgstr "このルールに関するコンテキスト情報" @@ -14100,6 +14305,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase:キャッシュ" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -14381,6 +14591,10 @@ msgstr "この接続のコピーを作成します" msgid "Create a copy of this group" msgstr "このグループのコピーを作成します" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "この通知ルールのコピーを作成します" + msgid "Create a copy of this notification rule" msgstr "この通知ルールのコピーを作成します" @@ -14464,6 +14678,11 @@ msgstr "IO統計リクエスト用の追加サービスを作成する" msgid "Create additional service for system wait" msgstr "システム待機用の追加サービスを作成する" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "この期間の注釈を作成します" @@ -14572,6 +14791,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "このレポートの定期的なタイムスケジュールを作成します" +#, fuzzy +msgid "Create robot" +msgstr "ホストを作成する" + msgid "Create separate notification bulks based on" msgstr "に基づいて個別の通知バルクを作成する" @@ -14667,6 +14890,10 @@ msgstr "新しいホスト %s を作成しました。" msgid "Created new host tag group '%s'" msgstr "新しいホストタググループ '%s'を作成しました" +#, fuzzy +msgid "Created new notification parameter" +msgstr "新しい通知ルールを作成しました" + msgid "Created new notification rule" msgstr "新しい通知ルールを作成しました" @@ -15099,6 +15326,10 @@ msgstr "カスタムGUIデザイン %s" msgid "Custom Graph" msgstr "カスタムグラフ" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "テーブル上にHTMLセクションを追加する(例:タイトル、説明文...)" + msgid "Custom Icons" msgstr "カスタムアイコン" @@ -15202,6 +15433,14 @@ msgstr "カスタムローカリゼーション" msgid "Custom logos" msgstr "カスタムロゴ" +#, fuzzy +msgid "Custom macro" +msgstr "カスタマーマクロ" + +#, fuzzy +msgid "Custom macros" +msgstr "カスタマーマクロ" + #, python-format msgid "Custom notification table for user %s" msgstr "ユーザー %s のカスタム通知テーブル" @@ -15215,9 +15454,15 @@ msgstr "カスタムプローブの状態" msgid "Custom profile" msgstr "カスタムプロフィール" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "カスタム検索クエリ" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "カスタムサービス属性" @@ -16029,9 +16274,6 @@ msgstr "日割り" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "非アクティブ化" - msgid "Deactivated" msgstr "非アクティブ化" @@ -16315,6 +16557,9 @@ msgstr "デフォルトのユーザープロファイル" msgid "Default value" msgstr "デフォルト値" +msgid "Defaults to 'https' when not provided." +msgstr "" + msgid "Deferred files age" msgstr "遅延ファイルの経過時間" @@ -16365,6 +16610,9 @@ msgstr "" "MTreeの可能な状態から監視状態、つまりチェックの結果への変換を定義します。これ" "により、チェックで使用されるデフォルトのマッピングが上書きされます。" +msgid "Define any events you want to be notified about." +msgstr "" + msgid "Define host assignment" msgstr "ホスト割り当ての定義" @@ -16401,6 +16649,9 @@ msgstr "待機コンテナ数の下位レベルの定義" msgid "Define name of NetBIOS server" msgstr "NetBIOSサーバー名の定義" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -16640,6 +16891,10 @@ msgstr "バックアップキー #%dを削除" msgid "Delete comments" msgstr "コメント削除" +#, fuzzy +msgid "Delete comments?" +msgstr "コメント削除" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "デフォルト設定" @@ -16707,6 +16962,14 @@ msgstr "ジョブ#%dを削除" msgid "Delete last alert handler rule" msgstr "最後のアラートハンドラルールを削除する" +#, fuzzy +msgid "Delete managed robot" +msgstr "管理対象オブジェクト" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "通知ルール#%dを削除" + #, python-format msgid "Delete notification rule #%d" msgstr "通知ルール#%dを削除" @@ -16859,9 +17122,17 @@ msgstr "このキーを削除します" msgid "Delete this logo" msgstr "ロゴを削除します" +#, fuzzy +msgid "Delete this managed robot" +msgstr "このタググループを削除します" + msgid "Delete this metric" msgstr "このメトリックを削除します" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "この通知ルールを削除します" + msgid "Delete this notification rule" msgstr "この通知ルールを削除します" @@ -16959,6 +17230,10 @@ msgstr "フォルダ%sを削除" msgid "Deleted host %s" msgstr "削除されたホスト %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "通知ルール#%dを削除" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "通知ルール%d(ユーザー%sのルール)は削除されました" @@ -17807,6 +18082,10 @@ msgstr "プロキシ処理を無効にする" msgid "Disable remote configuration" msgstr "リモート構成を無効にする" +#, fuzzy +msgid "Disable rule" +msgstr "全てを無効化" + msgid "Disable service notifications" msgstr "サービス通知を無効にする" @@ -18167,9 +18446,6 @@ msgstr "" "LUNが読み取り専用でない場合は、警告を表示します。この設定がないと、LUNが読み" "取り専用の場合に警告が表示されます。" -msgid "Display additional information" -msgstr "追加情報の表示" - msgid "Display additional messages" msgstr "追加のメッセージを表示する" @@ -18192,9 +18468,6 @@ msgstr "選択された/自動データ範囲の軸ラベルを表示する" msgid "Display dashboard title" msgstr "ダッシュボードのタイトルを表示する" -msgid "Display graphs among each other" -msgstr "相互にグラフを表示する" - msgid "Display historic data since the last" msgstr "前回以降の履歴データを表示する" @@ -18997,6 +19270,10 @@ msgstr "ドキュメント数のデルタ" msgid "Document count growth per minute" msgstr "1分あたりのドキュメント数の増加" +#, fuzzy +msgid "Documentation" +msgstr "ドキュメントURL" + msgid "Documentation URL" msgstr "ドキュメントURL" @@ -19776,6 +20053,10 @@ msgstr "編集" msgid "Edit %s" msgstr "%sを編集する" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "通知ルール %d を編集する" + #, python-format msgid "Edit %s: %s" msgstr "%s を編集: %s" @@ -19922,6 +20203,10 @@ msgstr "レイアウトを編集する" msgid "Edit layout only available if header is enabled" msgstr "ヘッダーが有効な場合のみ、レイアウトの編集が可能" +#, fuzzy +msgid "Edit managed robots" +msgstr "管理対象オブジェクト" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "サイト接続 %sを編集する" @@ -20080,6 +20365,14 @@ msgstr "この要素を編集する" msgid "Edit this host" msgstr "このホストを編集する" +#, fuzzy +msgid "Edit this managed robot" +msgstr "管理状態" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "この通知ルールを編集する" + msgid "Edit this notification rule" msgstr "この通知ルールを編集する" @@ -20151,6 +20444,9 @@ msgstr "ユーザ %s のプロファイルを編集しました" msgid "Edition" msgstr "版" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "効果的な 状態" @@ -20332,6 +20628,14 @@ msgstr "アカウントの識別に使用されるEメールアドレス" msgid "Email addresses to mail PDF reports to" msgstr "PDFレポートの送付先メールアドレス" +#, fuzzy +msgid "Email body/content" +msgstr "送信済みメール" + +#, fuzzy +msgid "Email header" +msgstr "Eメールアドレス" + msgid "Email sent" msgstr "送信済みメール" @@ -21304,6 +21608,10 @@ msgstr "イベントコメント" msgid "Event console" msgstr "イベントコンソール" +#, fuzzy +msgid "Event console alerts" +msgstr "イベントコンソールアラート" + msgid "Event console performance" msgstr "イベントコンソールのパフォーマンス" @@ -22520,10 +22828,6 @@ msgstr "値のレンダリングに失敗しました:" msgid "Failed to render value: %r" msgstr "値のレンダリングに失敗しました: %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "ピア証明書のフェッチに失敗しました(%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "ルールセット '%s' ルの検索に失敗しましたフォルダ内 '%s' (%r): %s" @@ -22631,6 +22935,10 @@ msgstr "" "データを送信するのは1つのノードだけで、他のノードの結果は少なくともWARNING状" "態をトリガーします。" +#, fuzzy +msgid "Failure" +msgstr "失敗" + msgid "Failures of the join launcher service" msgstr "ジョインランチャーサービスの失敗" @@ -22924,6 +23232,10 @@ msgstr "以下のファイルサイズ" msgid "File size levels" msgstr "ファイルサイズレベル" +#, fuzzy +msgid "File upload" +msgstr "バイトアップロード済" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -23051,6 +23363,10 @@ msgstr "" "そのホストのステータス情報に基づいて、すべての集計をフィルタリングします。完" "全一致(正規表現なし)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "ホスト/サービスのダウンタイム" + msgid "Filter group (see help)" msgstr "フィルタグループ(ヘルプを参照)" @@ -23707,6 +24023,9 @@ msgstr "ネットワーク" msgid "Form factor" msgstr "フォーム ファクタ" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "フォーマット" @@ -24330,6 +24649,11 @@ msgstr "生成する" msgid "Generate REST API specification" msgstr "SLA仕様" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + #, fuzzy msgid "Generate backup codes" msgstr "バックアップコードを再作成する" @@ -24398,6 +24722,21 @@ msgstr "一般的なレート" msgid "Generic string" msgstr "一般的な文字列" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "カーネルバージョン" + +#, fuzzy +msgid "Gerrit connection" +msgstr "接続を編集する" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "クエリするJenkinsインスタンス。" + msgid "Get file from SFTP server" msgstr "SFTPサーバーからファイルを取得する" @@ -24454,6 +24793,10 @@ msgstr "グローバル通知ルール" msgid "Global notification rules" msgstr "グローバル通知ルール" +#, fuzzy +msgid "Global services" +msgstr "すべてのサービス" + msgid "Global services to monitor" msgstr "監視するグローバルサービス" @@ -24479,6 +24822,10 @@ msgstr "入力ファイルのグロブパターン" msgid "Go critical if all licenses are used" msgstr "すべてのライセンスが使用されている場合はクリティカルに変化します" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "すべてのホスト" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -24491,6 +24838,12 @@ msgstr "メインページに移動" msgid "Go to rules of this InfluxDB connection" msgstr "新しいInfluxDB接続のルールに移動する" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "Saasの管理パネルに移動する" @@ -24650,18 +25003,12 @@ msgstr "グラフィックカード" msgid "Graphs" msgstr "グラフ" -msgid "Graphs are shown among each other" -msgstr "グラフは相互に表示されます" - msgid "Graphs for averaged single-core utilizations" msgstr "シングルコア使用率の平均のグラフ" msgid "Graphs for individual cores" msgstr "個々のコアのグラフ" -msgid "Graphs per notification (default: 5)" -msgstr "通知ごとのグラフ(デフォルト: 5)" - msgid "Graylog" msgstr "Graylog" @@ -24750,10 +25097,6 @@ msgstr "グループベースDN" msgid "Group discovery and activation for up to" msgstr "最大でグループの検出とアクティブ化" -#, fuzzy -msgid "Group execution interval" -msgstr "実行間隔" - msgid "Group files based on a regular expression pattern." msgstr "正規表現パターンに基づいてファイルをグループ化します。" @@ -24953,6 +25296,10 @@ msgstr "REST API 4.xを介したHPE StoreOnce" msgid "HR: Used memory via SNMP" msgstr "HR: SNMP経由で使用されたメモリ" +#, fuzzy +msgid "HTML Email parameters" +msgstr "モデルパラメータ" + #, fuzzy msgid "HTML email" msgstr "HTML Eメール" @@ -26261,6 +26608,10 @@ msgstr "構成変数の名前を非表示にする" msgid "Hide notification bulks" msgstr "通知ルール" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "すべての受信者に個別の通知を送信" + msgid "Hide response from socket" msgstr "ソケットからの応答を非表示" @@ -26327,6 +26678,10 @@ msgstr "ヒストリー" msgid "History Line Number" msgstr "履歴行番号" +#, fuzzy +msgid "History action type" +msgstr "登録状態" + msgid "History entries of one specific event" msgstr "1つの特定のイベントの履歴エントリ" @@ -28002,10 +28357,6 @@ msgstr "ホストの概要" msgid "Host parent/child topology" msgstr "ホストの親/子トポロジ" -#, fuzzy -msgid "Host path" -msgstr "ホストアラート" - msgid "Host performance data" msgstr "ホストのパフォーマンスデータ" @@ -28708,6 +29059,10 @@ msgstr "IP - 範囲 - インスタンスID" msgid "IP Address" msgstr "IPアドレス" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "ホストのIPアドレス" + msgid "IP address" msgstr "IPアドレス" @@ -30624,19 +30979,6 @@ msgstr "" "きます。一致するネームスペースのみが監視されます。これは、たとえばPodなど、一" "致する名前空間の一部であるすべてに関係することに注意してください。" -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"警告

    フォールバックメールアドレスを設定して" -"おらず、どのユーザーに対してもフォールバックメールの受信を有効にしていませ" -"ん。監視によって通知ルールのいずれにも一致しない通知が生成された場合、通知は" -"送信されません。これを防ぐには、グローバル設定を構成するか、少なくとも1人の" -"ユーザーに対してフォールバック連絡先オプションを有効にしてください。" - msgid "Ignore" msgstr "無視する" @@ -31597,6 +31939,14 @@ msgstr "" msgid "Indexspace wasted" msgstr "インデックススペースが無駄になります" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"最後の一括検出が失敗したかどうか。一度失敗するとTrueが設定され、それ以降に検" +"出が成功すると解除されます。" + msgid "Indices" msgstr "インデックス" @@ -32256,6 +32606,10 @@ msgstr "無効な証明書" msgid "Invalid certificate file: %s" msgstr "無効な証明書ファイル: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "無効なパラメータ%r:%s" + msgid "Invalid check parameter" msgstr "チェックパラメータが無効です" @@ -35024,6 +35378,10 @@ msgstr "Linuxマルチパスインベントリ" msgid "Linux and Solaris Multipath Count" msgstr "LinuxおよびSolarisマルチパスカウント" +#, fuzzy +msgid "Linux bonding" +msgstr "Vswitchボンディング" + msgid "Linux bonding interface status" msgstr "Linuxボンディングインターフェースのステータス" @@ -35609,6 +35967,10 @@ msgstr "" "Checkmk agent controller registrationコマンドで受信したリクエストのエージェン" "ト登録処理を記録します。" +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "ホストの自動削除を有効化" + msgid "Log: Details" msgstr "ログ:詳細" @@ -36107,6 +36469,10 @@ msgstr "接続総数の下位レベル" msgid "Lower levels on the total number of clients pending on a blocking call" msgstr "ブロッキングコールで保留中のクライアントの総数の下位レベル" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "予想されるログファイルのリスト" + msgid "Lowest: No notification, update badge number" msgstr "最低: 通知なし、バッジ番号を更新" @@ -36671,10 +37037,25 @@ msgstr "監視システムのユーザーを管理します。" msgid "Managed Robot" msgstr "管理対象オブジェクト" +#, fuzzy +msgid "Managed Robots" +msgstr "管理対象オブジェクト" + #, fuzzy msgid "Managed objects" msgstr "管理対象オブジェクト" +#, fuzzy +msgid "Managed robot deleted." +msgstr "管理対象オブジェクト" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "管理対象オブジェクト" + msgid "Management board" msgstr "管理ボード" @@ -38218,14 +38599,14 @@ msgstr "1秒あたりの最小接続数" msgid "Minimum error count" msgstr "最小エラー数" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "電圧の最小レベル" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "負荷の最小レベル(パーセント)" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "電圧の最小レベル" + msgid "Minimum levels if using magic factor" msgstr "マジックファクターを使用する場合の最小レベル" @@ -38334,6 +38715,10 @@ msgstr "ミススケジュールされた期間(DaemonSetのみ)" msgid "Misscheduled replicas" msgstr "間違ってスケジュールされたレプリカ" +#, fuzzy +msgid "Missing catalog topic." +msgstr "変数siteidがありません" + #, python-format msgid "Missing config file for agent %s%s" msgstr "エージェント %s%s の構成ファイルがありません" @@ -39818,6 +40203,11 @@ msgstr "名前解決" msgid "Name your %s for easy recognition." msgstr "わかりやすいように%sに名前をつけます。" +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -39830,15 +40220,16 @@ msgstr "名前: %s" msgid "Names" msgstr "名前" +#, fuzzy msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" "Robot Frameworkの追加コマンドライン引数を含むファイルの名前。パスは " @@ -40251,6 +40642,29 @@ msgstr "次の通知" msgid "Next run" msgstr "次の実行" +#, fuzzy +msgid "Next step: General properties" +msgstr "一般的なプロパティ" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "通知プラグイン" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "受信者" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "保留中の接続" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "コメントタイプ(ホスト/サービス)" + msgid "Nginx Server" msgstr "Nginxサーバー" @@ -40266,6 +40680,10 @@ msgstr "軽快なIOレベル" msgid "No" msgstr "No" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "ホスト構成" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "いいえ(エラー: %s、コード: %d、深さ: %d)" @@ -40273,6 +40691,10 @@ msgstr "いいえ(エラー: %s、コード: %d、深さ: %d)" msgid "No API integrations, no Checkmk agent" msgstr "API統合なし、Checkmkエージェントなし" +#, fuzzy +msgid "No AWS services found." +msgstr "ホスト/サービスが見つかりません。" + msgid "No CSRF token received" msgstr "CSRFトークンを受信していない" @@ -40283,6 +40705,10 @@ msgstr "条件なし" msgid "No Configuration Quick setup for %s available" msgstr "構成変数:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "通知ルール %d を変更しました" + msgid "No IP" msgstr "IPなし" @@ -40360,10 +40786,6 @@ msgstr "このビューではコマンドは使用できません" msgid "No conditions" msgstr "条件なし" -#, fuzzy -msgid "No configuration yet" -msgstr "ホスト構成" - msgid "No configured rules are affected" msgstr "構成されたルールは影響を受けません" @@ -40417,6 +40839,14 @@ msgstr "利用可能な発見情報はありません。再スキャンを実行 msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "利用不可" + +#, fuzzy +msgid "No elements selected" +msgstr "選択されていない" + msgid "No entries" msgstr "エントリなし" @@ -40547,6 +40977,10 @@ msgstr "接続が定義されていません" msgid "No need for syncing sites" msgstr "サイト同期不要" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "通知ルール %d を変更しました" + msgid "No object type" msgstr "オブジェクトタイプなし" @@ -40557,6 +40991,10 @@ msgstr "パスワードが入力されていません。パスワードを入力 msgid "No password provided" msgstr "パスワードストアから" +#, fuzzy +msgid "No password selected" +msgstr "パスワードストアから" + msgid "No pending changes" msgstr "保留中の変更はありません" @@ -40634,6 +41072,10 @@ msgstr "検索なし" msgid "No search, specify list of arguments" msgstr "検索なし、引数のリストを指定" +#, fuzzy +msgid "No smarthosts" +msgstr "スマートホスト" + msgid "No snapshot to restore available." msgstr "復元可能なスナップショットはありません。" @@ -41084,6 +41526,9 @@ msgstr "通知" msgid "Notation: %s" msgstr "注釈: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -41248,6 +41693,18 @@ msgstr "通知ログレベル" msgid "Notification method" msgstr "通知方法" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "グラフコレクション '%s'は存在しません" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "通知プラグイン" + +#, fuzzy +msgid "Notification parameter" +msgstr "通知フェーズ" + #, fuzzy msgid "Notification period" msgstr "通知期間" @@ -41687,6 +42144,14 @@ msgstr "各レベルで作成するフォルダーの数" msgid "Number of goroutines" msgstr "再試行回数" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "通知ごとのグラフ(デフォルト: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "通知ごとのグラフ(デフォルト: 5)" + msgid "Number of healthy hosts lower levels" msgstr "正常なホストの数 下位レベル" @@ -42313,8 +42778,8 @@ msgid "OTLP endpoint" msgstr "エンドポイント" #, fuzzy -msgid "OVS bonding interface status" -msgstr "ボンディングインターフェース" +msgid "OVS bonding" +msgstr "Vswitchボンディング" msgid "Object" msgstr "オブジェクト" @@ -44333,6 +44798,10 @@ msgstr "現在の全体的なイベント" msgid "Overall latency" msgstr "全体的な遅延" +#, fuzzy +msgid "Overall response time" +msgstr "平均応答時間" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "仮想マシン(ESX VMなど)の全体的な状態" @@ -44389,7 +44858,7 @@ msgid "Override check state based on last build result" msgstr "最後のビルド結果に基づいてチェック状態をオーバーライドする" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "センサーのオーバーライドユニット" msgid "Override unit of sensor" @@ -44980,13 +45449,16 @@ msgstr "並列接続の負荷" msgid "Parallel pings to send" msgstr "送信する並列ping" -#, fuzzy -msgid "Parallel plan groups" -msgstr "実行スケジュール" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "コア構成の作成を並列化する" +#, fuzzy +msgid "Parameter" +msgstr "パラメーター" + msgid "Parameter groups" msgstr "パラメータグループ" @@ -44996,6 +45468,10 @@ msgstr "リージョンごとのパラメータグループ" msgid "Parameter name" msgstr "パラメータ名" +#, fuzzy +msgid "Parameter properties" +msgstr "パッケージのプロパティ" + msgid "Parameter rule set" msgstr "パラメータルールセット" @@ -45019,6 +45495,10 @@ msgstr "" "$
    $INST$ (ドルで囲まれている)でパラメーターの実際の値を挿入で" "きます。標識)。" +#, fuzzy +msgid "Parameters for" +msgstr "%sのパラメータ" + #, python-format msgid "Parameters for %s" msgstr "%sのパラメータ" @@ -45026,6 +45506,10 @@ msgstr "%sのパラメータ" msgid "Parameters for input phases of UPSs and PDUs" msgstr "UPSおよびPDUの入力フェーズのパラメーター" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "このホストのパラメーター" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "UPSおよびPDUの出力負荷のパラメーター" @@ -46062,6 +46546,10 @@ msgstr "通常のIPアドレスにpingを実行します" msgid "Ping timeout" msgstr "Pingタイムアウト" +#, fuzzy +msgid "Placeholder" +msgstr "プレースホルダーVM" + msgid "Placeholder VMs" msgstr "プレースホルダーVM" @@ -46112,6 +46600,10 @@ msgstr "" "プランID(アプリケーション名、スイート名、バリアントの組み合わせ)は一意でな" "ければならない。" +#, fuzzy +msgid "Plan settings" +msgstr "グローバル設定" + msgid "Plans" msgstr "Plans" @@ -46138,6 +46630,10 @@ msgstr "ビューに少なくとも1つの列を追加してください。" msgid "Please add at least one endpoint to monitor" msgstr "監視するエンドポイントを少なくとも1つ追加してください" +#, fuzzy +msgid "Please add at least one recipient" +msgstr "少なくとも1つの子ノードを追加してください。" + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -46195,6 +46691,10 @@ msgstr "有効なPNG画像を選択してください。" msgid "Please choose an audit log to view:" msgstr "アップロードするファイルを選択してください。" +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "スケジュールするレポートを選択してください" + #, fuzzy msgid "Please choose the check plug-in" msgstr "チェックプラグインを選択してください" @@ -46818,6 +47318,10 @@ msgstr "root以外のユーザー向けのプラグイン、ローカルチェ msgid "Plugin" msgstr "プラグイン" +#, fuzzy +msgid "Plugin output" +msgstr "プラグイン出力" + msgid "Plugins" msgstr "プラグイン" @@ -46958,6 +47462,10 @@ msgstr "正の一致(一致するホストをセットに追加)" msgid "Positive match (Add matching services to the set)" msgstr "ポジティブマッチ(マッチングサービスをセットに追加)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "正の一致(一致するホストをセットに追加)" + msgid "Postfix" msgstr "Postfix" @@ -47136,6 +47644,10 @@ msgstr "プレフィックスのテキスト" msgid "Prepare AWS for Checkmk" msgstr "Checkmkの初期化されたGIT" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "Checkmkの初期化されたGIT" + msgid "Prepend namespace prefix for hosts" msgstr "ホストの名前スペースプレフィックスを付加する" @@ -47786,14 +48298,14 @@ msgstr "Pythonバージョン" msgid "Python agent plug-in execution (UNIX)" msgstr "Pythonエージェントプラグインの実行(UNIX)" +#, fuzzy msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" "変数を読み込む Python または YAML ファイル。(not available because Robotmk Core MKP " +"has been installed)" msgstr "" "分離実行にはRCCを使用(Robotmk Core MKPがインストールされているので%s)" +#, fuzzy msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" "RCC profile configuration: RCCプロファイルは、例えばプロキシ設定など、特定の" "RCC環境の設定を定義することができる。
    " @@ -48651,6 +49165,10 @@ msgstr "受信者" msgid "Recipient email address" msgstr "受信者のメールアドレス" +#, fuzzy +msgid "Recipients" +msgstr "受信者" + #, python-format msgid "Recipients: %s" msgstr "受信者: %s" @@ -49147,6 +49665,10 @@ msgstr "残りのライフ" msgid "Remaining Open Slots" msgstr "残りの空きスロット" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "有効期間の残り日数" + msgid "Remaining credits lower levels" msgstr "残存単位数 下位レベル" @@ -49307,9 +49829,6 @@ msgstr "すべてのファイルとサブディレクトリを削除します" msgid "Remove downtimes" msgstr "ダウンタイムを除く" -msgid "Remove downtimes?" -msgstr "ダウンタイム削除しますか?" - msgid "Remove explicit attribute settings" msgstr "明示的な属性設定を削除する" @@ -49341,6 +49860,10 @@ msgstr "全ての予定されたダウンタイムを削除しますか?" msgid "Remove service" msgstr "サービスを削除する" +#, fuzzy +msgid "Remove smarthost" +msgstr "このエントリを移動する" + #, fuzzy msgid "Remove style" msgstr "すべて削除する" @@ -49919,6 +50442,10 @@ msgstr "" "バージョンv2.4.1以降を実行しているBazel Remote Cacheインスタンス・メトリク" "ス・エンドポイントからデータを要求します" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "jenkinsインスタンスからデータをリクエストします。" + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "jenkinsインスタンスからデータをリクエストします。" @@ -49963,6 +50490,10 @@ msgstr "必要なポート" msgid "Required context filters" msgstr "必要なコンテキストフィルター" +#, fuzzy +msgid "Required field missing" +msgstr "サイトがありません" + msgid "Required match (regular expression)" msgstr "必要な一致(正規表現)" @@ -50272,6 +50803,10 @@ msgstr "AWSタグで監視サービスを制限する" msgid "Restrict number of processed messages per cycle" msgstr "サイクルごとに処理されるメッセージの数を制限する" +#, fuzzy +msgid "Restrict previous options to" +msgstr "重大度を最悪の場合に制限する" + msgid "Restrict runtime of logfile parsing" msgstr "ログファイル解析の実行時間を制限する" @@ -50412,6 +50947,11 @@ msgid "" msgstr "" "WMI(Windows Management Instrumentation)を使用してプロセス情報を取得する" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "リトライ" @@ -50437,6 +50977,10 @@ msgstr "このテストを再試行してください" msgid "Retry time" msgstr "再試行時間" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "見つかった場合はクリティカルを返し、見つからなかった場合はOKを返します" + msgid "Return code class 2xx (success)" msgstr "リターンコードクラス 2xx(成功)" @@ -50454,7 +50998,12 @@ msgstr "パフォーマンスデータ内のプロセス時間を返す" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -50475,10 +51024,19 @@ msgstr "外国の変更を有効にする" msgid "Review and run preview service discovery" msgstr "サービスディスカバリの実行と保存" +#, fuzzy +msgid "Review and test configuration" +msgstr "リモート設定" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "サービスディスカバリの実行と保存" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "1分あたりの回転数" @@ -50531,6 +51089,10 @@ msgstr "ロボット・フレーム: %s" msgid "Robot Framework: Last log" msgstr "ロボットフレームワーク:最終ログ" +#, fuzzy +msgid "Robot package" +msgstr "パッケージの取り外し" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -51630,12 +52192,14 @@ msgstr "この集計のコピーを作成します" msgid "Save response" msgstr "応答を保存" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "このホストを保存して、行く" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "ホスト '%s'のチェック構成を %d サービスで保存しました" @@ -51686,9 +52250,6 @@ msgstr "ホストでのダウンタイムのスケジュール" msgid "Schedule downtime on service" msgstr "ホストでのダウンタイムのスケジュール" -msgid "Schedule downtime?" -msgstr "ダウンタイムをスケジュールしますか?" - msgid "Schedule downtimes" msgstr "ダウンタイムをスケジュールする" @@ -52050,6 +52611,10 @@ msgstr "文字列の送信と応答のポーリングの間に待機する秒数 msgid "Secret access key" msgstr "秘密鍵" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "秘密鍵" + msgid "Secret key" msgstr "秘密鍵" @@ -52221,6 +52786,15 @@ msgstr "PCからiCalendarファイル (*.ics) を選択します" msgid "Select and configure AWS services you would like to monitor" msgstr "監視するAzureサービス" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "監視するAzureサービス" + +#, fuzzy +msgid "Select contact group" +msgstr "ルール連絡先グループ" + #, fuzzy msgid "Select datasource" msgstr "データソースを選択" @@ -52427,6 +53001,10 @@ msgstr "固定ページ要素のタイプを選択します" msgid "Select type from list" msgstr "リストから個々のファイルを選択します" +#, fuzzy +msgid "Select user" +msgstr "ユーザーを削除" + msgid "Select view" msgstr "ビューを選択" @@ -52463,6 +53041,10 @@ msgstr "選択した %s が削除されました。" msgid "Selected credential has been deleted" msgstr "選択した資格情報は削除されました" +#, fuzzy +msgid "Selected options" +msgstr "拒否されたコネクション" + msgid "Selected sections will not be executed by the agent." msgstr "選択したセクションはエージェントによって実行されません。" @@ -52531,6 +53113,10 @@ msgstr "HTTP POSTデータを送信する" msgid "Send custom notification" msgstr "カスタム通知の送信" +#, fuzzy +msgid "Send custom notification?" +msgstr "カスタム通知の送信" + #, fuzzy msgid "Send data" msgstr "マップされたデータ" @@ -52575,9 +53161,7 @@ msgid "Send notifications to remote Event Console" msgstr "リモートイベントコンソールに通知を送信する" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "通知は、通知ルールに従って送信されます" msgid "" @@ -52585,10 +53169,6 @@ msgid "" "notifications (forced)" msgstr "通知期間や通知の無効化など、制限に関係なく送信する(強制)" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "すべての受信者に個別の通知を送信" - msgid "Send service metrics to Graphite" msgstr "サービスメトリックをGraphiteに送信する" @@ -52630,6 +53210,10 @@ msgstr "メールで送信" msgid "Sending Power" msgstr "送信力" +#, fuzzy +msgid "Sending conditions" +msgstr "条件を設定する" + msgid "Sending reply" msgstr "返信を送信する" @@ -52683,7 +53267,11 @@ msgid "September" msgstr "9月" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "実行間隔" + +#, fuzzy +msgid "Sequence of plans" msgstr "実行スケジュール" msgid "Serial" @@ -52920,6 +53508,10 @@ msgstr "サービス検出:サービスの説明" msgid "Service discovery: State" msgstr "サービスディスカバリ:状態" +#, fuzzy +msgid "Service events" +msgstr "サービスレベル" + msgid "Service goes into critical state" msgstr "サービスがクリティカル状態になります" @@ -53251,6 +53843,10 @@ msgstr "サイトのサービス" msgid "Services per cluster" msgstr "クラスターごとのサービス" +#, fuzzy +msgid "Services per region" +msgstr "監視する地域ごとのサービス" + msgid "Services per region to monitor" msgstr "監視する地域ごとのサービス" @@ -53766,7 +54362,7 @@ msgstr "通知に表示されるグラフの数の制限を設定します。" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -54130,6 +54726,10 @@ msgstr "チェックボックスを表示する" msgid "Show column headings" msgstr "列見出しを表示する" +#, fuzzy +msgid "Show contact groups" +msgstr "ホストの連絡先グループ" + msgid "Show context" msgstr "コンテキストを表示" @@ -54197,9 +54797,17 @@ msgstr "ユーザー' メニューにヒントを表示する" msgid "Show historic values" msgstr "歴史的価値観を示す" +#, fuzzy +msgid "Show host labels" +msgstr "ホストテーブルに表示" + msgid "Show host status" msgstr "ホストステータスを表示する" +#, fuzzy +msgid "Show host tags" +msgstr "ホストステータスを表示する" + msgid "Show icon linking to Setup parameter editor for services" msgstr "サービスのセットアップパラメータエディタにリンクするアイコンを表示する" @@ -54274,6 +54882,10 @@ msgstr "もっと表示/少なく表示" msgid "Show notification bulks" msgstr "通知ルール" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "一括通知の通知の並べ替え順序" + msgid "Show number of groups" msgstr "グループの数を表示する" @@ -54338,6 +54950,10 @@ msgstr "この %s を使用してルールを表示する" msgid "Show separate result for each SLA period" msgstr "SLA期間ごとに個別の結果を表示する" +#, fuzzy +msgid "Show service labels" +msgstr "サービスラベル" + #, fuzzy msgid "Show service name" msgstr "サービス名" @@ -54716,6 +55332,11 @@ msgstr "" "す)。ここでノードを指定することにより、この自動化をオーバーライドすることが" "できます。" +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -55631,6 +56252,10 @@ msgstr "特定のオブジェクト" msgid "Specific sites" msgstr "特定のサイト" +#, fuzzy +msgid "Specific users" +msgstr "特定のサイト" + msgid "Specific version" msgstr "特定のバージョン" @@ -55652,16 +56277,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "デフォルトの線種を指定します" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" -"スケジューラがロボットフレームワークの実行を許可する最大時間を指定する。この" -"時間は、繰り返し実行の回数を乗じて、このグループ内の他のすべての計画と合計し" -"て、グループ実行間隔より大きくなってはならない。" - msgid "Specifies whether password authentication is allowed" msgstr "パスワード認証を許可するかどうかを指定します" @@ -55823,17 +56438,6 @@ msgstr "" "\\checkmk\\agent\\robotmk_output\\working\\suites\\ ' )を、一定時間後または一" "定回数のテスト実行後にクリーンアップするかどうかを指定します。" -#, fuzzy -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" -"ターゲットホスト上のRobotmkの作業ディレクトリ(デフォルトは ' C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites\\ ' )を、一定時間後または一" -"定回数のテスト実行後にクリーンアップするかどうかを指定します。" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -56240,6 +56844,11 @@ msgid "" "retrieved." msgstr "選択したグラフがない、または取得できない場合の対処方法を指定します。" +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "検出しないポートタイプを指定します" @@ -56462,6 +57071,10 @@ msgstr "来年の始まり" msgid "Start or end of a scheduled downtime" msgstr "スケジュールされたダウンタイムの開始または終了" +#, fuzzy +msgid "Start or end of downtime" +msgstr "ダウンタイムの開始" + msgid "Start or end of flapping state" msgstr "フラッピング状態の開始または終了" @@ -56686,6 +57299,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "予想される文字列の不一致の状態" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "予期しないアクティブなインターフェイスについて警告する" + +#, fuzzy +msgid "State found during service discovery" +msgstr "保留中のサービス検出" + msgid "State if 'maintenance' services are found" msgstr "\"メンテナンス\"サービスが見つかった場合の状態" @@ -57696,10 +58317,12 @@ msgstr "セクション名" msgid "Subject for bulk notifications" msgstr "一括通知の対象" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "ホスト通知の対象" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "サービス通知の対象" msgid "Submit" @@ -58093,6 +58716,10 @@ msgstr "同期" msgid "Syncing" msgstr "同期" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "SAPルーター証明書" + msgid "Synology Updates" msgstr "Synologyの更新" @@ -58376,6 +59003,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLSなしでの認証は不可" +#, fuzzy +msgid "TLS certificate verification" +msgstr "SSL証明書の検証" + #, fuzzy msgid "TLS processed bytes" msgstr "TLS処理されたバイト" @@ -58590,6 +59221,16 @@ msgstr "" msgid "Tags can be used to classify hosts and services in a flexible way." msgstr "タグを使用して、ホストとサービスを柔軟に分類できます。" +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "データソースが定義されていません。" + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "アラートのタグ。" @@ -58826,6 +59467,10 @@ msgstr "ルールセットに対して自分で定義した通知をテストす msgid "Test authentication" msgstr "テスト認証" +#, fuzzy +msgid "Test configuration" +msgstr "ホスト構成" + #, fuzzy msgid "Test connection" msgstr "この接続" @@ -58859,6 +59504,9 @@ msgstr "最終通知" msgid "Test runtime" msgstr "テストランタイム" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + msgid "Test verification" msgstr "テスト検証" @@ -60032,6 +60680,10 @@ msgstr "" msgid "The central (%s) and remote site (%s) are not compatible. Reason: %s" msgstr "セントラル(%s)は、リモートサイト(%s)と互換性がありません。理由: %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "アクティベートされたことがない" + #, python-format msgid "The character %s is not allowed here." msgstr "ここでは、文字%s は使用できません。" @@ -60306,6 +60958,11 @@ msgstr "" "コネクションはこの特定のフォルダにホストを作成します。一度作成されたホストは" "別のフォルダに移動することができます。" +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "このサイトへの接続は無効になっています。" @@ -60555,23 +61212,6 @@ msgstr "ダッシュボードに要素が見つかりません。" msgid "The element does not exist." msgstr "エレメントが存在しません。" -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"通知メッセージのFromヘッダーで使用されるメールアドレスと表示名。メールアドレ" -"スが指定されていない場合、デフォルトのアドレスは OMD_SITE @ FQDN が" -"使用されます。環境変数 OMD_SITE が設定されていない場合、デフォルトで" -" checkmk になります。" - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"通知メッセージのReply-Toヘッダーで使用される電子メールアドレスと表示名。" - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -60916,15 +61556,6 @@ msgstr "グラフの仕様がありません" msgid "The graph template id '%s' is disabled" msgstr "グラフテンプレートID' %s 'は無効です" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" -"グループの実行間隔は、個々のプランの実行時間制限の合計よりも大きくなければな" -"りません。計画の実行時間制限は以下のように計算されます: limit_per_attempt x " -"(1 + max_number_of_reexecutions)." - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -61151,16 +61782,6 @@ msgstr "" "インスタンス名、データベース名、テーブルスペース名の組み合わせは以下のように" "なります。 db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" -"実行グループが実行される間隔。この間隔は、個々の計画の実行時間制限の合計より" -"も大きくなければなりません。プランの実行時間制限は以下のように計算される:" -"limit_per_attempt x (1 + max_number_of_reexecutions)" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -61519,6 +62140,16 @@ msgstr "" "このサービスが警告/危機に陥るまでの往復時間の最大標準偏差(単位:ms)。この" "アラームはターゲットホストにのみ適用され、その間のホップには適用されません。" +#, fuzzy +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" +"スケジューラがロボットフレームワークの実行を許可する最大時間を指定する。この" +"時間は、繰り返し実行の回数を乗じて、このグループ内の他のすべての計画と合計し" +"て、グループ実行間隔より大きくなってはならない。" + msgid "The maximum value length is 256 characters." msgstr "最大値の長さは256文字です。" @@ -63146,6 +63777,28 @@ msgid "" msgstr "" "wait_duration_msのしきい値。上記で設定したデフォルトの状態を上書きします。" +#, fuzzy +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" +"実行グループが実行される間隔。この間隔は、個々の計画の実行時間制限の合計より" +"も大きくなければなりません。プランの実行時間制限は以下のように計算される:" +"limit_per_attempt x (1 + max_number_of_reexecutions)" + +#, fuzzy +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" +"実行グループが実行される間隔。この間隔は、個々の計画の実行時間制限の合計より" +"も大きくなければなりません。プランの実行時間制限は以下のように計算される:" +"limit_per_attempt x (1 + max_number_of_reexecutions)" + msgid "The time interval statistical data is saved to disk" msgstr "時間間隔の統計データはディスクに保存されます" @@ -63299,6 +63952,14 @@ msgstr "ログイン用のユーザー。" msgid "The username returned by the %s connector is not of type string (%r)." msgstr "%sコネクタによって返されるユーザー名は文字列(%r)タイプではありません。" +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"GraylogAPIへのアクセスに使用する必要があるユーザー名。少なくとも読み取り権限" +"が必要です。" + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -63591,8 +64252,8 @@ msgstr "復元するセットアップのスナップショットはありませ msgid "There is no backup job configured" msgstr "構成されたバックアップジョブはありません" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "idが \"%s\" のグラフテンプレートはありません" msgid "There is no manpage for this check." @@ -63757,10 +64418,11 @@ msgstr "これらのノードは、凍結されたアグリゲーションに含 msgid "These nodes are only in the frozen aggregation" msgstr "これらのノードは、凍結されたアグリゲーションにのみ含まれる" +#, fuzzy msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" "これらのオプションは、Robot Frameworkの最も一般的なコマンドラインパラメータを" "指定します。他のパラメータを使うには、\"引数ファイル\" オプションを使います" @@ -64073,6 +64735,9 @@ msgstr "" "トのエージェントコントローラもリセットする必要があります。'cmk-agent-ctl " "help' を参照してください)" +msgid "This action will affect all pending changes you have made." +msgstr "" + #, fuzzy msgid "" "This active check sends out special emails to a defined mail address using " @@ -64785,7 +65450,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -65586,8 +66251,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "この権限を持つユーザーは他のユーザーを別の接続に移行することができます" msgid "" @@ -66170,13 +66834,6 @@ msgstr "" "トリが頻繁に変更され、一時ファイルシステムがすぐにいっぱいになる可能性があり" "ます。" -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"このルールにより、vSphereAPIを介したVMwareESXの監視が可能になります。ここで接" -"続設定を構成できます。" - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -66823,15 +67480,6 @@ msgstr "" "このルールセットは、通常のCheckmkエージェントの代わりにNetAppの特別なエージェ" "ントを選択し、NetApp Ontap REST APIによる監視が可能になります。" -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"このルールセットは、通常のCheckmkエージェントの代わりにHPE StoreOnce " -"Applaincesの特別なエージェントを選択し、REST API v4.x 以降を介した監視を可能" -"にします。 " - msgid "" "This rule sets limits to the current number of connections through a Check " "Point firewall." @@ -71584,9 +72232,16 @@ msgstr "ベータ期間中の試用時間は未定" msgid "Tried to register incompatible rulespec: %r" msgstr "互換性のないrulespecを登録しようとしました: %r" +#, fuzzy +msgid "Triggering events" +msgstr "イベントのアーカイブ" + msgid "Trivial change" msgstr "ささいな変更" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -72770,6 +73425,14 @@ msgstr "応答をアップロード" msgid "Upload verification response file" msgstr "検証回答ファイルのアップロード" +#, fuzzy +msgid "Uploaded" +msgstr "アップロード" + +#, fuzzy +msgid "Uploaded by" +msgstr "キーをアップロード" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "カスタムGUIロゴをアップロード: %s" @@ -74126,6 +74789,10 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">グローバルルールのイ" "ベント制限 event limit
    を上書きできます" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "このオプションを使用して、標準ポート443とは異なるポートを照会します。" + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "このオプションを使用して、標準ポート443とは異なるポートを照会します。" @@ -74159,6 +74826,14 @@ msgstr "" "バック)。このチェックでは、応答を送信した最初のホストからのデータのみが出力さ" "れます。" +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"このオプションを使用して、スペシャルエージェントによりチェックされるべきイン" +"スタンスを設定します。ここにホスト名を追加してください(例:my_graylog.com)。" + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -74547,7 +75222,8 @@ msgstr "ユーザ―メッセージ" msgid "User name" msgstr "ユーザー名" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "ストレージシステム上のユーザー名。読取専用の権限で十分です。" msgid "User notification" @@ -74638,6 +75314,10 @@ msgstr "Active Directoryに登録されたユーザー" msgid "Users listed here are still allowed to modify things." msgstr "ここにリストされているユーザーは、引き続き変更することができます。" +#, fuzzy +msgid "Users of contact groups" +msgstr "コンタクトグループのメンバー" + msgid "Users using a cifs share" msgstr "cifs共有を使用しているユーザー" @@ -75673,6 +76353,10 @@ msgstr "証明書の検証" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "証明書エラーを無視する(安全でない)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "証明書エラーを無視する(安全でない)" + msgid "Verify certificates" msgstr "証明書を確認する" @@ -75734,6 +76418,9 @@ msgstr "PKI アプライアンスのバージョン" msgid "Version of Server" msgstr "サーバーのバージョン" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "バージョン: %s" @@ -76190,6 +76877,10 @@ msgstr "接続を待機しています" msgid "Waiting containers" msgstr "待機中コンテナ" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Netappポートの検出" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -76571,6 +77262,9 @@ msgstr "どんな機会ですか?" msgid "What is the purpose?" msgstr "目的は何ですか?" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -77561,6 +78255,10 @@ msgstr "" msgid "Who" msgstr "WHO" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "ユーザーがこの通知を非アクティブ化できるようにする" + msgid "WiFi connection types" msgstr "WiFi接続タイプ" @@ -77718,9 +78416,10 @@ msgid "" "With authentication type set to 'OAuth2' the option '%s' must be specified." msgstr "" +#, fuzzy msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -78032,6 +78731,13 @@ msgstr "" "ことを意味します。これは混乱を招く可能性があります。このルールは、" "初期段階でのみ構成する必要があります。" +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -78932,6 +79638,14 @@ msgstr "ローカルサイトへの接続を削除することはできません msgid "You can not delete this %s because it is in use." msgstr "この %s を削除することはできません。使用中です。" +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"このターゲットはこれらのバックアップジョブで使用されているため、削除できませ" +"ん: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -79704,6 +80418,10 @@ msgstr "" "エージェントの署名キーをまだ作成していませ" "ん。これは必須です。" +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "このホストのパラメーター" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -81621,9 +82339,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "モニター" - msgid "month" msgstr "月" @@ -82538,6 +83253,9 @@ msgstr "{actual}%s が高すぎます。最大許容値は {bound}です。" msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual}が低すぎます。最小許容値は {bound} です。" +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -82546,6 +83264,150 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. All Rights Reserved." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "" +"分離実行にはRCCを使用(Robotmk Core MKPがインストールされているので%s)" + +#, fuzzy +#~ msgid "" +#~ "Specify here whether the working directory of Robotmk (`C:\\ProgramData" +#~ "\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " +#~ "should be cleaned up either after a certain time or after a certain " +#~ "number of test executions." +#~ msgstr "" +#~ "ターゲットホスト上のRobotmkの作業ディレクトリ(デフォルトは ' C:" +#~ "\\ProgramData\\checkmk\\agent\\robotmk_output\\working\\suites\\ ' )を、一" +#~ "定時間後または一定回数のテスト実行後にクリーンアップするかどうかを指定しま" +#~ "す。" + +#~ msgid "API key from password store" +#~ msgstr "パスワードストアのAPIキー" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "ホストアラート" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "ピア証明書のフェッチに失敗しました(%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "警告

    フォールバックメールアドレスを設定し" +#~ "ておらず、どのユーザーに対してもフォールバックメールの受信を有効にしていま" +#~ "せん。監視によって通知ルールのいずれにも一致しない通知が生成された場合、通" +#~ "知は送信されません。これを防ぐには、グローバル設定を構成するか、少なくとも" +#~ "1人のユーザーに対してフォールバック連絡先オプションを有効にしてください。" + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "グラフ付きの一括通知(デフォルト: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "デフォルトでは、電子メール内のすべての複数のグラフが近くに浮かんで表示され" +#~ "ます。このオプションを有効にすると、グラフを相互に表示できます。" + +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "通知プラグインが直接smtpサーバーに接続するように設定します。これはエラー発" +#~ "生時により良いエラーメッセージを提供するという利点があります。しかし、より" +#~ "多くの設定が必要であり、厳密な同期です。そのため、通知スプーラを使用する商" +#~ "用版のインストール時のみ使用することをお勧めします。" + +#~ msgid "Display additional information" +#~ msgstr "追加情報の表示" + +#~ msgid "Display graphs among each other" +#~ msgstr "相互にグラフを表示する" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "グラフは相互に表示されます" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "通知メッセージのFromヘッダーで使用されるメールアドレスと表示名。メールアド" +#~ "レスが指定されていない場合、デフォルトのアドレスは OMD_SITE @ FQDN が使用されます。環境変数 OMD_SITE が設定されていない場合、デ" +#~ "フォルトで checkmk になります。" + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "通知メッセージのReply-Toヘッダーで使用される電子メールアドレスと表示名。" + +#~ msgid "Activate" +#~ msgstr "アクティベート" + +#~ msgid "Deactivate" +#~ msgstr "非アクティブ化" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "このルールにより、vSphereAPIを介したVMwareESXの監視が可能になります。ここ" +#~ "で接続設定を構成できます。" + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "このルールセットは、通常のCheckmkエージェントの代わりにHPE StoreOnce " +#~ "Applaincesの特別なエージェントを選択し、REST API v4.x 以降を介した監視を可" +#~ "能にします。 " + +#~ msgid "monitor" +#~ msgstr "モニター" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "ストレージアカウント名" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "実行スケジュール" + +#~ msgid "" +#~ "The group execution interval must be greater than the sum of the " +#~ "individual plan runtime limits. The runtime limit of a plan is calculated " +#~ "as follows: limit_per_attempt x (1 + max_number_of_reexecutions)." +#~ msgstr "" +#~ "グループの実行間隔は、個々のプランの実行時間制限の合計よりも大きくなければ" +#~ "なりません。計画の実行時間制限は以下のように計算されます: " +#~ "limit_per_attempt x (1 + max_number_of_reexecutions)." + +#~ msgid "(not supported)" +#~ msgstr "(サポートされていません)" + +#~ msgid "Remove downtimes?" +#~ msgstr "ダウンタイム削除しますか?" + +#~ msgid "Schedule downtime?" +#~ msgstr "ダウンタイムをスケジュールしますか?" + +#, fuzzy +#~ msgid "OVS bonding interface status" +#~ msgstr "ボンディングインターフェース" + #~ msgid "Common Name" #~ msgstr "コモンネーム" @@ -82642,9 +83504,6 @@ msgstr "© %s Checkmk GmbH. All Rights Reserved." #~ msgid "Database for PostgreSQL" #~ msgstr "PostgreSQL用データベース" -#~ msgid " to get notified once the commercial release is available. " -#~ msgstr " 商業リリースが可能になり次第、通知を受け取る。 " - #~ msgid "Checkmk Cloud (SaaS) Beta" #~ msgstr "Checkmk Cloud (SaaS) Beta" @@ -82681,10 +83540,6 @@ msgstr "© %s Checkmk GmbH. All Rights Reserved." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "使用済みクォータ: 絶対または相対的な上位レベル" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "アクティベートされたことがない" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "テーブルスペース" @@ -82971,10 +83826,6 @@ msgstr "© %s Checkmk GmbH. All Rights Reserved." #~ msgid "%s operations" #~ msgstr "%s操作" -#, python-format -#~ msgid "%s requests" -#~ msgstr "%s リクエスト" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -83305,9 +84156,6 @@ msgstr "© %s Checkmk GmbH. All Rights Reserved." #~ msgid "InfluxDB Queue Usage" #~ msgstr "InfluxDBキューの使用状況" -#~ msgid "Kernel Version" -#~ msgstr "カーネルバージョン" - #~ msgid "Levels Helper usage Check" #~ msgstr "レベルヘルパーの使用状況チェック" diff --git a/locale/nl/LC_MESSAGES/multisite.po b/locale/nl/LC_MESSAGES/multisite.po index 8702474983e..e0d99913402 100644 --- a/locale/nl/LC_MESSAGES/multisite.po +++ b/locale/nl/LC_MESSAGES/multisite.po @@ -407,6 +407,10 @@ msgstr "%d dagen" msgid "%d days ago" msgstr "%d dagen geleden" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Algemene eigenschappen" + #, python-format msgid "%d errors occured:" msgstr "%d foutmeldingen:" @@ -569,6 +573,10 @@ msgstr "%s door host" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -689,6 +697,10 @@ msgstr "%s ratio" msgid "%s resulting notifications" msgstr "Resulterende kennisgevingen" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s Verzoeken" + #, python-format msgid "%s running for %s" msgstr "%s loopt gedurende %s" @@ -801,9 +813,17 @@ msgid "" "configuration tracking in setup." msgstr "" +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Verwijderde items" + msgid "(0 is current period)" msgstr "(0 is huidige periode)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(geen invoer)" + #, fuzzy msgid "(Edit presets)" msgstr "Rapporten bewerken" @@ -881,9 +901,6 @@ msgstr "(geen titel)" msgid "(none)" msgstr "(geen)" -msgid "(not supported)" -msgstr "(niet ondersteund)" - msgid "(nothing selected)" msgstr "(niets geselecteerd)" @@ -991,6 +1008,10 @@ msgstr "1 wijziging" msgid "1 row" msgstr "1 rij" +#, fuzzy +msgid "1 rule" +msgstr "regel" + msgid "1 year" msgstr "1 jaar" @@ -1188,6 +1209,31 @@ msgstr "95ste percentiel" msgid "99th percentile" msgstr "99e percentiel" +#, fuzzy +msgid "< Remove" +msgstr "Verwijder" + +#, fuzzy +msgid "<< Remove all" +msgstr "Verwijder alle" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Piggybacktranslationsworden uitgevoerd voordat de piggyback connector hosts aanmaakt. Gebruik " +"dit bijvoorbeeld in een setup met meerdere Docker nodes om containers te " +"prefixen met de naam van de corresponderende Docker node. Anders kunnen " +"naambotsingen optreden als containers met dezelfde naam op meer dan één " +"Docker Node bestaan." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Note3: Om deze plugin op Solaris te implementeren, is een " @@ -1351,6 +1397,12 @@ msgstr "" msgid "You do not have any roles." msgstr "U heeft geen rollen." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1937,7 +1989,7 @@ msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" #, python-format @@ -2115,6 +2167,14 @@ msgstr "Een rubriek voor de grafieken" msgid "A heading for the view" msgstr "Een rubriek voor het uitzicht" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Een host met de naam %s bestaat al in de map
    " +"%s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Toevoegen %s" + msgid "Add Aggregation" msgstr "Aggregatie toevoegen" @@ -3628,9 +3705,6 @@ msgstr "Uitzondering toevoegen" msgid "Add Group" msgstr "Groep toevoegen" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "HTML-sectie boven tabel toevoegen (bijv. titel, beschrijving...)" - msgid "Add LDAP connection" msgstr "LDAP-verbinding toevoegen" @@ -3676,6 +3750,9 @@ msgstr "Toevoegen aggregatie" msgid "Add alert handler rule" msgstr "Waarschuwings afhandeling regel toevoegen" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Voeg alle gedetecteerde maar nog niet bewaakte diensten toe aan de bewaking." @@ -3778,6 +3855,10 @@ msgstr "Voeg element toe: %s" msgid "Add elements to your sidebar" msgstr "Voeg elementen toe aan uw zijbalk" +#, fuzzy +msgid "Add event" +msgstr "Element toevoegen" + msgid "Add exception" msgstr "Uitzondering toevoegen" @@ -3968,6 +4049,10 @@ msgstr "Voeg tag voorwaarde toe" msgid "Add new pattern" msgstr "Nieuw patroon toevoegen" +#, fuzzy +msgid "Add new plan" +msgstr "Nieuw patroon toevoegen" + msgid "Add new project" msgstr "Nieuw project toevoegen" @@ -3983,10 +4068,18 @@ msgstr "Nieuwe regel toevoegen" msgid "Add new scalar" msgstr "Nieuwe scalair toevoegen" +#, fuzzy +msgid "Add new sequence" +msgstr "Nieuwe dienst toevoegen" + #, fuzzy msgid "Add new service" msgstr "Nieuwe dienst toevoegen" +#, fuzzy +msgid "Add new smarthost" +msgstr "Nieuwe macro toevoegen" + msgid "Add new status" msgstr "Nieuwe status toevoegen" @@ -4029,6 +4122,10 @@ msgstr "Uitvoerbare bestanden toevoegen of wijzigen" msgid "Add page element" msgstr "Pagina-element toevoegen" +#, fuzzy +msgid "Add parameter" +msgstr "Modelparameters" + msgid "Add pattern" msgstr "Patroon toevoegen" @@ -4054,6 +4151,10 @@ msgstr "Voeg pre of postfix toe aan TNSALIASes %s" msgid "Add random hosts" msgstr "Voeg willekeurige hosts toe" +#, fuzzy +msgid "Add recipient" +msgstr "Ontvanger" + msgid "Add remote instance" msgstr "Externe instantie toevoegen" @@ -4301,6 +4402,10 @@ msgstr "Extra IPv6-adressen" msgid "Additional agent labels to send during registration" msgstr "Extra agent labels te sturen tijdens de registratie" +#, fuzzy +msgid "Additional details" +msgstr "Extra opties" + msgid "Additional header lines" msgstr "Extra kopregels" @@ -4433,7 +4538,7 @@ msgid "Admin states to discover" msgstr "Admin staten te ontdekken" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "Administratieve staten" msgid "Administrative port states to discover" @@ -5117,6 +5222,10 @@ msgstr "Alert handler zijn geconfigureerd om alle controles uit te voeren." msgid "Alert handler configuration" msgstr "Configuratie van de alarm-handler" +#, fuzzy +msgid "Alert handler execution" +msgstr "Uitvoering van waarschuwingshandlers" + msgid "Alert handler execution, failed" msgstr "Waarschuwings handler uitvoering, mislukt" @@ -5231,6 +5340,15 @@ msgstr "Waarschuwingsstatistieken: Aantal onbekende waarschuwingen" msgid "Alert statistics: Number of warnings" msgstr "Waarschuwingsstatistieken: Aantal waarschuwingen" +msgid "Alert when a major version release is available" +msgstr "" + +msgid "Alert when a minor version release is available" +msgstr "" + +msgid "Alert when a patch version release is available" +msgstr "" + msgid "Alerted" msgstr "Alerted" @@ -5338,6 +5456,10 @@ msgstr "Alle collecties" msgid "All components" msgstr "Alle onderdelen" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Alle contacten van het aangemelde object" + msgid "All contacts of the notified object" msgstr "Alle contacten van het aangemelde object" @@ -5765,6 +5887,10 @@ msgstr "Toestaan om het icoon %s te zien in de host en service views" msgid "Allow unencrypted legacy communication" msgstr "Sta onversleutelde legacy communicatie toe" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "gebruikers in staat stellen deze melding te deactiveren" + msgid "Allowed Ciphers" msgstr "Toegestane cijfers" @@ -6374,6 +6500,10 @@ msgstr "Een andere gebruikerssynchronisatie is al bezig: %s" msgid "AntiVirus last update age" msgstr "AntiVirus laatste update leeftijd" +#, fuzzy +msgid "Any" +msgstr "elke" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6554,9 +6684,21 @@ msgstr "Overzicht toepassingen" msgid "Applications, Processes & Services" msgstr "Toepassingen, processen en diensten" +#, fuzzy +msgid "Applied to" +msgstr "Solliciteer naar" + msgid "Apply" msgstr "Solliciteer" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Waarschuwings afhandeling regel" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Verwijder deze meldingsregel" + #, fuzzy msgid "Apply Latency" msgstr "Latency" @@ -6580,6 +6722,11 @@ msgstr "Voorwaarden toepassen" msgid "Apply filters" msgstr "Filters toepassen" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Breng Eindtijd aan" @@ -6716,6 +6863,10 @@ msgstr "Ontvang remote audit logs" msgid "Archive event" msgstr "Archief evenement" +#, fuzzy +msgid "Archive event?" +msgstr "Archief evenement" + msgid "Archive events" msgstr "Archief gebeurtenissen" @@ -6842,6 +6993,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Hostname vertaling voor piggybacked hosts" @@ -7286,10 +7442,10 @@ msgstr "Auto-uitbreidbaar" msgid "Automated environment setup (via RCC)" msgstr "" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Gebruik SSL voor de verbinding." msgid "Automatic" @@ -8653,6 +8809,10 @@ msgstr "Gebakken agenten" msgid "Baked host specific agent" msgstr "Gebakken gastheer-specifiek middel" +#, fuzzy +msgid "Bakery rules" +msgstr "Ontdekking regels" + msgid "Baking Agents..." msgstr "Bakmiddelen..." @@ -9193,8 +9353,9 @@ msgstr "Bulk host import" msgid "Bulk move" msgstr "Bulk verplaatsing" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Bulk meldingen met grafieken (standaard: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Open bulk meldingen" msgid "Bulk removal of explicit attributes" msgstr "Bulk verwijderen van expliciete attributen" @@ -9560,13 +9721,6 @@ msgstr "" "via SNMP v1/v2. Deze regel kan worden gebruikt om de credentials aan te " "passen die moeten worden gebruikt bij het contacteren van hosts via SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Standaard worden alle meervoudige grafieken in emails zwevend naast elkaar " -"getoond. U kunt deze optie aanzetten om de grafieken onder elkaar te tonen." - msgid "By default all of the sections will be executed." msgstr "Standaard zullen alle secties worden uitgevoerd." @@ -9752,14 +9906,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" msgid "" @@ -9768,7 +9922,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" msgid "" @@ -10037,8 +10191,8 @@ msgstr "Alle grafieken voor een bepaalde host." msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11287,6 +11441,10 @@ msgstr "Gewijzigde LDAP-verbinding %s" msgid "Changed alert handler rule %d" msgstr "Waarschuwings afhandel regel %d veranderd" +#, fuzzy +msgid "Changed by" +msgstr "Gewijzigd" + msgid "Changed entries" msgstr "Gewijzigde ingangen" @@ -11302,6 +11460,14 @@ msgstr[1] "Gewijzigde host labels: " msgid "Changed host selection has been saved." msgstr "De gewijzigde hostselectie is opgeslagen." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Gewijzigde meldingsregel %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Gewijzigde meldingsregel %d" + #, python-format msgid "Changed notification rule %d" msgstr "Gewijzigde meldingsregel %d" @@ -11321,6 +11487,10 @@ msgstr "Veranderde positie van %s %d" msgid "Changed position of connection %s to %d" msgstr "Positie van verbinding %s gewijzigd in %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "Gewijzigde positie van meldingsregel %d van gebruiker %s" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "Gewijzigde positie van meldingsregel %d van gebruiker %s" @@ -11377,6 +11547,10 @@ msgstr "Locatie specifieke configuratie variabele %s veranderd in %s." msgid "Changes" msgstr "Wijzigingen" +#, fuzzy +msgid "Changes activated" +msgstr "Is nooit geactiveerd geweest" + msgid "Changes since last dump" msgstr "Veranderingen sinds de laatste dump" @@ -12687,6 +12861,11 @@ msgstr "Klik hier om de activeringsstatus per site te zien." msgid "Click on 'Register %s' to enable two-factor authentication via %s." msgstr "Twee-factor authenticatie verwijderen van %s" +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Klik om deze instelling aan te zetten" @@ -12848,6 +13027,10 @@ msgstr "Kloon deze verbinding om een nieuwe te maken" msgid "Clone this element" msgstr "Kloon dit element" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Beheerde objecten" + msgid "Clone this metric" msgstr "Kloon deze metriek" @@ -13404,6 +13587,10 @@ msgstr "Voltooi de restauratie" msgid "Complete tree" msgstr "Volledige boom" +#, fuzzy +msgid "Complete variable list" +msgstr "Volledige lijst van variabelen (voor testen)" + msgid "Complete variable list (for testing)" msgstr "Volledige lijst van variabelen (voor testen)" @@ -13548,6 +13735,10 @@ msgstr "Configuratiebestanden ('*.mk' of '*.conf') van etc/checkmk: %s" msgid "Configuration generation" msgstr "Configuratie generatie" +#, fuzzy +msgid "Configuration name" +msgstr "Configuratie" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Configuratie van Checkmk's Business Intelligence component" @@ -13619,6 +13810,10 @@ msgstr "Configureer" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Toezicht op Amazon Web Services (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Toezicht op Amazon Web Services (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "SNMP gerelateerde instellingen configureren met regelsets" @@ -13684,6 +13879,10 @@ msgstr "Uitwijkmailadres voor crashmeldingen" msgid "Configure grouping of interfaces" msgstr "Groepering van interfaces configureren" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configuratie" + #, fuzzy msgid "Configure host and regions" msgstr "Configuratie" @@ -13910,6 +14109,10 @@ msgstr "" "Configureer de naam van de HTTP verzoek header variabele om te lezen van de " "inkomende HTTP verzoeken" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configureer detectie van afzonderlijke interfaces" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13942,20 +14145,6 @@ msgstr "" "de gebruikers- of groepssleutel op te geven. De sleutel kan worden verkregen " "op de Pushover website." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configureer dit om de meldingsplugin direct verbinding te laten maken met de " -"smtp server. Dit heeft het voordeel dat het betere foutmeldingen geeft in " -"geval van een fout, maar het vereist meer configuratie en is strikt " -"synchroon, dus we adviseren het alleen te gebruiken op bedrijfsinstallaties " -"die de notificatie spooler gebruiken." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14360,6 +14549,10 @@ msgstr "Neem contact op met" msgid "Contact Name" msgstr "Naam contactpersoon" +#, fuzzy +msgid "Contact group" +msgstr "Contactgroepen" + msgid "Contact group (effective)" msgstr "Contactgroep (effectief)" @@ -14520,6 +14713,10 @@ msgstr "Contextinformatie" msgid "Context information about this connection" msgstr "Contextinformatie over deze verbinding" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Contextinformatie over deze regel" + msgid "Context information about this rule" msgstr "Contextinformatie over deze regel" @@ -14779,6 +14976,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase: Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, fuzzy, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -15063,6 +15265,10 @@ msgstr "Maak een kopie van deze verbinding" msgid "Create a copy of this group" msgstr "Maak een kopie van deze groep" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Maak een kopie van deze notificatieregel" + msgid "Create a copy of this notification rule" msgstr "Maak een kopie van deze notificatieregel" @@ -15146,6 +15352,11 @@ msgstr "Maak een extra dienst voor IO Stats Verzoeken" msgid "Create additional service for system wait" msgstr "Creëer extra dienst voor Systeem Wacht" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Maak een annotatie voor deze periode" @@ -15256,6 +15467,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Maak een tijdschema voor dit rapport" +#, fuzzy +msgid "Create robot" +msgstr "Maak hosts" + msgid "Create separate notification bulks based on" msgstr "Maak aparte notificatie bulken gebaseerd op" @@ -15356,6 +15571,10 @@ msgstr "Nieuwe host %s aangemaakt." msgid "Created new host tag group '%s'" msgstr "Nieuwe host tag groep '%s' aangemaakt" +#, fuzzy +msgid "Created new notification parameter" +msgstr "Nieuwe meldingsregel aangemaakt" + msgid "Created new notification rule" msgstr "Nieuwe meldingsregel aangemaakt" @@ -15804,6 +16023,10 @@ msgstr "Aangepast GUI ontwerp van %s" msgid "Custom Graph" msgstr "Aangepaste grafiek" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "HTML-sectie boven tabel toevoegen (bijv. titel, beschrijving...)" + msgid "Custom Icons" msgstr "Aangepaste pictogrammen" @@ -15910,6 +16133,14 @@ msgstr "Aangepaste lokalisaties" msgid "Custom logos" msgstr "Aangepaste logo's" +#, fuzzy +msgid "Custom macro" +msgstr "Macro's voor klanten" + +#, fuzzy +msgid "Custom macros" +msgstr "Macro's voor klanten" + #, python-format msgid "Custom notification table for user %s" msgstr "Aangepaste meldingentabel voor gebruiker %s" @@ -15924,9 +16155,15 @@ msgstr "Aangepaste sondestatus" msgid "Custom profile" msgstr "Aangepaste titel" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Aangepaste zoekopdracht" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Aangepaste dienstkenmerken" @@ -16768,9 +17005,6 @@ msgstr "Dagtarief" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Deactiveer" - msgid "Deactivated" msgstr "Gedeactiveerd" @@ -17064,6 +17298,9 @@ msgstr "Standaard gebruikersprofiel" msgid "Default value" msgstr "Standaardwaarde" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "Uitgestelde bestanden Leeftijd" @@ -17120,6 +17357,9 @@ msgstr "" "controle toestanden, d.w.z. naar het resultaat van de controle. Dit " "overschrijft de standaard mapping die door de controle wordt gebruikt." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Host toewijzing definiëren" @@ -17160,6 +17400,9 @@ msgstr "Definieer lagere niveaus voor het aantal wachtende containers" msgid "Define name of NetBIOS server" msgstr "NetBIOS naam van de server" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17402,6 +17645,10 @@ msgstr "Delete backup key #%d" msgid "Delete comments" msgstr "Evenement commentaar" +#, fuzzy +msgid "Delete comments?" +msgstr "Evenement commentaar" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Standaard configuratie" @@ -17470,6 +17717,14 @@ msgstr "Job verwijderen #%d" msgid "Delete last alert handler rule" msgstr "Verwijder de laatste alert handler regel" +#, fuzzy +msgid "Delete managed robot" +msgstr "Beheerde objecten" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Kennisgevingsregel verwijderen #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Kennisgevingsregel verwijderen #%d" @@ -17622,9 +17877,17 @@ msgstr "Verwijder deze toets" msgid "Delete this logo" msgstr "Dit logo verwijderen" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Verwijder deze tag groep" + msgid "Delete this metric" msgstr "Verwijder deze metriek" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Verwijder deze meldingsregel" + msgid "Delete this notification rule" msgstr "Verwijder deze meldingsregel" @@ -17722,6 +17985,10 @@ msgstr "Verwijderde map %s" msgid "Deleted host %s" msgstr "Verwijderde host %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Kennisgevingsregel verwijderen #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Verwijderde notificatie regel %d van gebruiker %s" @@ -18657,6 +18924,10 @@ msgstr "Uitschakelen proxy behandeling" msgid "Disable remote configuration" msgstr "Externe configuratie uitschakelen" +#, fuzzy +msgid "Disable rule" +msgstr "Alles uitschakelen" + msgid "Disable service notifications" msgstr "Dienst meldingen uitschakelen" @@ -19030,9 +19301,6 @@ msgstr "" "Geef een waarschuwing weer als een LUN niet alleen-lezen is. Zonder deze " "instelling wordt een waarschuwing weergegeven als een LUN alleen-lezen is." -msgid "Display additional information" -msgstr "Aanvullende informatie weergeven" - msgid "Display additional messages" msgstr "Extra berichten weergeven" @@ -19056,9 +19324,6 @@ msgstr "Toon aslabels voor het geselecteerde/automatische gegevensbereik" msgid "Display dashboard title" msgstr "Titel dashboard weergeven" -msgid "Display graphs among each other" -msgstr "Grafieken onder elkaar weergeven" - msgid "Display historic data since the last" msgstr "Toon historische gegevens sinds de laatste" @@ -19947,6 +20212,10 @@ msgstr "Aantal documenten delta" msgid "Document count growth per minute" msgstr "Aantal documenten groeit per minuut" +#, fuzzy +msgid "Documentation" +msgstr "Documentatie URL" + msgid "Documentation URL" msgstr "Documentatie URL" @@ -20730,6 +20999,10 @@ msgstr "Bewerken" msgid "Edit %s" msgstr "Bewerk %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Wijzig notificatie regel %d" + #, python-format msgid "Edit %s: %s" msgstr "Bewerken %s: %s" @@ -20880,6 +21153,10 @@ msgstr "Lay-out bewerken" msgid "Edit layout only available if header is enabled" msgstr "Wijzig lay-out alleen beschikbaar als koptekst is ingeschakeld" +#, fuzzy +msgid "Edit managed robots" +msgstr "Beheerde objecten" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Siteverbinding %s bewerken" @@ -21037,6 +21314,14 @@ msgstr "Dit element bewerken" msgid "Edit this host" msgstr "Bewerk deze host" +#, fuzzy +msgid "Edit this managed robot" +msgstr "Administratieve staten" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Bewerk deze meldingsregel" + msgid "Edit this notification rule" msgstr "Bewerk deze meldingsregel" @@ -21108,6 +21393,9 @@ msgstr "Bewerkt gebruikersprofiel voor gebruiker %s" msgid "Edition" msgstr "Editie" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "Effectieve staat" @@ -21292,6 +21580,14 @@ msgstr "E-mailadres gebruikt voor rekeningidentificatie" msgid "Email addresses to mail PDF reports to" msgstr "Email-Adressen om PDF-rapporten naar te mailen" +#, fuzzy +msgid "Email body/content" +msgstr "E-mail verzonden" + +#, fuzzy +msgid "Email header" +msgstr "Emailadres" + msgid "Email sent" msgstr "E-mail verzonden" @@ -22298,6 +22594,10 @@ msgstr "Evenement commentaar" msgid "Event console" msgstr "Gebeurtenis console" +#, fuzzy +msgid "Event console alerts" +msgstr "Event Console waarschuwingen" + msgid "Event console performance" msgstr "Prestaties gebeurtenisconsole" @@ -23524,10 +23824,6 @@ msgstr "Mislukt om waarde te renderen:" msgid "Failed to render value: %r" msgstr "Mislukt om waarde te renderen: %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Kan peer-certificaat niet ophalen (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "Regel van regelset '%s' in map '%s' (%r) zoeken mislukt: %s" @@ -23636,6 +23932,10 @@ msgstr "" "gegevens te verzenden, de resultaten van alle extra nodes zullen op zijn " "minst een WARNING status triggeren." +#, fuzzy +msgid "Failure" +msgstr "mislukkingen" + msgid "Failures of the join launcher service" msgstr "Storingen van de join launcher service" @@ -23933,6 +24233,10 @@ msgstr "Bestandsgrootte hieronder" msgid "File size levels" msgstr "Niveaus bestandsgrootte" +#, fuzzy +msgid "File upload" +msgstr "Geüploade bytes" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -24060,6 +24364,10 @@ msgstr "" "Filter voor alle aggregaties die gebaseerd zijn op statusinformatie van die " "host. Exacte overeenkomst (geen reguliere expressie)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Downtime voor host/dienst" + msgid "Filter group (see help)" msgstr "Filter groep (zie help)" @@ -24734,6 +25042,9 @@ msgstr "Netwerken" msgid "Form factor" msgstr "Vormfactor" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Formaat" @@ -25369,6 +25680,11 @@ msgstr "Genereer" msgid "Generate REST API specification" msgstr "SLA-specificatie" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + #, fuzzy msgid "Generate backup codes" msgstr "Back-upcodes opnieuw genereren" @@ -25434,6 +25750,21 @@ msgstr "Algemeen tarief" msgid "Generic string" msgstr "Generieke string" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Kernel Versie" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Verbinding bewerken" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "Jenkins instantie om te bevragen." + msgid "Get file from SFTP server" msgstr "Bestand van SFTP-server halen" @@ -25492,6 +25823,10 @@ msgstr "Algemene kennisgevingsregel" msgid "Global notification rules" msgstr "Globale kennisgevingsregels" +#, fuzzy +msgid "Global services" +msgstr "Alle diensten" + msgid "Global services to monitor" msgstr "Wereldwijde diensten voor toezicht" @@ -25517,6 +25852,10 @@ msgstr "Globbing patroon voor invoerbestanden" msgid "Go critical if all licenses are used" msgstr "Ga kritisch als alle licenties zijn gebruikt" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Alle gastheren" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25529,6 +25868,12 @@ msgstr "Ga naar de hoofdpagina" msgid "Go to rules of this InfluxDB connection" msgstr "Ga naar de regels van deze InfluxDB verbinding" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "" @@ -25689,18 +26034,12 @@ msgstr "Grafische kaarten" msgid "Graphs" msgstr "Grafieken" -msgid "Graphs are shown among each other" -msgstr "Grafieken worden onder elkaar getoond" - msgid "Graphs for averaged single-core utilizations" msgstr "Grafieken voor gemiddeld single-core gebruik" msgid "Graphs for individual cores" msgstr "Grafieken voor afzonderlijke kernen" -msgid "Graphs per notification (default: 5)" -msgstr "Grafieken per melding (standaard: 5)" - msgid "Graylog" msgstr "Graylog" @@ -25789,10 +26128,6 @@ msgstr "Groep basis DN" msgid "Group discovery and activation for up to" msgstr "Ontdekking en activering van groepen tot" -#, fuzzy -msgid "Group execution interval" -msgstr "Uitvoeringsinterval" - msgid "Group files based on a regular expression pattern." msgstr "Groepeert bestanden op basis van een regelmatig expressiepatroon." @@ -25994,6 +26329,10 @@ msgstr "HPE StoreOnce via REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: Gebruikt geheugen via SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Modelparameters" + #, fuzzy msgid "HTML email" msgstr "HTML e-mail" @@ -27333,6 +27672,10 @@ msgstr "Verberg namen van configuratievariabelen" msgid "Hide notification bulks" msgstr "kennisgevingsregel" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Stuur aparte meldingen naar elke ontvanger" + msgid "Hide response from socket" msgstr "Verberg antwoord van socket" @@ -27399,6 +27742,10 @@ msgstr "Geschiedenis" msgid "History Line Number" msgstr "Geschiedenis Lijnnummer" +#, fuzzy +msgid "History action type" +msgstr "Registratie Staat" + msgid "History entries of one specific event" msgstr "Historische gegevens van één specifieke gebeurtenis" @@ -29079,10 +29426,6 @@ msgstr "Overzicht gastheren" msgid "Host parent/child topology" msgstr "Gastheer Ouder-Kind topologie" -#, fuzzy -msgid "Host path" -msgstr "Gastheer alarm" - msgid "Host performance data" msgstr "Prestatiegegevens van de gastheer" @@ -29794,6 +30137,10 @@ msgstr "IP - regio - instantie-ID" msgid "IP Address" msgstr "IP-adres" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "IP-adres van gastheer" + msgid "IP address" msgstr "IP-adres" @@ -31783,21 +32130,6 @@ msgstr "" "Merk op dat dit alles betreft wat deel uitmaakt van de overeenkomende " "namespaces, zoals pods bijvoorbeeld." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Waarschuwing

    U hebt geen terugval-e-mailadres geconfigureerd en u hebt het ontvangen van terugval-e-mails voor geen " -"enkele gebruiker ingeschakeld. Als uw bewaking een melding genereert die " -"niet overeenkomt met een van uw meldingsregels, zal de melding niet worden " -"verzonden. Om dat te voorkomen, moet u ofwel de globale instelling " -"configureren of de optie voor fallback contact inschakelen voor ten minste " -"één van uw gebruikers." - msgid "Ignore" msgstr "Negeer" @@ -32763,6 +33095,14 @@ msgstr "Indexen om te doorzoeken, standaard '*', wat betekent alle indexen." msgid "Indexspace wasted" msgstr "Verspilde indexruimte" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Of de laatste bulk ontdekking al dan niet mislukt is. Het wordt op True " +"gezet als het mislukt en op Unset als een latere ontdekking slaagt." + msgid "Indices" msgstr "Indexen" @@ -33430,6 +33770,10 @@ msgstr "Ongeldig certificaat" msgid "Invalid certificate file: %s" msgstr "Ongeldig certificaatbestand: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Ongeldige parameter %r: %s" + msgid "Invalid check parameter" msgstr "Ongeldige controleparameter" @@ -36263,6 +36607,10 @@ msgstr "Linux Multipath Inventaris" msgid "Linux and Solaris Multipath Count" msgstr "Linux en Solaris Multipath telling" +#, fuzzy +msgid "Linux bonding" +msgstr "Vswitch binding" + msgid "Linux bonding interface status" msgstr "Linux interface status" @@ -36853,6 +37201,10 @@ msgstr "" "Log het agent registratieproces van inkomende verzoeken door het Checkmk " "agent controller registratiecommando." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Automatische hostverwijdering inschakelen" + msgid "Log: Details" msgstr "Logboek: Details" @@ -37360,6 +37712,10 @@ msgid "Lower levels on the total number of clients pending on a blocking call" msgstr "" "Totaal aantal cliënten in afwachting van een blokkerend gesprek lager niveau" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Lijst van verwachte logfiles" + msgid "Lowest: No notification, update badge number" msgstr "Laagste: Geen kennisgeving, update badge nummer" @@ -37932,10 +38288,25 @@ msgstr "Beheer van de gebruikers van het bewakingssysteem." msgid "Managed Robot" msgstr "Beheerde objecten" +#, fuzzy +msgid "Managed Robots" +msgstr "Beheerde objecten" + #, fuzzy msgid "Managed objects" msgstr "Beheerde objecten" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Beheerde objecten" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Beheerde objecten" + msgid "Management board" msgstr "Raad van bestuur" @@ -39503,14 +39874,14 @@ msgstr "Minimale verbindingen per seconde" msgid "Minimum error count" msgstr "Minimaal aantal fouten" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Minimum Spanningsniveaus" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Minimumniveaus voor belasting in procenten" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Minimum Spanningsniveaus" + msgid "Minimum levels if using magic factor" msgstr "Minimum niveaus bij gebruik van magische factor" @@ -39619,6 +39990,10 @@ msgstr "Misplande duur (alleen DaemonSet)" msgid "Misscheduled replicas" msgstr "Verkeerd geplande replica's" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Ontbrekende variabele siteid" + #, python-format msgid "Missing config file for agent %s%s" msgstr "Ontbrekend config-bestand voor agent %s%s" @@ -41102,6 +41477,11 @@ msgstr "Naam resolutie" msgid "Name your %s for easy recognition." msgstr "Geef uw %s een naam voor gemakkelijke herkenning." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -41116,13 +41496,13 @@ msgstr "Namen" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" @@ -41535,6 +41915,29 @@ msgstr "Volgende kennisgeving" msgid "Next run" msgstr "Volgende run" +#, fuzzy +msgid "Next step: General properties" +msgstr "Algemene eigenschappen" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugins voor kennisgeving" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Ontvanger" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "in behandeling zijnde verbindingen" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Type opmerking (host/dienst)" + msgid "Nginx Server" msgstr "Nginx Server" @@ -41550,6 +41953,10 @@ msgstr "Nauwkeurige IO niveaus" msgid "No" msgstr "Geen" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Host configuratie" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "Nee (Fout: %s, Code: %d, Diepte: %d)" @@ -41557,6 +41964,10 @@ msgstr "Nee (Fout: %s, Code: %d, Diepte: %d)" msgid "No API integrations, no Checkmk agent" msgstr "Geen API-integraties, geen Checkmk-agent" +#, fuzzy +msgid "No AWS services found." +msgstr "Geen hosts/services gevonden." + msgid "No CSRF token received" msgstr "Geen CSRF-token ontvangen" @@ -41567,6 +41978,10 @@ msgstr "Geen voorwaarden" msgid "No Configuration Quick setup for %s available" msgstr "Configuratie variabele:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Gewijzigde meldingsregel %d" + msgid "No IP" msgstr "Geen IP" @@ -41644,10 +42059,6 @@ msgstr "In deze weergave zijn geen commando's mogelijk" msgid "No conditions" msgstr "Geen voorwaarden" -#, fuzzy -msgid "No configuration yet" -msgstr "Host configuratie" - msgid "No configured rules are affected" msgstr "Geen geconfigureerde regels worden beïnvloed" @@ -41704,6 +42115,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "niet beschikbaar" + +#, fuzzy +msgid "No elements selected" +msgstr "Niet geselecteerd" + msgid "No entries" msgstr "Geen inzendingen" @@ -41835,6 +42254,10 @@ msgstr "Geen verbindingen gedefinieerd" msgid "No need for syncing sites" msgstr "Geen behoefte om sites te synchroniseren" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Gewijzigde meldingsregel %d" + msgid "No object type" msgstr "Geen objecttype" @@ -41845,6 +42268,10 @@ msgstr "" msgid "No password provided" msgstr "Van wachtwoord opslag" +#, fuzzy +msgid "No password selected" +msgstr "Van wachtwoord opslag" + msgid "No pending changes" msgstr "Geen hangende wijzigingen" @@ -41923,6 +42350,10 @@ msgstr "Geen zoekopdracht" msgid "No search, specify list of arguments" msgstr "Geen zoekfunctie, geef een lijst met argumenten" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthosts" + #, fuzzy msgid "No snapshot to restore available." msgstr "Geen informatie beschikbaar" @@ -42385,6 +42816,9 @@ msgstr "Kennisgeving" msgid "Notation: %s" msgstr "Annotaties: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42551,6 +42985,18 @@ msgstr "Niveau meldingslogboek" msgid "Notification method" msgstr "Kennisgevingsmethode" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "Grafiekverzameling '%s' bestaat niet" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugins voor kennisgeving" + +#, fuzzy +msgid "Notification parameter" +msgstr "Kennisgevingsfase" + #, fuzzy msgid "Notification period" msgstr "Kennisgevingsperiode" @@ -42996,6 +43442,14 @@ msgstr "Aantal te creëren mappen in elk niveau" msgid "Number of goroutines" msgstr "Aantal herhalingen" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Grafieken per melding (standaard: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Grafieken per melding (standaard: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Aantal gezonde gastheren lagere niveaus" @@ -43649,8 +44103,8 @@ msgid "OTLP endpoint" msgstr "Eindpunt" #, fuzzy -msgid "OVS bonding interface status" -msgstr "Koppelvlakken" +msgid "OVS bonding" +msgstr "Vswitch binding" msgid "Object" msgstr "Object" @@ -45686,6 +46140,10 @@ msgstr "Algemene actualiteit" msgid "Overall latency" msgstr "Totale latentie" +#, fuzzy +msgid "Overall response time" +msgstr "Gemiddelde reactietijd" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "Algemene toestand van een virtuele machine (bijvoorbeeld ESX-VM's)" @@ -45747,7 +46205,7 @@ msgid "Override check state based on last build result" msgstr "Overschrijven controle status gebaseerd op laatste build resultaat" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Overbruggingseenheid van sensor" msgid "Override unit of sensor" @@ -46342,13 +46800,16 @@ msgstr "Parallelle aansluitingen belasting" msgid "Parallel pings to send" msgstr "Parallelle pings te sturen" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Plan uitvoering" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Paralleliseren van core config creatie" +#, fuzzy +msgid "Parameter" +msgstr "Parameters" + msgid "Parameter groups" msgstr "Parameter groepen" @@ -46358,6 +46819,10 @@ msgstr "Parameter groepen per regio" msgid "Parameter name" msgstr "Naam van de parameter" +#, fuzzy +msgid "Parameter properties" +msgstr "Pakketeigenschappen" + msgid "Parameter rule set" msgstr "Parameter regel set" @@ -46382,6 +46847,10 @@ msgstr "" "waarde van de parameters invoegen door $HOST$ en $INST$ " "(ingesloten door dollartekens)." +#, fuzzy +msgid "Parameters for" +msgstr "Parameters voor %s" + #, python-format msgid "Parameters for %s" msgstr "Parameters voor %s" @@ -46389,6 +46858,10 @@ msgstr "Parameters voor %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parameters voor ingangsfasen van UPS-systemen en PDU's" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Parameters voor deze host" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parameters voor uitgangsbelastingen van UPS-systemen en PDU's" @@ -47438,6 +47911,10 @@ msgstr "Ping het normale IP adres" msgid "Ping timeout" msgstr "Ping timeout" +#, fuzzy +msgid "Placeholder" +msgstr "Plaatsvervangende VM's" + msgid "Placeholder VMs" msgstr "Plaatsvervangende VM's" @@ -47489,6 +47966,10 @@ msgid "" msgstr "" "Combinaties van operationele en administratieve status in kaart brengen" +#, fuzzy +msgid "Plan settings" +msgstr "Globale instellingen" + msgid "Plans" msgstr "" @@ -47516,6 +47997,10 @@ msgstr "Voeg ten minste één kolom toe aan je uitzicht." msgid "Please add at least one endpoint to monitor" msgstr "Voeg ten minste één kolom toe aan je uitzicht." +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Voeg ten minste één kindknooppunt toe." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47575,6 +48060,10 @@ msgstr "Kies een geldige PNG afbeelding." msgid "Please choose an audit log to view:" msgstr "Kies een bestand om te uploaden." +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Kies een rapport om te plannen" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Kies de check plugin" @@ -48215,6 +48704,10 @@ msgstr "Plugins, lokale controles en MRPE voor niet-root gebruikers" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Plugin uitgang" + msgid "Plugins" msgstr "Plugins" @@ -48359,6 +48852,10 @@ msgstr "Positieve match (Voeg overeenkomende hosts toe aan de set)" msgid "Positive match (Add matching services to the set)" msgstr "Positieve match (voeg overeenkomende diensten toe aan de set)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Positieve match (Voeg overeenkomende hosts toe aan de set)" + msgid "Postfix" msgstr "Postfix" @@ -48544,6 +49041,10 @@ msgstr "Voorvoegsel tekst" msgid "Prepare AWS for Checkmk" msgstr "Geïnitialiseerde GIT voor Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "Geïnitialiseerde GIT voor Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Prepend namespace prefix voor hosts" @@ -49202,11 +49703,10 @@ msgstr "Python agent plugin uitvoering (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" #, fuzzy @@ -49441,14 +49941,15 @@ msgstr "Lees gemiddelde exe" msgid "RCC profile configuration" msgstr "Configuratie op afstand" -#, fuzzy, python-format +#, fuzzy msgid "" -"RCC profile configuration (%s because Robotmk Core MKP has been installed)" +"RCC profile configuration (⚠ not available because Robotmk Core MKP " +"has been installed)" msgstr "Gebruik SSL voor de verbinding." msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" msgid "RCU" @@ -50056,6 +50557,10 @@ msgstr "Ontvanger" msgid "Recipient email address" msgstr "Emailadres van de ontvanger" +#, fuzzy +msgid "Recipients" +msgstr "Ontvanger" + #, python-format msgid "Recipients: %s" msgstr "Ontvangers: %s" @@ -50561,6 +51066,10 @@ msgstr "Resterende levensduur" msgid "Remaining Open Slots" msgstr "Overblijvende Open Slots" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Resterende dagen van geldigheid" + msgid "Remaining credits lower levels" msgstr "Resterende kredieten lagere niveaus" @@ -50722,10 +51231,6 @@ msgstr "Verwijder alle bestanden en subdirectories" msgid "Remove downtimes" msgstr "Uitvaltijd verwijderen" -#, fuzzy -msgid "Remove downtimes?" -msgstr "Uitvaltijd verwijderen" - msgid "Remove explicit attribute settings" msgstr "Expliciete attribuutinstellingen verwijderen" @@ -50755,6 +51260,10 @@ msgstr "verwijder alle geplande downtimes van " msgid "Remove service" msgstr "Service verwijderen" +#, fuzzy +msgid "Remove smarthost" +msgstr "Verplaats dit item" + #, fuzzy msgid "Remove style" msgstr "Verwijder alle" @@ -51319,6 +51828,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Vraagt gegevens op van een Jenkins instantie." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Vraagt gegevens op van een Jenkins instantie." @@ -51364,6 +51877,10 @@ msgstr "Vereiste poort" msgid "Required context filters" msgstr "Vereiste context filters" +#, fuzzy +msgid "Required field missing" +msgstr "Site ontbreekt" + msgid "Required match (regular expression)" msgstr "Vereiste overeenkomst (reguliere expressie)" @@ -51683,6 +52200,10 @@ msgstr "Beperk bewakingsdiensten door één van deze AWS tags" msgid "Restrict number of processed messages per cycle" msgstr "Beperking van het aantal verwerkte berichten per cyclus" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Beperk de ernst tot in het ergste geval" + msgid "Restrict runtime of logfile parsing" msgstr "Beperk runtime van logfile parsing" @@ -51822,6 +52343,11 @@ msgid "" "Retrieve process information using WMI (Windows Management Instrumentation)" msgstr "Procesinformatie opvragen met WMI (Windows Management Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Opnieuw proberen" @@ -51847,6 +52373,10 @@ msgstr "Probeer deze test opnieuw" msgid "Retry time" msgstr "Herhalingstijd" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "geef CRITICAL terug indien gevonden, OK indien niet" + msgid "Return code class 2xx (success)" msgstr "Retourcode klasse 2xx (succes)" @@ -51864,7 +52394,12 @@ msgstr "Terugkeren procestijden binnen prestatiegegevens" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -51887,10 +52422,19 @@ msgstr "Buitenlandse wijzigingen activeren" msgid "Review and run preview service discovery" msgstr "Save & run service discovery" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configuratie op afstand" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Save & run service discovery" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Omwentelingen per minuut" @@ -51943,6 +52487,10 @@ msgstr "Robot Framework: %s" msgid "Robot Framework: Last log" msgstr "Robot Framework: Laatste logboek" +#, fuzzy +msgid "Robot package" +msgstr "Pakket verwijderen" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -53048,12 +53596,14 @@ msgstr "Maak een kopie van deze aggregatie" msgid "Save response" msgstr "Reactie opslaan" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Sla deze host op en ga naar" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "Opgeslagen controleconfiguratie van host '%s' met %d diensten" @@ -53105,10 +53655,6 @@ msgstr "Plan downtime op host" msgid "Schedule downtime on service" msgstr "Plan downtime op host" -#, fuzzy -msgid "Schedule downtime?" -msgstr "Uitvaltijden plannen" - msgid "Schedule downtimes" msgstr "Uitvaltijden plannen" @@ -53478,6 +54024,10 @@ msgstr "" msgid "Secret access key" msgstr "Geheime sleutel" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Geheime sleutel" + msgid "Secret key" msgstr "Geheime sleutel" @@ -53652,6 +54202,15 @@ msgstr "Selecteer een iCalendar bestand (*.ics) van uw PC" msgid "Select and configure AWS services you would like to monitor" msgstr "Te controleren Azure diensten" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Te controleren Azure diensten" + +#, fuzzy +msgid "Select contact group" +msgstr "Regel contactgroepen" + #, fuzzy msgid "Select datasource" msgstr "Selecteer gegevensbron" @@ -53851,6 +54410,10 @@ msgstr "Selecteer het type vast pagina-element" msgid "Select type from list" msgstr "Selecteer individuele bestanden uit de lijst" +#, fuzzy +msgid "Select user" +msgstr "Gebruikers verwijderen" + msgid "Select view" msgstr "Weergave kiezen" @@ -53888,6 +54451,10 @@ msgstr "De geselecteerde %s zijn verwijderd." msgid "Selected credential has been deleted" msgstr "Credential is verwijderd" +#, fuzzy +msgid "Selected options" +msgstr "Afgewezen verbindingen" + msgid "Selected sections will not be executed by the agent." msgstr "Geselecteerde secties zullen niet worden uitgevoerd door de agent." @@ -53958,6 +54525,10 @@ msgstr "HTTP POST-gegevens verzenden" msgid "Send custom notification" msgstr "Aangepaste kennisgeving verzenden" +#, fuzzy +msgid "Send custom notification?" +msgstr "Aangepaste kennisgeving verzenden" + #, fuzzy msgid "Send data" msgstr "In kaart gebrachte gegevens" @@ -54004,9 +54575,7 @@ msgid "Send notifications to remote Event Console" msgstr "Meldingen verzenden naar externe gebeurtenissenconsole" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "Sorteervolgorde voor bulkmeldingen" msgid "" @@ -54014,10 +54583,6 @@ msgid "" "notifications (forced)" msgstr "" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Stuur aparte meldingen naar elke ontvanger" - msgid "Send service metrics to Graphite" msgstr "Dienstgegevens naar Graphite sturen" @@ -54061,6 +54626,10 @@ msgstr "Versturen via e-mail" msgid "Sending Power" msgstr "Zendvermogen" +#, fuzzy +msgid "Sending conditions" +msgstr "Stel voorwaarden" + msgid "Sending reply" msgstr "Ik stuur antwoord" @@ -54114,7 +54683,11 @@ msgid "September" msgstr "September" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Uitvoeringsinterval" + +#, fuzzy +msgid "Sequence of plans" msgstr "Plan uitvoering" msgid "Serial" @@ -54355,6 +54928,10 @@ msgstr "Ontdekking van de dienst: Beschrijving van de dienst" msgid "Service discovery: State" msgstr "Dienst ontdekking: Toestand" +#, fuzzy +msgid "Service events" +msgstr "Dienstverleningsniveau" + msgid "Service goes into critical state" msgstr "Dienst gaat in kritieke toestand" @@ -54687,6 +55264,10 @@ msgstr "Diensten van Site" msgid "Services per cluster" msgstr "Diensten per cluster" +#, fuzzy +msgid "Services per region" +msgstr "Te controleren diensten per regio" + msgid "Services per region to monitor" msgstr "Te controleren diensten per regio" @@ -55215,7 +55796,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -55584,6 +56165,10 @@ msgstr "Toon selectievakjes" msgid "Show column headings" msgstr "Toon kolomkoppen" +#, fuzzy +msgid "Show contact groups" +msgstr "Host contactgroepen" + msgid "Show context" msgstr "Toon context" @@ -55651,9 +56236,17 @@ msgstr "Toon hint in het \"Gebruiker\" menu" msgid "Show historic values" msgstr "Toon historische waarden" +#, fuzzy +msgid "Show host labels" +msgstr "Toon in gastheertabellen" + msgid "Show host status" msgstr "Toon host status" +#, fuzzy +msgid "Show host tags" +msgstr "Toon host status" + msgid "Show icon linking to Setup parameter editor for services" msgstr "Toon icoon dat linkt naar Setup parameter editor voor diensten" @@ -55729,6 +56322,10 @@ msgstr "Toon meer / Toon minder" msgid "Show notification bulks" msgstr "kennisgevingsregel" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Sorteervolgorde voor bulkmeldingen" + msgid "Show number of groups" msgstr "Toon aantal groepen" @@ -55793,6 +56390,10 @@ msgstr "Toon regels met behulp van deze %s" msgid "Show separate result for each SLA period" msgstr "Toon afzonderlijk resultaat voor elke SLA periode" +#, fuzzy +msgid "Show service labels" +msgstr "Dienstetiketten" + #, fuzzy msgid "Show service name" msgstr "De naam van de dienst" @@ -56182,6 +56783,11 @@ msgstr "" "resultaat (de voorkeurs knoop indien er twijfel is). U kunt dit automatisme " "opheffen door hier een node te specificeren." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -57104,6 +57710,10 @@ msgstr "Specifieke objecten" msgid "Specific sites" msgstr "Specifieke sites" +#, fuzzy +msgid "Specific users" +msgstr "Specifieke sites" + msgid "Specific version" msgstr "Specifieke versie" @@ -57127,13 +57737,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Specificeert de standaard lijnstijl" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Geeft aan of wachtwoordauthenticatie is toegestaan" @@ -57300,13 +57903,6 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -57753,6 +58349,11 @@ msgstr "" "Geef aan wat we moeten doen als de geselecteerde grafiek ontbreekt of niet " "kan worden opgehaald." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Geef aan welke poorttypes niet ontdekt mogen worden" @@ -57972,6 +58573,10 @@ msgstr "Begin volgend jaar" msgid "Start or end of a scheduled downtime" msgstr "Begin of einde van een geplande downtime" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Begin van uitvaltijd" + msgid "Start or end of flapping state" msgstr "Begin of einde van de slagtoestand" @@ -58196,6 +58801,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Staat voor verwachte string mismatch" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Waarschuwing voor onverwachte actieve interface" + +#, fuzzy +msgid "State found during service discovery" +msgstr "In afwachting van dienstontdekking" + msgid "State if 'maintenance' services are found" msgstr "Vermeld of \"onderhouds\"-diensten zijn gevonden" @@ -59223,10 +59836,12 @@ msgstr "Naam van de sectie" msgid "Subject for bulk notifications" msgstr "Onderwerp voor bulkmeldingen" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Onderwerp voor hostmeldingen" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Onderwerp voor dienstmededelingen" msgid "Submit" @@ -59624,6 +60239,10 @@ msgstr "Synchroon" msgid "Syncing" msgstr "Synchroniseren" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "SAP-routercertificaat" + msgid "Synology Updates" msgstr "Synology Updates" @@ -59913,6 +60532,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLS-authenticatie zonder TLS is niet mogelijk" +#, fuzzy +msgid "TLS certificate verification" +msgstr "SSL-certificaat verificatie" + #, fuzzy msgid "TLS processed bytes" msgstr "TLS Verwerkte bytes" @@ -60135,6 +60758,16 @@ msgstr "" "Tags kunnen worden gebruikt om hosts en diensten op een flexibele manier te " "classificeren." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "Geen datasource gedefinieerd." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Tags van de waarschuwing." @@ -60378,6 +61011,10 @@ msgstr "Maak een kopie van deze notificatieregel" msgid "Test authentication" msgstr "Token authenticatie" +#, fuzzy +msgid "Test configuration" +msgstr "Host configuratie" + #, fuzzy msgid "Test connection" msgstr "Deze verbinding" @@ -60412,6 +61049,9 @@ msgstr "laatste mededeling" msgid "Test runtime" msgstr "Procesruntime" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + #, fuzzy msgid "Test verification" msgstr "Verificatie van het rijbewijs" @@ -61664,6 +62304,10 @@ msgstr "" msgid "The central (%s) and remote site (%s) are not compatible. Reason: %s" msgstr "De centrale (%s) en externe site (%s) zijn niet compatibel. Reden: %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "Is nooit geactiveerd geweest" + #, python-format msgid "The character %s is not allowed here." msgstr "Het teken %s is hier niet toegestaan." @@ -61951,6 +62595,11 @@ msgstr "" "De verbinding creëert hosts in deze specifieke map. Eenmaal aangemaakt, kunt " "u ervoor kiezen de host naar een andere map te verplaatsen." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "De verbinding met deze site is verbroken." @@ -62216,24 +62865,6 @@ msgstr "Het element is niet te vinden op het dashboard." msgid "The element does not exist." msgstr "Het element bestaat niet." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"Het e-mailadres en de zichtbare naam die worden gebruikt in de kop Van van " -"kennisgevingen. Als geen e-mailadres wordt opgegeven, wordt standaard " -"OMD_SITE@FQDN gebruikt. Als de omgevingsvariabele OMD_SITE " -"niet is ingesteld, wordt standaard checkmk gebruikt." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"Het e-mailadres en de zichtbare naam die worden gebruikt in de kop Reply-To " -"van kennisgevingen." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -62597,12 +63228,6 @@ msgstr "De grafiekspecificatie ontbreekt" msgid "The graph template id '%s' is disabled" msgstr "Het grafieksjabloon id '%s' is uitgeschakeld" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -62838,13 +63463,6 @@ msgstr "" "De naam van de instantie, de naam van de database en de naam van de " "tablespace gecombineerd als volgt db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -63221,6 +63839,12 @@ msgstr "" "dienst in waarschuwing/critiek gaat. Dit alarm is alleen van toepassing op " "de doelhost, niet op de tussenliggende hops." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "De maximale lengte van de waarde is 256 tekens." @@ -64866,6 +65490,20 @@ msgstr "" "De drempels voor wait_duration_ms. Overschrijven de standaard toestand die " "hierboven is ingesteld." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "" "Het tijdsinterval waarin statistische gegevens op schijf worden opgeslagen" @@ -65020,6 +65658,14 @@ msgstr "" "De gebruikersnaam geretourneerd door de %s connector is niet van het type " "string (%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"De gebruikersnaam die moet worden gebruikt voor toegang tot de Graylog API. " +"Moet minstens leesrechten hebben." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -65331,8 +65977,8 @@ msgstr "Er is geen Setup snapshot dat moet worden hersteld." msgid "There is no backup job configured" msgstr "Er is geen back-uptaak geconfigureerd" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "Er is geen grafieksjabloon met id '%s'" msgid "There is no manpage for this check." @@ -65503,7 +66149,7 @@ msgstr "Deze knooppunten zitten alleen in de bevroren aggregatie" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" msgid "" @@ -65823,6 +66469,9 @@ msgstr "" "controller op de bewaakte host moet resetten (raadpleeg `cmk-agent-ctl " "help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + #, fuzzy msgid "" "This active check sends out special emails to a defined mail address using " @@ -66574,7 +67223,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -67413,8 +68062,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Met deze toestemming kunnen gebruikers andere gebruikers naar een andere " "verbinding migreren" @@ -68016,13 +68664,6 @@ msgstr "" "leiden tot frequente veranderingen in de HW/SW inventaris, wat het " "tijdelijke bestandssysteem snel kan vullen." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Deze regel maakt monitoring van VMware ESX via de vSphere API mogelijk. U " -"kunt uw verbindingsinstellingen hier configureren." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -68703,15 +69344,6 @@ msgstr "" "plaats van de normale Checkmk agent en maakt monitoring via Web API " "mogelijk. " -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Deze regelset selecteert de speciale agent voor HPE StoreOnce Appliances in " -"plaats van de normale Checkmk agent en staat monitoring toe via REST API v4." -"x of hoger. " - #, fuzzy msgid "" "This rule sets limits to the current number of connections through a Check " @@ -73535,9 +74167,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "Geprobeerd om incompatibele regelspec te registreren: %r" +#, fuzzy +msgid "Triggering events" +msgstr "Archief gebeurtenissen" + msgid "Trivial change" msgstr "Triviale verandering" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -74739,6 +75378,14 @@ msgstr "antwoord verbergen" msgid "Upload verification response file" msgstr "Antwoord op verificatie uploaden" +#, fuzzy +msgid "Uploaded" +msgstr "Upload" + +#, fuzzy +msgid "Uploaded by" +msgstr "Upload sleutel" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "Aangepaste GUI logo geupload: %s" @@ -76128,6 +76775,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">global rule event " "limit op te heffen" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Gebruik deze optie om een poort op te vragen die afwijkt van standaardpoort " +"443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -76169,6 +76822,15 @@ msgstr "" "de volgende server worden ondervraagd (fallback). De controle zal alleen " "gegevens uitvoeren van de eerste host die een antwoord stuurt." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Gebruik deze optie om in te stellen welke instantie moet worden " +"gecontroleerd door de special agent. Voeg hier de hostnaam toe, bijv. " +"my_graylog.com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -76566,7 +77228,8 @@ msgstr "Berichten van gebruikers" msgid "User name" msgstr "Naam gebruiker" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Gebruikersnaam op het opslagsysteem. Alleen-lezen permissies zijn voldoende." @@ -76660,6 +77323,10 @@ msgstr "Gebruikers in de Active Directory" msgid "Users listed here are still allowed to modify things." msgstr "Gebruikers die hier staan, mogen nog steeds dingen wijzigen." +#, fuzzy +msgid "Users of contact groups" +msgstr "Leden van contactgroepen" + msgid "Users using a cifs share" msgstr "Gebruikers die een cifs share gebruiken" @@ -77704,6 +78371,10 @@ msgstr "Certificaten verifiëren" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Negeer certificaatfouten (onveilig)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Negeer certificaatfouten (onveilig)" + msgid "Verify certificates" msgstr "Certificaten verifiëren" @@ -77767,6 +78438,9 @@ msgstr "Versie van PKI-toestel" msgid "Version of Server" msgstr "Versie van server" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Versie: %s" @@ -78229,6 +78903,10 @@ msgstr "Wachtende verbindingen" msgid "Waiting containers" msgstr "Wachtende containers" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Netapp poort ontdekking" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -78616,6 +79294,9 @@ msgstr "" msgid "What is the purpose?" msgstr "" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -79682,6 +80363,10 @@ msgstr "" msgid "Who" msgstr "Wie" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "gebruikers in staat stellen deze melding te deactiveren" + msgid "WiFi connection types" msgstr "WiFi-verbindingstypes" @@ -79843,7 +80528,7 @@ msgstr "" msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -80165,6 +80850,13 @@ msgstr "" "verwarrend zijn.Deze regel moet alleen in het beginstadium worden " "geconfigureerd." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -81102,6 +81794,14 @@ msgid "You can not delete this %s because it is in use." msgstr "" "U kunt deze %s niet verwijderen omdat hij in gebruik is." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"U kunt dit doel niet verwijderen omdat het door deze back-uptaken wordt " +"gebruikt: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -81924,6 +82624,10 @@ msgstr "" "U hebt nog geen agent signature keys aangemaakt. Dit is " "nodig." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Parameters voor deze host" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -83837,9 +84541,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "monitor" - msgid "month" msgstr "maand" @@ -84762,6 +85463,9 @@ msgstr "{actual} is te hoog. De maximaal toegestane waarde is {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} is te laag. De minimaal toegestane waarde is {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -84770,6 +85474,136 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Alle rechten voorbehouden." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Gebruik SSL voor de verbinding." + +#~ msgid "API key from password store" +#~ msgstr "API sleutel van wachtwoord opslag" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Gastheer alarm" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Kan peer-certificaat niet ophalen (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Waarschuwing

    U hebt geen terugval-e-" +#~ "mailadres geconfigureerd en u hebt het ontvangen van terugval-e-mails " +#~ "voor geen enkele gebruiker ingeschakeld. Als uw bewaking een melding " +#~ "genereert die niet overeenkomt met een van uw meldingsregels, zal de " +#~ "melding niet worden verzonden. Om dat te voorkomen, moet u ofwel de " +#~ "globale instelling configureren of de optie voor fallback contact " +#~ "inschakelen voor ten minste één van uw gebruikers." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Bulk meldingen met grafieken (standaard: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Standaard worden alle meervoudige grafieken in emails zwevend naast " +#~ "elkaar getoond. U kunt deze optie aanzetten om de grafieken onder elkaar " +#~ "te tonen." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configureer dit om de meldingsplugin direct verbinding te laten maken met " +#~ "de smtp server. Dit heeft het voordeel dat het betere foutmeldingen geeft " +#~ "in geval van een fout, maar het vereist meer configuratie en is strikt " +#~ "synchroon, dus we adviseren het alleen te gebruiken op " +#~ "bedrijfsinstallaties die de notificatie spooler gebruiken." + +#~ msgid "Display additional information" +#~ msgstr "Aanvullende informatie weergeven" + +#~ msgid "Display graphs among each other" +#~ msgstr "Grafieken onder elkaar weergeven" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Grafieken worden onder elkaar getoond" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "Het e-mailadres en de zichtbare naam die worden gebruikt in de kop Van " +#~ "van kennisgevingen. Als geen e-mailadres wordt opgegeven, wordt standaard " +#~ "OMD_SITE@FQDN gebruikt. Als de omgevingsvariabele OMD_SITE niet is ingesteld, wordt standaard checkmk gebruikt." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "Het e-mailadres en de zichtbare naam die worden gebruikt in de kop Reply-" +#~ "To van kennisgevingen." + +#~ msgid "Activate" +#~ msgstr "Activeer" + +#~ msgid "Deactivate" +#~ msgstr "Deactiveer" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Deze regel maakt monitoring van VMware ESX via de vSphere API mogelijk. U " +#~ "kunt uw verbindingsinstellingen hier configureren." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Deze regelset selecteert de speciale agent voor HPE StoreOnce Appliances " +#~ "in plaats van de normale Checkmk agent en staat monitoring toe via REST " +#~ "API v4.x of hoger. " + +#~ msgid "monitor" +#~ msgstr "monitor" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Naam opslagrekening" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Plan uitvoering" + +#~ msgid "(not supported)" +#~ msgstr "(niet ondersteund)" + +#, fuzzy +#~ msgid "Remove downtimes?" +#~ msgstr "Uitvaltijd verwijderen" + +#, fuzzy +#~ msgid "Schedule downtime?" +#~ msgstr "Uitvaltijden plannen" + +#, fuzzy +#~ msgid "OVS bonding interface status" +#~ msgstr "Koppelvlakken" + #~ msgid "Common Name" #~ msgstr "Gebruikelijke naam" @@ -84897,10 +85731,6 @@ msgstr "© %s Checkmk GmbH. Alle rechten voorbehouden." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Gebruikt quotum: Absolute of relatieve bovengrenzen" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "Is nooit geactiveerd geweest" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Tafelspaces" @@ -85198,10 +86028,6 @@ msgstr "© %s Checkmk GmbH. Alle rechten voorbehouden." #~ msgid "%s operations" #~ msgstr "%s operaties" -#, fuzzy, python-format -#~ msgid "%s requests" -#~ msgstr "%s Verzoeken" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -85541,9 +86367,6 @@ msgstr "© %s Checkmk GmbH. Alle rechten voorbehouden." #~ msgid "InfluxDB Queue Usage" #~ msgstr "InfluxDB wachtrijgebruik" -#~ msgid "Kernel Version" -#~ msgstr "Kernel Versie" - #~ msgid "Levels Helper usage Check" #~ msgstr "Niveaus Helper gebruik Check" diff --git a/locale/pt_PT/LC_MESSAGES/multisite.po b/locale/pt_PT/LC_MESSAGES/multisite.po index b6f4997738b..b876a0f9869 100644 --- a/locale/pt_PT/LC_MESSAGES/multisite.po +++ b/locale/pt_PT/LC_MESSAGES/multisite.po @@ -408,6 +408,10 @@ msgstr "%d dias" msgid "%d days ago" msgstr "%d dias atrás" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Propriedades Gerais" + #, python-format msgid "%d errors occured:" msgstr "%d erros ocorridos:" @@ -570,6 +574,10 @@ msgstr "%s por servidor" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -690,6 +698,10 @@ msgstr "%s rate" msgid "%s resulting notifications" msgstr "Notificações resultantes" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s Pedidos" + #, python-format msgid "%s running for %s" msgstr "%s a correr por %s" @@ -806,9 +818,17 @@ msgstr "" "versionar a configuração. Por favor, instale o 'git' ou desactive o git no " "WATO." +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Entradas removidas" + msgid "(0 is current period)" msgstr "(0 é o período atual)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(sem entrada)" + msgid "(Edit presets)" msgstr "Editar Presets" @@ -884,9 +904,6 @@ msgstr "(sem título)" msgid "(none)" msgstr "(nenhuma)" -msgid "(not supported)" -msgstr "(não suportado)" - msgid "(nothing selected)" msgstr "(nada seleccionado)" @@ -995,6 +1012,10 @@ msgstr "1 mudança" msgid "1 row" msgstr "1 fila" +#, fuzzy +msgid "1 rule" +msgstr "regra" + msgid "1 year" msgstr "1 ano" @@ -1184,6 +1205,31 @@ msgstr "Percentil 95" msgid "99th percentile" msgstr "Percentil 99" +#, fuzzy +msgid "< Remove" +msgstr "Remover" + +#, fuzzy +msgid "<< Remove all" +msgstr "Remover tudo" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Piggybacktranslationssão executadas antes de o conector piggyback criar hosts. Use isso, por " +"exemplo, em uma configuração com vários nós do Docker para prefixar " +"contêineres com o nome do nó do Docker correspondente. Caso contrário, podem " +"ocorrer colisões de nomes se existirem contentores com o mesmo nome em mais " +"do que um nó Docker." + msgid "" "PiggybacktranslationsNota: Se migrar para o conector htpasswd, os utilizadores " "terão de alterar a sua palavra-passe no início de sessão seguinte." +#, fuzzy msgid "" "Note3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Nota3: Para implementar este plugin no Solaris, uma " @@ -1347,6 +1394,12 @@ msgstr "Aviso: Há %d werks incompatíveis não reconhecidos:" msgid "You do not have any roles." msgstr "Você não tem nenhum papel." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1930,7 +1983,7 @@ msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" #, python-format @@ -2110,6 +2163,14 @@ msgstr "Um título para os gráficos" msgid "A heading for the view" msgstr "Um título para a vista" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"Já existe um hospedeiro com o nome %s na pasta
    %s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Adicionar %s" + msgid "Add Aggregation" msgstr "Adicionar Agregação" @@ -3623,10 +3701,6 @@ msgstr "Adicionar Exceção" msgid "Add Group" msgstr "Adicionar Grupo" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"Adicionar secção HTML acima da tabela (por exemplo, título, descrição...)" - msgid "Add LDAP connection" msgstr "Adicionar conexão LDAP" @@ -3672,6 +3746,9 @@ msgstr "Adicionar agregação" msgid "Add alert handler rule" msgstr "Adicionar regra do manipulador de alerta" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Adicione todos os serviços detectados mas ainda não monitorados ao " @@ -3774,6 +3851,10 @@ msgstr "Adicionar elemento: %s" msgid "Add elements to your sidebar" msgstr "Adicione elementos à sua barra lateral" +#, fuzzy +msgid "Add event" +msgstr "Adicionar elemento" + msgid "Add exception" msgstr "Adicionar exceção" @@ -3965,6 +4046,10 @@ msgstr "Adicionar condição de etiqueta" msgid "Add new pattern" msgstr "Adicionar novo padrão" +#, fuzzy +msgid "Add new plan" +msgstr "Adicionar novo padrão" + msgid "Add new project" msgstr "Adicionar novo projeto" @@ -3980,10 +4065,18 @@ msgstr "Adicionar nova regra" msgid "Add new scalar" msgstr "Adicionar novo escalar" +#, fuzzy +msgid "Add new sequence" +msgstr "Adicionar novo serviço" + #, fuzzy msgid "Add new service" msgstr "Adicionar novo serviço" +#, fuzzy +msgid "Add new smarthost" +msgstr "Adicionar nova macro" + msgid "Add new status" msgstr "Adicionar novo estado" @@ -4026,6 +4119,10 @@ msgstr "Adicionar ou modificar executáveis" msgid "Add page element" msgstr "Adicionar elemento de página" +#, fuzzy +msgid "Add parameter" +msgstr "Parâmetros do modelo" + msgid "Add pattern" msgstr "Adicionar padrão" @@ -4051,6 +4148,10 @@ msgstr "Adicionar pré ou pós-fixo a TNSALIASes %s" msgid "Add random hosts" msgstr "Adicionar hospedeiros aleatórios" +#, fuzzy +msgid "Add recipient" +msgstr "Destinatário" + msgid "Add remote instance" msgstr "Adicionar instância remota" @@ -4299,6 +4400,10 @@ msgstr "Endereços IPv6 adicionais" msgid "Additional agent labels to send during registration" msgstr "Etiquetas de agente adicionais a enviar durante o registo" +#, fuzzy +msgid "Additional details" +msgstr "Opções adicionais" + msgid "Additional header lines" msgstr "Linhas de cabeçalho adicionais" @@ -4427,7 +4532,7 @@ msgid "Admin states to discover" msgstr "Estados administrativos a descobrir" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "Estados administrativos" msgid "Administrative port states to discover" @@ -5111,6 +5216,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "Configuração do gestor de alertas" +#, fuzzy +msgid "Alert handler execution" +msgstr "Alerta de execuções de manipuladores" + msgid "Alert handler execution, failed" msgstr "Alerta de execução do manipulador, falhou" @@ -5224,6 +5333,15 @@ msgstr "Estatísticas de Alerta: Número de alertas desconhecidos" msgid "Alert statistics: Number of warnings" msgstr "Estatísticas de Alerta: Número de alertas" +msgid "Alert when a major version release is available" +msgstr "" + +msgid "Alert when a minor version release is available" +msgstr "" + +msgid "Alert when a patch version release is available" +msgstr "" + msgid "Alerted" msgstr "Alertado" @@ -5330,6 +5448,10 @@ msgstr "Todas as colecções" msgid "All components" msgstr "Todos os componentes" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Todos os contactos do objecto notificado" + msgid "All contacts of the notified object" msgstr "Todos os contactos do objecto notificado" @@ -5773,6 +5895,10 @@ msgstr "Permitir ver o ícone %s nas vistas do host e do serviço" msgid "Allow unencrypted legacy communication" msgstr "Permitir comunicações herdadas não encriptadas" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "permitir que os usuários desativem esta notificação" + msgid "Allowed Ciphers" msgstr "Cifras permitidas" @@ -6380,6 +6506,10 @@ msgstr "Outra sincronização de usuários já está em execução: %s" msgid "AntiVirus last update age" msgstr "AntiVirus última era de actualização" +#, fuzzy +msgid "Any" +msgstr "qualquer" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6559,9 +6689,21 @@ msgstr "Visão geral das aplicações" msgid "Applications, Processes & Services" msgstr "Aplicações, Processos e Serviços" +#, fuzzy +msgid "Applied to" +msgstr "Aplicar para" + msgid "Apply" msgstr "Candidate-se" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Regra do manipulador de alertas" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Eliminar esta regra de notificação" + #, fuzzy msgid "Apply Latency" msgstr "Latência" @@ -6584,6 +6726,11 @@ msgstr "Aplicar condições" msgid "Apply filters" msgstr "Aplicar filtros" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Aplicar tempo de acabamento" @@ -6718,6 +6865,10 @@ msgstr "Obter registos de auditoria remotos" msgid "Archive event" msgstr "Evento de Arquivo" +#, fuzzy +msgid "Archive event?" +msgstr "Evento de Arquivo" + msgid "Archive events" msgstr "Arquivo de eventos" @@ -6852,6 +7003,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Tradução do nome do anfitrião para os anfitriões piggybacked" @@ -7294,10 +7450,10 @@ msgstr "Autoextensível" msgid "Automated environment setup (via RCC)" msgstr "" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Use SSL para a conexão." msgid "Automatic" @@ -8662,6 +8818,10 @@ msgstr "Agentes cozidos" msgid "Baked host specific agent" msgstr "Agente específico do hospedeiro assado" +#, fuzzy +msgid "Bakery rules" +msgstr "Regras de Descoberta" + msgid "Baking Agents..." msgstr "Agentes de panificação..." @@ -9198,8 +9358,9 @@ msgstr "Importação a granel" msgid "Bulk move" msgstr "Movimento a granel" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Notificações em massa com gráficos (padrão: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Notificações em massa abertas" msgid "Bulk removal of explicit attributes" msgstr "Remoção em massa de atributos explícitos" @@ -9562,14 +9723,6 @@ msgstr "" "personalizar as credenciais a utilizar quando se contactam anfitriões " "através de SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"Por padrão, todos os gráficos múltiplos em e-mails são exibidos flutuando " -"nas proximidades. Você pode habilitar esta opção para mostrar os gráficos " -"entre si." - msgid "By default all of the sections will be executed." msgstr "Por padrão, todas as seções serão executadas." @@ -9752,14 +9905,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" msgid "" @@ -9768,7 +9921,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" msgid "" @@ -10036,8 +10189,8 @@ msgstr "Todos os gráficos para um determinado anfitrião." msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11292,6 +11445,10 @@ msgstr "Ligação LDAP alterada %s" msgid "Changed alert handler rule %d" msgstr "Alteração da regra do manipulador de alertas %d" +#, fuzzy +msgid "Changed by" +msgstr "Alterado" + msgid "Changed entries" msgstr "Entradas alteradas" @@ -11307,6 +11464,14 @@ msgstr[1] "Etiquetas de anfitrião alteradas: " msgid "Changed host selection has been saved." msgstr "A seleção de host modificada foi salva." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Regra de notificação modificada %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Regra de notificação modificada %d" + #, python-format msgid "Changed notification rule %d" msgstr "Regra de notificação modificada %d" @@ -11326,6 +11491,10 @@ msgstr "Posição alterada de %s %d" msgid "Changed position of connection %s to %d" msgstr "Posição alterada da ligação %s para %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "Posição alterada da regra de notificação %d de usuário %s" + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "Posição alterada da regra de notificação %d de usuário %s" @@ -11383,6 +11552,10 @@ msgstr "Mudou a variável de configuração específica do local %s para %s." msgid "Changes" msgstr "Mudanças" +#, fuzzy +msgid "Changes activated" +msgstr "Nunca foi ativado" + msgid "Changes since last dump" msgstr "Mudanças desde a última lixeira" @@ -12688,6 +12861,11 @@ msgstr "Clique aqui para ver o status de ativação por site." msgid "Click on 'Register %s' to enable two-factor authentication via %s." msgstr "Remover a autenticação de dois factores de %s" +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Clique para activar esta definição" @@ -12847,6 +13025,10 @@ msgstr "Clonar esta conexão para criar uma nova" msgid "Clone this element" msgstr "Clonar este elemento" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Objetos Gerenciados" + msgid "Clone this metric" msgstr "Clonar esta métrica" @@ -13403,6 +13585,10 @@ msgstr "Complete a restauração" msgid "Complete tree" msgstr "Árvore completa" +#, fuzzy +msgid "Complete variable list" +msgstr "Lista completa de variáveis (para testes)" + msgid "Complete variable list (for testing)" msgstr "Lista completa de variáveis (para testes)" @@ -13545,6 +13731,10 @@ msgstr "Arquivos de configuração ('*.mk' ou '*.conf') de etc/checkmk: %s" msgid "Configuration generation" msgstr "Geração da configuração" +#, fuzzy +msgid "Configuration name" +msgstr "Configuração" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "Configuração da componente de Business Intelligence da Checkmk" @@ -13616,6 +13806,10 @@ msgstr "Configure" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Monitorização de Amazon Web Services (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Monitorização de Amazon Web Services (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "" "Configure as configurações relacionadas ao SNMP usando conjuntos de regras" @@ -13683,6 +13877,10 @@ msgstr "Relatório de acidente fallback endereço postal" msgid "Configure grouping of interfaces" msgstr "Configurar o agrupamento de interfaces" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configuração" + #, fuzzy msgid "Configure host and regions" msgstr "Configuração" @@ -13908,6 +14106,10 @@ msgstr "" "Configurar o nome da variável do cabeçalho da solicitação HTTP para ler a " "partir das solicitações HTTP de entrada" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configurar a descoberta de interfaces únicas" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13939,20 +14141,6 @@ msgstr "" "chave do usuário ou grupo aqui. A chave pode ser obtida a partir do site " "Pushover." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configurando isto para que o plugin de notificação se conecte diretamente ao " -"servidor smtp. Isto tem a vantagem de fornecer melhores mensagens de erro em " -"caso de erro, mas requer mais configuração e é estritamente síncrono, por " -"isso aconselhamos o uso apenas em instalações empresariais utilizando o " -"spooler de notificação." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14352,6 +14540,10 @@ msgstr "Contato" msgid "Contact Name" msgstr "Nome para contato" +#, fuzzy +msgid "Contact group" +msgstr "Grupos de contato" + msgid "Contact group (effective)" msgstr "Grupo de contato (efetivo)" @@ -14509,6 +14701,10 @@ msgstr "Informações do contexto" msgid "Context information about this connection" msgstr "Informações de contexto sobre esta conexão" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Informações de contexto sobre esta regra" + msgid "Context information about this rule" msgstr "Informações de contexto sobre esta regra" @@ -14768,6 +14964,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase: Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, fuzzy, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -15058,6 +15259,10 @@ msgstr "Criar uma cópia desta ligação" msgid "Create a copy of this group" msgstr "Criar uma cópia deste grupo" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Criar uma cópia desta regra de notificação" + msgid "Create a copy of this notification rule" msgstr "Criar uma cópia desta regra de notificação" @@ -15143,6 +15348,11 @@ msgstr "Criar serviço adicional para solicitações de estatísticas IO" msgid "Create additional service for system wait" msgstr "Criar serviço adicional para System Wait" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Criar uma anotação para este período" @@ -15254,6 +15464,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Criar um cronograma regular para este relatório" +#, fuzzy +msgid "Create robot" +msgstr "Criar anfitriões" + msgid "Create separate notification bulks based on" msgstr "Criar bulks de notificação separados com base em" @@ -15355,6 +15569,10 @@ msgstr "Criado novo anfitrião %s." msgid "Created new host tag group '%s'" msgstr "Criado novo grupo de tags de anfitrião '%s'" +#, fuzzy +msgid "Created new notification parameter" +msgstr "Criada nova regra de notificação" + msgid "Created new notification rule" msgstr "Criada nova regra de notificação" @@ -15799,6 +16017,11 @@ msgstr "Desenho GUI personalizado de %s" msgid "Custom Graph" msgstr "Gráfico personalizado" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "" +"Adicionar secção HTML acima da tabela (por exemplo, título, descrição...)" + msgid "Custom Icons" msgstr "Ícones personalizados" @@ -15905,6 +16128,14 @@ msgstr "Localizações personalizadas" msgid "Custom logos" msgstr "Logótipos personalizados" +#, fuzzy +msgid "Custom macro" +msgstr "Macros de Cliente" + +#, fuzzy +msgid "Custom macros" +msgstr "Macros de Cliente" + #, python-format msgid "Custom notification table for user %s" msgstr "Tabela de notificação personalizada para usuários %s" @@ -15919,9 +16150,15 @@ msgstr "Estado da sonda personalizada" msgid "Custom profile" msgstr "Título personalizado" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Consulta de pesquisa personalizada" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Atributos de serviço personalizados" @@ -16761,9 +16998,6 @@ msgstr "Preço por dia" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Desativar" - msgid "Deactivated" msgstr "Desativado" @@ -17057,6 +17291,9 @@ msgstr "Perfil de usuário predefinido" msgid "Default value" msgstr "Valor por defeito" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "Idade dos arquivos diferidos" @@ -17112,6 +17349,9 @@ msgstr "" "monitorização, ou seja, para o resultado da verificação. Isso sobregrava o " "mapeamento padrão usado pela verificação." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Definir atribuição de anfitrião" @@ -17151,6 +17391,9 @@ msgstr "Definir níveis inferiores para o número de contentores em espera" msgid "Define name of NetBIOS server" msgstr "Definir o nome do servidor NetBIOS" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17395,6 +17638,10 @@ msgstr "Eliminar a tecla de cópia de segurança #%d" msgid "Delete comments" msgstr "Eliminar comentários" +#, fuzzy +msgid "Delete comments?" +msgstr "Eliminar comentários" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Configuração predefinida" @@ -17462,6 +17709,14 @@ msgstr "Apagar o trabalho #%d" msgid "Delete last alert handler rule" msgstr "Eliminar a última regra do manipulador de alerta" +#, fuzzy +msgid "Delete managed robot" +msgstr "Objetos Gerenciados" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Eliminar regra de notificação #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Eliminar regra de notificação #%d" @@ -17615,9 +17870,17 @@ msgstr "Apagar esta chave" msgid "Delete this logo" msgstr "Eliminar este logótipo" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Eliminar este grupo de etiquetas" + msgid "Delete this metric" msgstr "Eliminar esta métrica" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Eliminar esta regra de notificação" + msgid "Delete this notification rule" msgstr "Eliminar esta regra de notificação" @@ -17715,6 +17978,10 @@ msgstr "Pasta eliminada %s" msgid "Deleted host %s" msgstr "Eliminado %s do anfitrião" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Eliminar regra de notificação #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Eliminada regra de notificação %d de usuário %s" @@ -18646,6 +18913,10 @@ msgstr "Desabilitar o manuseio de proxy" msgid "Disable remote configuration" msgstr "Desactivar a configuração remota" +#, fuzzy +msgid "Disable rule" +msgstr "Desactivar tudo" + msgid "Disable service notifications" msgstr "Desativar notificações de serviço" @@ -19016,9 +19287,6 @@ msgstr "" "Exibir um aviso se um LUN não for apenas de leitura. Sem esta configuração " "será exibido um aviso se um LUN for apenas de leitura." -msgid "Display additional information" -msgstr "Apresentar informações adicionais" - msgid "Display additional messages" msgstr "Exibir mensagens adicionais" @@ -19044,9 +19312,6 @@ msgstr "" msgid "Display dashboard title" msgstr "Mostrar título do painel de instrumentos" -msgid "Display graphs among each other" -msgstr "Mostrar gráficos entre si" - msgid "Display historic data since the last" msgstr "Exibir dados históricos desde a última" @@ -19944,6 +20209,10 @@ msgstr "Delta de contagem de documentos" msgid "Document count growth per minute" msgstr "Crescimento da contagem de documentos por minuto" +#, fuzzy +msgid "Documentation" +msgstr "URL da documentação" + msgid "Documentation URL" msgstr "URL da documentação" @@ -20720,6 +20989,10 @@ msgstr "Editar" msgid "Edit %s" msgstr "Editar %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Editar regra de notificação %d" + #, python-format msgid "Edit %s: %s" msgstr "Editar %s: %s" @@ -20870,6 +21143,10 @@ msgstr "Editar layout" msgid "Edit layout only available if header is enabled" msgstr "O esquema de edição só está disponível se o cabeçalho estiver activado" +#, fuzzy +msgid "Edit managed robots" +msgstr "Objetos Gerenciados" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Editar conexão ao site %s" @@ -21029,6 +21306,14 @@ msgstr "Editar este elemento" msgid "Edit this host" msgstr "Editar este anfitrião" +#, fuzzy +msgid "Edit this managed robot" +msgstr "Estados administrativos" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Editar esta regra de notificação" + msgid "Edit this notification rule" msgstr "Editar esta regra de notificação" @@ -21100,6 +21385,9 @@ msgstr "Perfil de utilizador editado para o utilizador %s" msgid "Edition" msgstr "Edição" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "Estado efectivo" @@ -21284,6 +21572,14 @@ msgstr "Endereço de correio electrónico utilizado para identificação da cont msgid "Email addresses to mail PDF reports to" msgstr "Endereços de e-mail para enviar relatórios em PDF para" +#, fuzzy +msgid "Email body/content" +msgstr "E-mail enviado" + +#, fuzzy +msgid "Email header" +msgstr "Endereço de e-mail" + msgid "Email sent" msgstr "E-mail enviado" @@ -22291,6 +22587,10 @@ msgstr "Comentário do evento" msgid "Event console" msgstr "Console do evento" +#, fuzzy +msgid "Event console alerts" +msgstr "Alertas de Console de Eventos" + msgid "Event console performance" msgstr "Desempenho do console de eventos" @@ -23516,10 +23816,6 @@ msgstr "Falha em renderizar valor:" msgid "Failed to render value: %r" msgstr "Falha em renderizar valor: %r" -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Falha na obtenção do certificado do par (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -23629,6 +23925,10 @@ msgstr "" "resultados de nós adicionais irão, pelo menos, desencadear um estado de " "AVISO." +#, fuzzy +msgid "Failure" +msgstr "falhas" + msgid "Failures of the join launcher service" msgstr "Falhas do serviço de lançadores" @@ -23927,6 +24227,10 @@ msgstr "Tamanho do arquivo abaixo" msgid "File size levels" msgstr "Níveis de tamanho de arquivo" +#, fuzzy +msgid "File upload" +msgstr "Bytes carregados" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -24055,6 +24359,10 @@ msgstr "" "Filtro para todas as agregações que se baseiam nas informações de status " "daquele hospedeiro. Combinação exacta (sem expressão regular)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Tempo de inactividade para o anfitrião/serviço" + msgid "Filter group (see help)" msgstr "Grupo de filtros (ver ajuda)" @@ -24728,6 +25036,9 @@ msgstr "Redes" msgid "Form factor" msgstr "Factor de forma" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Formato" @@ -25363,6 +25674,11 @@ msgstr "Gerar" msgid "Generate REST API specification" msgstr "Especificação do SLA" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + #, fuzzy msgid "Generate backup codes" msgstr "Regenerar códigos de backup" @@ -25431,6 +25747,21 @@ msgstr "Taxa genérica" msgid "Generic string" msgstr "Cordão genérico" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Versão Kernel" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Editar conexão" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "Jenkins exemplo a consultar." + msgid "Get file from SFTP server" msgstr "Obter ficheiro a partir do servidor SFTP" @@ -25490,6 +25821,10 @@ msgstr "Regra de notificação global" msgid "Global notification rules" msgstr "Regras de notificação global" +#, fuzzy +msgid "Global services" +msgstr "Todos os serviços" + msgid "Global services to monitor" msgstr "Serviços globais para monitorar" @@ -25516,6 +25851,10 @@ msgstr "Padrão de Globbing para arquivos de entrada" msgid "Go critical if all licenses are used" msgstr "Fique crítico se todas as licenças forem utilizadas" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Todos os anfitriões" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25528,6 +25867,12 @@ msgstr "Ir para a página principal" msgid "Go to rules of this InfluxDB connection" msgstr "Ir para as regras desta ligação InfluxDB" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "Aceder ao painel de administração do Saas" @@ -25691,18 +26036,12 @@ msgstr "Cartões Gráficos" msgid "Graphs" msgstr "Gráficos" -msgid "Graphs are shown among each other" -msgstr "Os gráficos são mostrados entre si" - msgid "Graphs for averaged single-core utilizations" msgstr "Gráficos para médias de utilizações single-core" msgid "Graphs for individual cores" msgstr "Gráficos para núcleos individuais" -msgid "Graphs per notification (default: 5)" -msgstr "Gráficos por notificação (padrão: 5)" - msgid "Graylog" msgstr "Graylog" @@ -25791,10 +26130,6 @@ msgstr "DN base do grupo" msgid "Group discovery and activation for up to" msgstr "Descoberta e ativação de grupo para até" -#, fuzzy -msgid "Group execution interval" -msgstr "Intervalo de execução" - msgid "Group files based on a regular expression pattern." msgstr "Arquivos de grupo baseados em um padrão de expressão regular." @@ -25994,6 +26329,10 @@ msgstr "HPE StoreOnce via REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: Memória usada via SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Parâmetros do modelo" + #, fuzzy msgid "HTML email" msgstr "E-mail HTML" @@ -27335,6 +27674,10 @@ msgstr "Ocultar nomes de variáveis de configuração" msgid "Hide notification bulks" msgstr "regra de notificação" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Enviar notificações separadas para cada destinatário" + msgid "Hide response from socket" msgstr "Ocultar resposta da tomada" @@ -27401,6 +27744,10 @@ msgstr "História" msgid "History Line Number" msgstr "Número da linha de história" +#, fuzzy +msgid "History action type" +msgstr "Estado de registo" + msgid "History entries of one specific event" msgstr "Entradas históricas de um evento específico" @@ -29080,10 +29427,6 @@ msgstr "Visão geral do anfitrião" msgid "Host parent/child topology" msgstr "Topologia do pai/mãe anfitrião/criança" -#, fuzzy -msgid "Host path" -msgstr "Alerta do anfitrião" - msgid "Host performance data" msgstr "Dados de desempenho do host" @@ -29792,6 +30135,10 @@ msgstr "IP - região - ID da instância" msgid "IP Address" msgstr "Endereço IP" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "Endereço IP do Host" + msgid "IP address" msgstr "endereço IP" @@ -31771,20 +32118,6 @@ msgstr "" "monitorizados. Note que isto diz respeito a tudo o que faz parte dos " "namespaces correspondentes, como as cápsulas, por exemplo." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Aviso>>br>>br>Você não configurou um fallback email " -"address nem habilitou o recebimento de fallback emails para nenhum " -"usuário. Se a sua monitorização produzir uma notificação que não corresponda " -"a nenhuma das suas regras de notificação, a notificação não será enviada. " -"Para evitar isso, por favor configure a configuração global ou habilite a " -"opção de contato fallback para pelo menos um de seus usuários." - msgid "Ignore" msgstr "Ignorar" @@ -32758,6 +33091,14 @@ msgstr "" msgid "Indexspace wasted" msgstr "Espaço de índice desperdiçado" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Se a última descoberta em massa falhou ou não. É definido como Verdadeiro se " +"falhar e não é definido se uma descoberta posterior for bem sucedida." + msgid "Indices" msgstr "Índices" @@ -33421,6 +33762,10 @@ msgstr "Certificado inválido" msgid "Invalid certificate file: %s" msgstr "Arquivo de certificado inválido: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Parâmetro inválido %r: %s" + msgid "Invalid check parameter" msgstr "Parâmetro de verificação inválido" @@ -36241,6 +36586,10 @@ msgstr "Inventário Multipath Linux" msgid "Linux and Solaris Multipath Count" msgstr "Linux e Solaris Multipath Count" +#, fuzzy +msgid "Linux bonding" +msgstr "ligação por troca de chaves" + msgid "Linux bonding interface status" msgstr "Status da interface Linux bonding" @@ -36833,6 +37182,10 @@ msgstr "" "Registar o processo de registo de agentes dos pedidos recebidos através do " "comando Checkmk agent controller registration." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Activar a remoção automática do anfitrião" + msgid "Log: Details" msgstr "Registo: Detalhes" @@ -37343,6 +37696,10 @@ msgstr "" "Número total de clientes pendentes em uma chamada de bloqueio de nível " "inferior" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Lista de ficheiros de registo esperados" + msgid "Lowest: No notification, update badge number" msgstr "O mais baixo: Sem notificação, atualizar número do crachá" @@ -37920,10 +38277,25 @@ msgstr "Gerencie os usuários do sistema de monitoramento." msgid "Managed Robot" msgstr "Objetos Gerenciados" +#, fuzzy +msgid "Managed Robots" +msgstr "Objetos Gerenciados" + #, fuzzy msgid "Managed objects" msgstr "Objetos Gerenciados" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Objetos Gerenciados" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Objetos Gerenciados" + msgid "Management board" msgstr "Conselho de Administração" @@ -39495,14 +39867,14 @@ msgstr "Ligações mínimas por segundo" msgid "Minimum error count" msgstr "Contagem mínima de erros" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Níveis mínimos de tensão" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Níveis mínimos de carga em percentagem" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Níveis mínimos de tensão" + msgid "Minimum levels if using magic factor" msgstr "Níveis mínimos se usar factor mágico" @@ -39611,6 +39983,10 @@ msgstr "Duração não programada (apenas DaemonSet)" msgid "Misscheduled replicas" msgstr "Réplicas não programadas" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Siteid variável em falta" + #, python-format msgid "Missing config file for agent %s%s" msgstr "Ficheiro de configuração em falta para o agente %s%s" @@ -41095,6 +41471,11 @@ msgstr "Resolução do nome" msgid "Name your %s for easy recognition." msgstr "Dê um nome ao seu %s para facilitar o reconhecimento." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -41109,13 +41490,13 @@ msgstr "Nomes" msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" @@ -41524,6 +41905,29 @@ msgstr "Próxima notificação" msgid "Next run" msgstr "Próxima execução" +#, fuzzy +msgid "Next step: General properties" +msgstr "Propriedades Gerais" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugins de notificação" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Destinatário" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "ligações pendentes" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Tipo de comentário (anfitrião/serviço)" + msgid "Nginx Server" msgstr "Servidor Nginx" @@ -41539,6 +41943,10 @@ msgstr "Níveis de IO ágeis" msgid "No" msgstr "Não" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Configuração do anfitrião" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "Não (Erro: %s, Código: %d, Profundidade: %d)" @@ -41546,6 +41954,10 @@ msgstr "Não (Erro: %s, Código: %d, Profundidade: %d)" msgid "No API integrations, no Checkmk agent" msgstr "Sem integrações de API, sem agente Checkmk" +#, fuzzy +msgid "No AWS services found." +msgstr "Não foram encontrados hospedeiros/serviços." + msgid "No CSRF token received" msgstr "Nenhum token CSRF recebido" @@ -41556,6 +41968,10 @@ msgstr "Sem condições" msgid "No Configuration Quick setup for %s available" msgstr "Variável de configuração:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Regra de notificação modificada %d" + msgid "No IP" msgstr "Sem IP" @@ -41633,10 +42049,6 @@ msgstr "Não são possíveis comandos nesta vista" msgid "No conditions" msgstr "Sem condições" -#, fuzzy -msgid "No configuration yet" -msgstr "Configuração do anfitrião" - msgid "No configured rules are affected" msgstr "Nenhuma regra configurada é afetada" @@ -41692,6 +42104,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "não disponíveis" + +#, fuzzy +msgid "No elements selected" +msgstr "Não selecionado" + msgid "No entries" msgstr "Nenhuma entrada" @@ -41822,6 +42242,10 @@ msgstr "Nenhuma ligação definida" msgid "No need for syncing sites" msgstr "Não é necessário sincronizar sítios" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Regra de notificação modificada %d" + msgid "No object type" msgstr "Nenhum tipo de objeto" @@ -41833,6 +42257,10 @@ msgstr "" msgid "No password provided" msgstr "Da loja de senhas" +#, fuzzy +msgid "No password selected" +msgstr "Da loja de senhas" + msgid "No pending changes" msgstr "Sem alterações pendentes" @@ -41910,6 +42338,10 @@ msgstr "Nenhuma busca" msgid "No search, specify list of arguments" msgstr "Sem pesquisa, especificar lista de argumentos" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthosts" + msgid "No snapshot to restore available." msgstr "Não está disponível nenhum instantâneo para restauro." @@ -42370,6 +42802,9 @@ msgstr "Notificação" msgid "Notation: %s" msgstr "Anotação: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42536,6 +42971,18 @@ msgstr "Nível de log de notificação" msgid "Notification method" msgstr "Método de Notificação" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "A colecção de gráficos '%s' não existe" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugins de notificação" + +#, fuzzy +msgid "Notification parameter" +msgstr "Fase de notificação" + #, fuzzy msgid "Notification period" msgstr "Período de Notificação" @@ -42980,6 +43427,14 @@ msgstr "Número de pastas a criar em cada nível" msgid "Number of goroutines" msgstr "Número de tentativas" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Gráficos por notificação (padrão: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Gráficos por notificação (padrão: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Número de hospedeiros saudáveis níveis inferiores" @@ -43619,8 +44074,8 @@ msgid "OTLP endpoint" msgstr "Ponto final" #, fuzzy -msgid "OVS bonding interface status" -msgstr "Interfaces de colagem" +msgid "OVS bonding" +msgstr "ligação por troca de chaves" msgid "Object" msgstr "Objeto" @@ -45654,6 +46109,10 @@ msgstr "Acontecimentos gerais actuais" msgid "Overall latency" msgstr "Latência geral" +#, fuzzy +msgid "Overall response time" +msgstr "Tempo médio de resposta" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "Estado geral de uma máquina virtual (por exemplo, ESX VMs)" @@ -45716,7 +46175,7 @@ msgstr "" "Substituir o estado de verificação com base no resultado da última construção" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Substituir unidade de sensor" msgid "Override unit of sensor" @@ -46310,13 +46769,16 @@ msgstr "Carga das ligações paralelas" msgid "Parallel pings to send" msgstr "Pings paralelos para enviar" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Programação da execução" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Paralelizar a criação da configuração do núcleo" +#, fuzzy +msgid "Parameter" +msgstr "Parâmetros" + msgid "Parameter groups" msgstr "Grupos de parâmetros" @@ -46326,6 +46788,10 @@ msgstr "Grupos de parâmetros por região" msgid "Parameter name" msgstr "Nome do parâmetro" +#, fuzzy +msgid "Parameter properties" +msgstr "Propriedades do pacote" + msgid "Parameter rule set" msgstr "Conjunto de regras de parâmetros" @@ -46350,6 +46816,10 @@ msgstr "" "você pode inserir o valor real dos parâmetros por $HOST$ e $INST" "$ (incluído em sinais de dólar)." +#, fuzzy +msgid "Parameters for" +msgstr "Parâmetros para %s" + #, python-format msgid "Parameters for %s" msgstr "Parâmetros para %s" @@ -46357,6 +46827,10 @@ msgstr "Parâmetros para %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parâmetros para fases de entrada de UPSs e PDUs" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Parâmetros para este anfitrião" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parâmetros para cargas de saída de UPSs e PDUs" @@ -47397,6 +47871,10 @@ msgstr "Pingar o endereço IP normal" msgid "Ping timeout" msgstr "Ping timeout" +#, fuzzy +msgid "Placeholder" +msgstr "Colocar VMs de suporte" + msgid "Placeholder VMs" msgstr "Colocar VMs de suporte" @@ -47446,6 +47924,10 @@ msgid "" "be unique." msgstr "Mapear combinações de estado operacional e administrativo" +#, fuzzy +msgid "Plan settings" +msgstr "Configurações globais" + msgid "Plans" msgstr "" @@ -47473,6 +47955,10 @@ msgstr "Por favor, adicione pelo menos uma coluna à sua vista." msgid "Please add at least one endpoint to monitor" msgstr "Por favor, adicione pelo menos uma coluna à sua vista." +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Por favor, acrescente pelo menos um nó de criança." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47536,6 +48022,10 @@ msgstr "Por favor, escolha uma imagem PNG válida." msgid "Please choose an audit log to view:" msgstr "Por favor, escolha um arquivo para carregar." +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Por favor, escolha um relatório para agendar" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Por favor escolha o plugin de verificação" @@ -48191,6 +48681,10 @@ msgstr "Plugins, verificações locais e MRPE para usuários não-rooticiais" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Saída do Plugin" + msgid "Plugins" msgstr "Plugins" @@ -48332,6 +48826,10 @@ msgstr "Partida positiva (Adicionar hospedeiros correspondentes ao conjunto)" msgid "Positive match (Add matching services to the set)" msgstr "Combinação positiva (Adicionar serviços de combinação ao conjunto)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Partida positiva (Adicionar hospedeiros correspondentes ao conjunto)" + msgid "Postfix" msgstr "Postfix" @@ -48515,6 +49013,10 @@ msgstr "Texto do prefixo" msgid "Prepare AWS for Checkmk" msgstr "GIT Inicializado para Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "GIT Inicializado para Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Prefixo do espaço de nomes para os anfitriões" @@ -49172,11 +49674,10 @@ msgstr "Execução de plugin de agente Python (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" #, fuzzy @@ -49411,14 +49912,15 @@ msgstr "Ler exe médio" msgid "RCC profile configuration" msgstr "Configuração remota" -#, fuzzy, python-format +#, fuzzy msgid "" -"RCC profile configuration (%s because Robotmk Core MKP has been installed)" +"RCC profile configuration (⚠ not available because Robotmk Core MKP " +"has been installed)" msgstr "Use SSL para a conexão." msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" msgid "RCU" @@ -50025,6 +50527,10 @@ msgstr "Destinatário" msgid "Recipient email address" msgstr "Endereço de e-mail do destinatário" +#, fuzzy +msgid "Recipients" +msgstr "Destinatário" + #, python-format msgid "Recipients: %s" msgstr "Beneficiários: %s" @@ -50535,6 +51041,10 @@ msgstr "Vida restante" msgid "Remaining Open Slots" msgstr "Restantes Caça-níqueis Abertos" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Restantes dias de validade" + msgid "Remaining credits lower levels" msgstr "Créditos remanescentes níveis inferiores" @@ -50696,9 +51206,6 @@ msgstr "Remover todos os arquivos e subdiretórios" msgid "Remove downtimes" msgstr "Remover tempos de paragem" -msgid "Remove downtimes?" -msgstr "Eliminar os tempos de inatividade?" - msgid "Remove explicit attribute settings" msgstr "Remover definições de atributos explícitas" @@ -50728,6 +51235,10 @@ msgstr "Remover todos os tempos de inatividade programados?" msgid "Remove service" msgstr "Remover serviço" +#, fuzzy +msgid "Remove smarthost" +msgstr "Mova esta entrada" + #, fuzzy msgid "Remove style" msgstr "Remover tudo" @@ -51314,6 +51825,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Solicita dados de uma instância de Jenkins." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Solicita dados de uma instância de Jenkins." @@ -51358,6 +51873,10 @@ msgstr "Porto necessário" msgid "Required context filters" msgstr "Filtros de contexto requeridos" +#, fuzzy +msgid "Required field missing" +msgstr "Falta o local" + msgid "Required match (regular expression)" msgstr "Partida necessária (expressão regular)" @@ -51674,6 +52193,10 @@ msgstr "Restringir os serviços de monitoramento por um destes tags AWS" msgid "Restrict number of processed messages per cycle" msgstr "Restringir o número de mensagens processadas por ciclo" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Restringir a severidade à pior das hipóteses" + msgid "Restrict runtime of logfile parsing" msgstr "Restringir tempo de execução de análise de arquivos de log" @@ -51814,6 +52337,11 @@ msgstr "" "Recuperar informações do processo usando o WMI (Windows Management " "Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Tentativa" @@ -51839,6 +52367,10 @@ msgstr "Tente novamente este teste" msgid "Retry time" msgstr "Tempo de tentativas" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "devolver CRÍTICO se encontrado, OK se não" + msgid "Return code class 2xx (success)" msgstr "Código de retorno classe 2xx (sucesso)" @@ -51856,7 +52388,12 @@ msgstr "Tempos de processo de retorno dentro dos dados de desempenho" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -51877,10 +52414,19 @@ msgstr "Ativar mudanças estrangeiras" msgid "Review and run preview service discovery" msgstr "Guardar & executar a descoberta de serviços" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configuração remota" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Guardar & executar a descoberta de serviços" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Revoluções por minuto" @@ -51933,6 +52479,10 @@ msgstr "Estrutura do robô: %s" msgid "Robot Framework: Last log" msgstr "Estrutura do robô: Último registo" +#, fuzzy +msgid "Robot package" +msgstr "Remover a embalagem" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -53040,12 +53590,14 @@ msgstr "Criar uma cópia desta agregação" msgid "Save response" msgstr "Guardar resposta" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Salve este anfitrião e vá para" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "" @@ -53097,9 +53649,6 @@ msgstr "Programar o tempo de inatividade no host" msgid "Schedule downtime on service" msgstr "Programar o tempo de inatividade no host" -msgid "Schedule downtime?" -msgstr "Programar o tempo de inatividade?" - msgid "Schedule downtimes" msgstr "Horário de paradas" @@ -53473,6 +54022,10 @@ msgstr "Segundos para esperar entre o envio do fio e a votação para resposta" msgid "Secret access key" msgstr "Chave secreta" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Chave secreta" + msgid "Secret key" msgstr "Chave secreta" @@ -53645,6 +54198,15 @@ msgstr "Seleccione um ficheiro iCalendar (*.ics) a partir do seu PC" msgid "Select and configure AWS services you would like to monitor" msgstr "Serviços do Azure a monitorizar" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Serviços do Azure a monitorizar" + +#, fuzzy +msgid "Select contact group" +msgstr "Grupos de contato de regras" + #, fuzzy msgid "Select datasource" msgstr "Selecione Datasource" @@ -53843,6 +54405,10 @@ msgstr "Selecione o tipo de elemento fixo da página" msgid "Select type from list" msgstr "Selecione arquivos individuais da lista" +#, fuzzy +msgid "Select user" +msgstr "Eliminar utilizador" + msgid "Select view" msgstr "Seleccionar vista" @@ -53879,6 +54445,10 @@ msgstr "As %s selecionadas foram eliminadas." msgid "Selected credential has been deleted" msgstr "A credencial selecionada foi eliminada" +#, fuzzy +msgid "Selected options" +msgstr "Ligações rejeitadas" + msgid "Selected sections will not be executed by the agent." msgstr "As seções selecionadas não serão executadas pelo agente." @@ -53948,6 +54518,10 @@ msgstr "Enviar dados HTTP POST" msgid "Send custom notification" msgstr "Enviar notificação personalizada" +#, fuzzy +msgid "Send custom notification?" +msgstr "Enviar notificação personalizada" + #, fuzzy msgid "Send data" msgstr "Dados cartografados" @@ -53992,9 +54566,7 @@ msgid "Send notifications to remote Event Console" msgstr "Enviar notificações para console de eventos remoto" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "As notificações serão enviadas de acordo com as regras de notificação" msgid "" @@ -54004,10 +54576,6 @@ msgstr "" "Enviar independentemente das restrições, por exemplo, período de notificação " "ou notificações desactivadas (forçado)" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Enviar notificações separadas para cada destinatário" - msgid "Send service metrics to Graphite" msgstr "Enviar métricas de serviço para o Graphite" @@ -54051,6 +54619,10 @@ msgstr "Enviar por e-mail" msgid "Sending Power" msgstr "Envio de energia" +#, fuzzy +msgid "Sending conditions" +msgstr "Condições definidas" + msgid "Sending reply" msgstr "Envio de resposta" @@ -54104,7 +54676,11 @@ msgid "September" msgstr "Setembro" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Intervalo de execução" + +#, fuzzy +msgid "Sequence of plans" msgstr "Programação da execução" msgid "Serial" @@ -54342,6 +54918,10 @@ msgstr "Descoberta de serviços: Descrição do serviço" msgid "Service discovery: State" msgstr "Descoberta de serviços: Estado" +#, fuzzy +msgid "Service events" +msgstr "Nível de serviço" + msgid "Service goes into critical state" msgstr "O serviço entra em estado crítico" @@ -54676,6 +55256,10 @@ msgstr "Serviços do Site" msgid "Services per cluster" msgstr "Serviços por cluster" +#, fuzzy +msgid "Services per region" +msgstr "Serviços por região a monitorar" + msgid "Services per region to monitor" msgstr "Serviços por região a monitorar" @@ -55200,7 +55784,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -55570,6 +56154,10 @@ msgstr "Mostrar caixas de seleção" msgid "Show column headings" msgstr "Mostrar títulos de colunas" +#, fuzzy +msgid "Show contact groups" +msgstr "Grupos de contato anfitriões" + msgid "Show context" msgstr "Mostrar contexto" @@ -55637,9 +56225,17 @@ msgstr "Mostrar dica no menu 'Usuário'" msgid "Show historic values" msgstr "Mostrar valores históricos" +#, fuzzy +msgid "Show host labels" +msgstr "Mostrar em mesas de acolhimento" + msgid "Show host status" msgstr "Mostrar o estado do anfitrião" +#, fuzzy +msgid "Show host tags" +msgstr "Mostrar o estado do anfitrião" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Mostrar ícone de ligação ao editor de parâmetros de configuração para " @@ -55716,6 +56312,10 @@ msgstr "Mostrar mais / Mostrar menos" msgid "Show notification bulks" msgstr "regra de notificação" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Ordem de ordenação de notificação para notificações em massa" + msgid "Show number of groups" msgstr "Mostrar número de grupos" @@ -55780,6 +56380,10 @@ msgstr "Mostrar regras usando esta %s" msgid "Show separate result for each SLA period" msgstr "Mostrar resultado separado para cada período do SLA" +#, fuzzy +msgid "Show service labels" +msgstr "Etiquetas de serviço" + #, fuzzy msgid "Show service name" msgstr "O nome do serviço" @@ -56170,6 +56774,11 @@ msgstr "" "nó que foi crucial para o resultado global (o preferido em caso de dúvida). " "Pode anular este automatismo especificando um nó aqui." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -57103,6 +57712,10 @@ msgstr "Objetos específicos" msgid "Specific sites" msgstr "Locais específicos" +#, fuzzy +msgid "Specific users" +msgstr "Locais específicos" + msgid "Specific version" msgstr "Versão específica" @@ -57125,13 +57738,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Especifica o estilo de linha padrão" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Especifica se a autenticação por senha é permitida" @@ -57299,13 +57905,6 @@ msgid "" "up either after a certain time or after a certain number of test executions." msgstr "" -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -57752,6 +58351,11 @@ msgstr "" "Especifique o que devemos fazer se o gráfico selecionado estiver faltando ou " "não puder ser recuperado." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Especificar que tipos de portos não devem ser descobertos" @@ -57968,6 +58572,10 @@ msgstr "Início do próximo ano" msgid "Start or end of a scheduled downtime" msgstr "Início ou fim de um período de inatividade programado" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Início do tempo de inactividade" + msgid "Start or end of flapping state" msgstr "Início ou fim do estado de flapping" @@ -58192,6 +58800,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Estado para o esperado descasamento de cordas" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Alerta sobre interface ativa inesperada" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Pendente de descoberta de serviços" + msgid "State if 'maintenance' services are found" msgstr "Indique se são encontrados serviços de \"manutenção" @@ -59220,10 +59836,12 @@ msgstr "Nome da seção" msgid "Subject for bulk notifications" msgstr "Assunto para notificações em massa" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Assunto para notificações do anfitrião" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Assunto para notificações de serviço" msgid "Submit" @@ -59621,6 +60239,10 @@ msgstr "Síncrono" msgid "Syncing" msgstr "Sincronização" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "certificado de roteador SAP" + msgid "Synology Updates" msgstr "Atualizações de Sinologia" @@ -59908,6 +60530,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "A autenticação TLS sem TLS não é possível" +#, fuzzy +msgid "TLS certificate verification" +msgstr "verificação do certificado SSL" + #, fuzzy msgid "TLS processed bytes" msgstr "Bytes Processados TLS" @@ -60133,6 +60759,16 @@ msgstr "" "As etiquetas podem ser usadas para classificar os anfitriões e serviços de " "uma forma flexível." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "Nenhuma fonte de dados definida." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Tags do alerta." @@ -60371,6 +61007,10 @@ msgstr "Criar uma cópia desta regra de notificação" msgid "Test authentication" msgstr "Testar a autenticação" +#, fuzzy +msgid "Test configuration" +msgstr "Configuração do anfitrião" + #, fuzzy msgid "Test connection" msgstr "Esta ligação" @@ -60404,6 +61044,9 @@ msgstr "última notificação" msgid "Test runtime" msgstr "Tempo de execução do teste" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + msgid "Test verification" msgstr "Verificação dos ensaios" @@ -61645,6 +62288,10 @@ msgid "The central (%s) and remote site (%s) are not compatible. Reason: %s" msgstr "" "O sítio central (%s) e o sítio remoto (%s) não são compatíveis. Motivo: %s" +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "Nunca foi ativado" + #, python-format msgid "The character %s is not allowed here." msgstr "O caractere %s não é permitido aqui." @@ -61930,6 +62577,11 @@ msgstr "" "A ligação cria anfitriões nesta pasta específica. Uma vez criado, pode optar " "por mover o anfitrião para outra pasta." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "A ligação a este site foi desactivada." @@ -62192,24 +62844,6 @@ msgstr "O elemento não pode ser encontrado no painel de instrumentos." msgid "The element does not exist." msgstr "O elemento não existe." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"O endereço de e-mail e o nome visível utilizado no cabeçalho das mensagens " -"de notificação. Se nenhum endereço de e-mail for especificado o endereço " -"padrão é OMD_SITE@FQDN é usado. Se a variável de ambiente " -"OMD_SITE não estiver definida como checkmk." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"O endereço de e-mail e o nome visível utilizado no cabeçalho das mensagens " -"de resposta às notificações." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -62572,12 +63206,6 @@ msgstr "Falta a especificação do gráfico" msgid "The graph template id '%s' is disabled" msgstr "O modelo de gráfico id '%s' está desactivado" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -62812,13 +63440,6 @@ msgstr "" "O nome da instância, o nome do banco de dados e o nome do tablespace " "combinados como este db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -63198,6 +63819,12 @@ msgstr "" "entrar em alerta/crítico. Este alarme só se aplica ao hospedeiro alvo, não " "aos lúpulos no meio." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "O comprimento máximo do valor é de 256 caracteres." @@ -64837,6 +65464,20 @@ msgstr "" "As debulhadoras de espera_duração_ms. irão sobregravar o estado padrão " "definido acima." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "Os dados estatísticos do intervalo de tempo são gravados em disco" @@ -64989,6 +65630,14 @@ msgid "The username returned by the %s connector is not of type string (%r)." msgstr "" "O nome de usuário retornado pelo conector %s não é do tipo string (%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"O nome de usuário que deve ser usado para acessar a API do Graylog. Tem de " +"ter pelo menos permissões de leitura." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -65290,8 +65939,8 @@ msgstr "Não há nenhum instantâneo de Configuração a ser restaurado." msgid "There is no backup job configured" msgstr "Não há nenhum trabalho de backup configurado" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "Não há um modelo gráfico com o id '%s'" msgid "There is no manpage for this check." @@ -65464,7 +66113,7 @@ msgstr "Estes nós estão apenas na agregação congelada" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" msgid "" @@ -65784,6 +66433,9 @@ msgstr "" "criptografado (nesse caso, você também precisa redefinir o controlador do " "agente no host monitorado (consulte a `cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + msgid "" "This active check sends out special emails to a defined mail address using " "either the SMTP protocol or an EWS connection and then tries to receive " @@ -66522,7 +67174,7 @@ msgstr "" msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -67358,8 +68010,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Esta permissão permite aos utilizadores migrarem outros utilizadores para " "outra ligação" @@ -67962,13 +68613,6 @@ msgstr "" "Inventariar um desses parâmetros levará a mudanças frequentes no inventário " "HW/SW, o que pode preencher rapidamente o sistema de arquivos temporários." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Esta regra permite a monitorização do VMware ESX através da API do vSphere. " -"Pode configurar as suas definições de ligação aqui." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -68657,15 +69301,6 @@ msgstr "" "Applainces em vez do agente Checkmk normal e permite a monitorização através " "da API Web. " -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Este conjunto de regras selecciona o agente especial para HPE StoreOnce " -"Appliances em vez do agente Checkmk normal e permite a monitorização através " -"da API REST v4.x ou superior. " - msgid "" "This rule sets limits to the current number of connections through a Check " "Point firewall." @@ -73488,9 +74123,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "Tentei registar regras incompatíveispec: %r" +#, fuzzy +msgid "Triggering events" +msgstr "Arquivo de eventos" + msgid "Trivial change" msgstr "Mudança trivial" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -74679,6 +75321,14 @@ msgstr "Carregar resposta" msgid "Upload verification response file" msgstr "Carregar ficheiro de resposta à verificação" +#, fuzzy +msgid "Uploaded" +msgstr "Carregar" + +#, fuzzy +msgid "Uploaded by" +msgstr "Chave de Upload" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "Carregamento do logótipo GUI personalizado: %s" @@ -76067,6 +76717,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">global rule event " "limit" +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Use esta opção para consultar uma porta que seja diferente da porta padrão " +"443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -76108,6 +76764,14 @@ msgstr "" "será consultado (fallback). A checagem somente emitirá dados do primeiro " "host que enviar uma resposta." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Use esta opção para definir qual instância deve ser verificada pelo agente " +"especial. Por favor adicione o hostname aqui, por exemplo, my_graylog.com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -76505,7 +77169,8 @@ msgstr "Mensagens do utilizador" msgid "User name" msgstr "Nome do usuário" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Nome do usuário no sistema de armazenamento. Apenas as permissões de leitura " "são suficientes." @@ -76600,6 +77265,10 @@ msgid "Users listed here are still allowed to modify things." msgstr "" "Os usuários listados aqui ainda têm permissão para modificar as coisas." +#, fuzzy +msgid "Users of contact groups" +msgstr "Membros de grupos de contato" + msgid "Users using a cifs share" msgstr "Utilizadores que utilizam uma acção cifs" @@ -77643,6 +78312,10 @@ msgstr "Verificar certificados" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Ignorar erros de certificado (inseguro)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Ignorar erros de certificado (inseguro)" + msgid "Verify certificates" msgstr "Verificar certificados" @@ -77704,6 +78377,9 @@ msgstr "Versão do dispositivo PKI" msgid "Version of Server" msgstr "Versão do Servidor" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Versão: %s" @@ -78164,6 +78840,10 @@ msgstr "Ligações em espera" msgid "Waiting containers" msgstr "Contentores em espera" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Netapp descoberta da porta" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -78548,6 +79228,9 @@ msgstr "" msgid "What is the purpose?" msgstr "" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -79605,6 +80288,10 @@ msgstr "" msgid "Who" msgstr "Quem" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "permitir que os usuários desativem esta notificação" + msgid "WiFi connection types" msgstr "tipos de conexão WiFi" @@ -79766,7 +80453,7 @@ msgstr "" msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -80079,6 +80766,13 @@ msgstr "" "algum parâmetro estiver configurado. Isto pode ser confuso.Esta " "regra só deve ser configurada nas fases iniciais." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -81005,6 +81699,14 @@ msgstr "Você não pode apagar a conexão com o site local." msgid "You can not delete this %s because it is in use." msgstr "Você não pode apagar esta %s porque é em uso." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"Você não pode apagar este alvo porque ele é usado por estes trabalhos de " +"backup: %s" + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -81818,6 +82520,10 @@ msgstr "" "Ainda não criou nenhum agente chaves de assinatura. Isso é " "necessário." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Parâmetros para este anfitrião" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -83733,9 +84439,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "monitor" - msgid "month" msgstr "mês" @@ -84654,6 +85357,9 @@ msgstr "{actual} é demasiado elevado. O valor máximo permitido é {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} é demasiado baixo. O valor mínimo permitido é {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -84662,6 +85368,134 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Todos os direitos reservados." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Use SSL para a conexão." + +#~ msgid "API key from password store" +#~ msgstr "Chave API da loja de senhas" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Alerta do anfitrião" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Falha na obtenção do certificado do par (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Aviso>>br>>br>Você não configurou um fallback email " +#~ "address nem habilitou o recebimento de fallback emails para nenhum " +#~ "usuário. Se a sua monitorização produzir uma notificação que não " +#~ "corresponda a nenhuma das suas regras de notificação, a notificação não " +#~ "será enviada. Para evitar isso, por favor configure a configuração global " +#~ "ou habilite a opção de contato fallback para pelo menos um de seus " +#~ "usuários." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Notificações em massa com gráficos (padrão: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "Por padrão, todos os gráficos múltiplos em e-mails são exibidos flutuando " +#~ "nas proximidades. Você pode habilitar esta opção para mostrar os gráficos " +#~ "entre si." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configurando isto para que o plugin de notificação se conecte diretamente " +#~ "ao servidor smtp. Isto tem a vantagem de fornecer melhores mensagens de " +#~ "erro em caso de erro, mas requer mais configuração e é estritamente " +#~ "síncrono, por isso aconselhamos o uso apenas em instalações empresariais " +#~ "utilizando o spooler de notificação." + +#~ msgid "Display additional information" +#~ msgstr "Apresentar informações adicionais" + +#~ msgid "Display graphs among each other" +#~ msgstr "Mostrar gráficos entre si" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Os gráficos são mostrados entre si" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "O endereço de e-mail e o nome visível utilizado no cabeçalho das " +#~ "mensagens de notificação. Se nenhum endereço de e-mail for especificado o " +#~ "endereço padrão é OMD_SITE@FQDN é usado. Se a variável de " +#~ "ambiente OMD_SITE não estiver definida como checkmk." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "O endereço de e-mail e o nome visível utilizado no cabeçalho das " +#~ "mensagens de resposta às notificações." + +#~ msgid "Activate" +#~ msgstr "Ativar" + +#~ msgid "Deactivate" +#~ msgstr "Desativar" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Esta regra permite a monitorização do VMware ESX através da API do " +#~ "vSphere. Pode configurar as suas definições de ligação aqui." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Este conjunto de regras selecciona o agente especial para HPE StoreOnce " +#~ "Appliances em vez do agente Checkmk normal e permite a monitorização " +#~ "através da API REST v4.x ou superior. " + +#~ msgid "monitor" +#~ msgstr "monitor" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Nome da conta de armazenamento" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Programação da execução" + +#~ msgid "(not supported)" +#~ msgstr "(não suportado)" + +#~ msgid "Remove downtimes?" +#~ msgstr "Eliminar os tempos de inatividade?" + +#~ msgid "Schedule downtime?" +#~ msgstr "Programar o tempo de inatividade?" + +#, fuzzy +#~ msgid "OVS bonding interface status" +#~ msgstr "Interfaces de colagem" + #~ msgid "Common Name" #~ msgstr "Nome Comum" @@ -84790,10 +85624,6 @@ msgstr "© %s Checkmk GmbH. Todos os direitos reservados." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Quota usada: Níveis superiores absolutos ou relativos" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "Nunca foi ativado" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Tablespaces" @@ -85093,10 +85923,6 @@ msgstr "© %s Checkmk GmbH. Todos os direitos reservados." #~ msgid "%s operations" #~ msgstr "%s operações" -#, fuzzy, python-format -#~ msgid "%s requests" -#~ msgstr "%s Pedidos" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -85433,9 +86259,6 @@ msgstr "© %s Checkmk GmbH. Todos os direitos reservados." #~ msgid "InfluxDB Queue Usage" #~ msgstr "Uso da fila do InfluxDB" -#~ msgid "Kernel Version" -#~ msgstr "Versão Kernel" - #~ msgid "Levels Helper usage Check" #~ msgstr "Níveis Verificação do uso do Helper" diff --git a/locale/ro/LC_MESSAGES/multisite.po b/locale/ro/LC_MESSAGES/multisite.po index 3c6b7febabe..599b0ec86de 100644 --- a/locale/ro/LC_MESSAGES/multisite.po +++ b/locale/ro/LC_MESSAGES/multisite.po @@ -404,6 +404,10 @@ msgstr "%d zile" msgid "%d days ago" msgstr "%d zile în urmă" +#, fuzzy, python-format +msgid "%d defined parameter properties" +msgstr "Proprietăți generale" + #, python-format msgid "%d errors occured:" msgstr "%d au apărut erori:" @@ -568,6 +572,10 @@ msgstr "%s de către gazdă" msgid "%s can only be deleted via Quick setup" msgstr "" +#, python-format +msgid "%s cannot be empty" +msgstr "" + #, python-format msgid "" "%s failed after %s: %s (see var/log/web.log for further information)" @@ -692,6 +700,10 @@ msgstr "%s rata" msgid "%s resulting notifications" msgstr "%s notificări rezultate" +#, fuzzy, python-format +msgid "%s rules" +msgstr "%s Cereri" + #, python-format msgid "%s running for %s" msgstr "%s rulează pentru %s" @@ -809,9 +821,17 @@ msgstr "" "versiunea configurației.Vă rugăm să instalați 'git' sau să dezactivați " "urmărirea configurației git în WATO." +#, fuzzy, python-format +msgid "(%s more entries)" +msgstr "Intrări eliminate" + msgid "(0 is current period)" msgstr "(0 reprezintă perioada curentă)" +#, fuzzy +msgid "(1 more entry)" +msgstr "(nici o intrare)" + msgid "(Edit presets)" msgstr "(Editare preselecții)" @@ -887,9 +907,6 @@ msgstr "(fără titlu)" msgid "(none)" msgstr "(nimic)" -msgid "(not supported)" -msgstr "(neacceptat)" - msgid "(nothing selected)" msgstr "(nimic selectat)" @@ -997,6 +1014,10 @@ msgstr "1 schimbare" msgid "1 row" msgstr "1 rând" +#, fuzzy +msgid "1 rule" +msgstr "regula" + msgid "1 year" msgstr "1 an" @@ -1194,6 +1215,31 @@ msgstr "A 95-a percentila" msgid "99th percentile" msgstr "Percentila 99" +#, fuzzy +msgid "< Remove" +msgstr "Eliminați" + +#, fuzzy +msgid "<< Remove all" +msgstr "Eliminați toate" + +#, fuzzy +msgid "" +"Piggyback " +"translations are performed before the piggyback connector creates hosts. " +"Use this, for example, in a setup with multiple Docker nodes to prefix " +"containers with the name of the corresponding Docker node. Otherwise, name " +"collisions can occur if containers with the same name exist on more than one " +"Docker Node." +msgstr "" +"Piggybacktranslationssunt efectuate înainte ca conectorul piggyback să creeze gazde. Utilizați " +"acest lucru, de exemplu, într-o configurație cu mai multe noduri Docker " +"pentru a prefixa containerele cu numele nodului Docker corespunzător. În caz " +"contrar, pot apărea coliziuni de nume dacă există containere cu același nume " +"pe mai multe noduri Docker." + msgid "" "PiggybacktranslationsNote3: In order to deploy this plug-in to Solaris, a " -"Python 3.4 installation (or newer) with installed python packages \"pyOpenSSL" +"Python 3.7 installation (or newer) with installed python packages \"pyOpenSSL" "\", \"requests\" and \"PySocks\" is required on the target hosts." msgstr "" "Nota3: Pentru a implementa acest plugin pe Solaris, este " @@ -1363,6 +1409,12 @@ msgstr "Avertisment: Există %d lucrări incompatibile nerecunoscute:" msgid "You do not have any roles." msgstr "Nu aveți niciun rol." +msgid "" +"

    Important note: When changing this option, the services " +"need to be removed and rediscovered to apply the changes. Otherwise there is " +"a risk of mismatch between the discovered and checked services." +msgstr "" + msgid "" "
    HINT: The individual program is called from the current working " "directory. You should therefore specify absolute path names in scripts (by " @@ -1952,7 +2004,7 @@ msgid "" "robot.yaml is the main RCC configuration file. It is specified " "relative to the base directory of Robot Framework projects. This file also " "references the conda.yaml file which lists all environment " -"dependencies. " +"dependencies." msgstr "" #, python-format @@ -2134,6 +2186,14 @@ msgstr "Un titlu pentru grafice" msgid "A heading for the view" msgstr "Un titlu pentru view" +#, fuzzy, python-format +msgid "" +"A host with the name %s already exists in the folder %s. Please choose a " +"different host name." +msgstr "" +"O gazdă cu numele %s există deja în folderul
    " +"%s." + #, python-format msgid "" "A host with the name %s already exists in the folder " +msgstr "Adaugă %s" + msgid "Add Aggregation" msgstr "Adăugați agregarea" @@ -3640,10 +3717,6 @@ msgstr "Adaugă Excepție" msgid "Add Group" msgstr "Adăugați un grup" -msgid "Add HTML section above table (e.g. title, description…)" -msgstr "" -"Adăugați secțiunea HTML deasupra tabelului (de exemplu, titlu, descriere...)" - msgid "Add LDAP connection" msgstr "Adăugați conexiunea LDAP" @@ -3689,6 +3762,9 @@ msgstr "Adăugați agregarea" msgid "Add alert handler rule" msgstr "Adăugați regula de gestionare a alertelor" +msgid "Add all >>" +msgstr "" + msgid "Add all detected but not yet monitored services to the monitoring." msgstr "" "Adăugați la monitorizare toate serviciile detectate, dar care nu au fost " @@ -3790,6 +3866,10 @@ msgstr "Adăugați un element: %s" msgid "Add elements to your sidebar" msgstr "Adăugați elemente la bara laterală" +#, fuzzy +msgid "Add event" +msgstr "Adaugă element" + msgid "Add exception" msgstr "Adăugați o excepție" @@ -3976,6 +4056,10 @@ msgstr "Adăugați o nouă condiție de nod" msgid "Add new pattern" msgstr "Adăugați un nou model" +#, fuzzy +msgid "Add new plan" +msgstr "Adăugați un nou model" + msgid "Add new project" msgstr "Adăugați un nou proiect" @@ -3991,10 +4075,18 @@ msgstr "Adăugați o nouă regulă" msgid "Add new scalar" msgstr "Adăugați un nou scalar" +#, fuzzy +msgid "Add new sequence" +msgstr "Adăugați un nou serviciu" + #, fuzzy msgid "Add new service" msgstr "Adăugați un nou serviciu" +#, fuzzy +msgid "Add new smarthost" +msgstr "Adăugați o nouă macro" + msgid "Add new status" msgstr "Adăugați un nou statut" @@ -4036,6 +4128,10 @@ msgstr "Adăugarea sau modificarea executabilelor" msgid "Add page element" msgstr "Adăugați un element de pagină" +#, fuzzy +msgid "Add parameter" +msgstr "Parametrii modelului" + msgid "Add pattern" msgstr "Adaugă model/tipar" @@ -4061,6 +4157,10 @@ msgstr "Adăugați pre sau postfix la TNSALIASes %s" msgid "Add random hosts" msgstr "Adăugați gazde aleatorii" +#, fuzzy +msgid "Add recipient" +msgstr "Destinatarul" + msgid "Add remote instance" msgstr "Adăugați o instanță la distanță" @@ -4308,6 +4408,10 @@ msgstr "" "Etichete suplimentare pentru agenți care trebuie trimise în timpul " "înregistrării" +#, fuzzy +msgid "Additional details" +msgstr "Opțiuni adiționale" + msgid "Additional header lines" msgstr "Linii de header adiționale" @@ -4438,7 +4542,7 @@ msgid "Admin states to discover" msgstr "Statele administrației de descoperit" #, fuzzy -msgid "Administrate managed robots" +msgid "Administrate robots" msgstr "Statele administrative" msgid "Administrative port states to discover" @@ -5123,6 +5227,10 @@ msgstr "" msgid "Alert handler configuration" msgstr "Configurarea gestionarului de alertă" +#, fuzzy +msgid "Alert handler execution" +msgstr "Executarea gestionarilor de alerte" + msgid "Alert handler execution, failed" msgstr "Executarea gestionarului de alertă, eșuată" @@ -5235,6 +5343,15 @@ msgstr "Statistici de alertă: Numărul de alerte necunoscute" msgid "Alert statistics: Number of warnings" msgstr "Statistici de alertă: Numărul de avertismente" +msgid "Alert when a major version release is available" +msgstr "" + +msgid "Alert when a minor version release is available" +msgstr "" + +msgid "Alert when a patch version release is available" +msgstr "" + msgid "Alerted" msgstr "Alertat" @@ -5341,6 +5458,10 @@ msgstr "Toate colecțiile" msgid "All components" msgstr "Toate componentele" +#, fuzzy +msgid "All contacts of the affected object" +msgstr "Toate persoanele de contact ale obiectului notificat" + msgid "All contacts of the notified object" msgstr "Toate persoanele de contact ale obiectului notificat" @@ -5774,6 +5895,10 @@ msgstr "Permiteți să vedeți pictograma %s în vizualizările gazdă și servi msgid "Allow unencrypted legacy communication" msgstr "Permiterea comunicării necriptate a moștenirii" +#, fuzzy +msgid "Allow users to deactivate this notification" +msgstr "permite utilizatorilor să dezactiveze această notificare" + msgid "Allowed Ciphers" msgstr "Cifre permise" @@ -6387,6 +6512,10 @@ msgstr "" msgid "AntiVirus last update age" msgstr "Vârsta ultimei actualizări AntiVirus" +#, fuzzy +msgid "Any" +msgstr "orice" + msgid "" "Any certificate should expire at some point. Usual values are within 90 and " "365 days." @@ -6561,9 +6690,21 @@ msgstr "Prezentare generală a aplicațiilor" msgid "Applications, Processes & Services" msgstr "Aplicații, procese & Servicii" +#, fuzzy +msgid "Applied to" +msgstr "Aplicați la" + msgid "Apply" msgstr "Aplicați" +#, fuzzy +msgid "Apply & create another rule" +msgstr "Regula de gestionare a alertelor" + +#, fuzzy +msgid "Apply & test notification rule" +msgstr "Ștergeți această regulă de notificare" + #, fuzzy msgid "Apply Latency" msgstr "Latență" @@ -6586,6 +6727,11 @@ msgstr "Aplicați condițiile" msgid "Apply filters" msgstr "Aplicați filtre" +msgid "" +"Apply filters to specify which hosts and services are affected by this " +"notification rule." +msgstr "" + #, fuzzy msgid "Apply finish time" msgstr "Aplicați timpul de finisare" @@ -6720,6 +6866,10 @@ msgstr "Arhivați jurnalul de audit curent" msgid "Archive event" msgstr "Eveniment de arhivă" +#, fuzzy +msgid "Archive event?" +msgstr "Eveniment de arhivă" + msgid "Archive events" msgstr "Arhiva evenimentelor" @@ -6854,6 +7004,11 @@ msgid "" "(not email)." msgstr "" +msgid "" +"Assign permissions to the app: Grant necessary access rights, assigning the " +"\"Reader\" role." +msgstr "" + #, fuzzy msgid "Assign plan/test result to piggyback host" msgstr "Atribuiți rezultatul la gazda piggyback" @@ -7286,10 +7441,10 @@ msgstr "Autoextensibil" msgid "Automated environment setup (via RCC)" msgstr "Configurarea automată a mediului (prin RCC)" -#, fuzzy, python-format +#, fuzzy msgid "" -"Automated environment setup (via RCC, %s because Robotmk Core MKP has been " -"installed)" +"Automated environment setup (via RCC, ⚠ not available because Robotmk " +"Core MKP has been installed)" msgstr "Utilizați SSL pentru conexiune." msgid "Automatic" @@ -8648,6 +8803,10 @@ msgstr "Agenți coapte" msgid "Baked host specific agent" msgstr "Agent specific gazdei coapte" +#, fuzzy +msgid "Bakery rules" +msgstr "Reguli de descoperire" + msgid "Baking Agents..." msgstr "Agenți de coacere..." @@ -9183,8 +9342,9 @@ msgstr "Importul de gazde în masă" msgid "Bulk move" msgstr "Mutarea în vrac" -msgid "Bulk notifications with graphs (default: 5)" -msgstr "Notificări în masă cu grafice (implicit: 5)" +#, fuzzy +msgid "Bulk notifications" +msgstr "Deschideți notificări în masă" msgid "Bulk removal of explicit attributes" msgstr "Eliminarea în bloc a atributelor explicite" @@ -9542,14 +9702,6 @@ msgstr "" "personaliza acreditările care urmează să fie utilizate la contactarea " "gazdelor prin SNMP." -msgid "" -"By default all multiple graphs in emails are displayed floating nearby. You " -"can enable this option to show the graphs among each other." -msgstr "" -"În mod implicit, toate graficele multiple din e-mailuri sunt afișate în mod " -"plutitor în apropiere. Puteți activa această opțiune pentru a afișa " -"graficele unele printre altele." - msgid "By default all of the sections will be executed." msgstr "În mod implicit, toate secțiunile vor fi executate." @@ -9748,14 +9900,14 @@ msgid "" "option is active, Robot Framework will immediately stop the suite " "execution if a test fails.
    The results of subsequent tests (which would " "have failed) will then not be passed to Checkmk; depending on the discovery " -"settings,their results will either be missing (if within a suite " -"result) or the services generated for them will go stale.

    " -"Important note: this is where Robotmk deviates from Robot Framework " -"behavior. The HTML log will still contain the omitted tests and show them as " -"FAIL (even though they were not executed).
    See also \"
    How to stop a " -"suite when the first test fails\". " +"settings, their results will either be missing (if within a suite " +"result) or the services generated for them will go stale." +"

    Important note: this is where Robotmk deviates from Robot " +"Framework behavior. The HTML log will still contain the omitted tests and " +"show them as FAIL (even though they were not executed).
    See also " +"\"How to stop a suite when the first test fails\". " msgstr "" "În mod implicit, Robot Framework va executa fiecare test.
    Dar " "uneori testele sunt interdependente - în cazul unei autentificări eșuate, de " @@ -9780,7 +9932,7 @@ msgid "" "run tests on Windows GUI applications, you can specify the name of a user " "who is permanently logged on to a desktop session. The prerequisites for " "this are security-related and must be fulfilled by you (auto-login, screen " -"saver, session lock, ...)" +"saver, session lock, ...)." msgstr "" "În mod implicit, Robotmk execută toate suitele în contextul de utilizator al " "agentului Checkmk, care nu are acces la desktop-ul computerului Windows. " @@ -10057,10 +10209,11 @@ msgstr "" msgid "Bypass Proxy for certain hosts" msgstr "Bypassarea Proxy pentru anumite gazde" +#, fuzzy msgid "" "Bypass Proxy for certain hosts: Specifies a list of destination hosts/" -"adresses which should not be accessed through the given proxy.
    The proxy " -"setting is used for access to the internet, where RCC needs to download the " +"adresses which should not be accessed through the given proxy.
    The proxy " +"setting is used for access to the internet, where RCC needs to ownload the " "installation files from. (In order to access a page through a proxy inside " "of the test suite, use the libraries capabilities)" msgstr "" @@ -11310,6 +11463,10 @@ msgstr "Conexiune LDAP schimbată %s" msgid "Changed alert handler rule %d" msgstr "Regula de gestionare a alertelor a fost modificată %d" +#, fuzzy +msgid "Changed by" +msgstr "Modificat" + msgid "Changed entries" msgstr "Intrări modificate" @@ -11327,6 +11484,14 @@ msgstr[2] "Etichete de gazdă modificate: " msgid "Changed host selection has been saved." msgstr "Selecția modificată a gazdei a fost salvată." +#, fuzzy, python-format +msgid "Changed notification parameter %d" +msgstr "Regula de notificare modificată %d" + +#, fuzzy, python-format +msgid "Changed notification parameter %s" +msgstr "Regula de notificare modificată %d" + #, python-format msgid "Changed notification rule %d" msgstr "Regula de notificare modificată %d" @@ -11346,6 +11511,11 @@ msgstr "A fost schimbată poziția lui %s %d" msgid "Changed position of connection %s to %d" msgstr "A schimbat poziția conexiunii %s în %d" +#, fuzzy, python-format +msgid "Changed position of notification parameter %d" +msgstr "" +"A fost modificată poziția regulii de notificare %d a utilizatorului %s." + #, python-format msgid "Changed position of notification rule %d of user %s" msgstr "" @@ -11405,6 +11575,10 @@ msgstr "" msgid "Changes" msgstr "Modificări" +#, fuzzy +msgid "Changes activated" +msgstr "Nu a fost niciodată activat" + msgid "Changes since last dump" msgstr "Modificări de la ultima descărcare de gestiune" @@ -12706,6 +12880,11 @@ msgstr "" "Faceți clic pe \"Înregistrare %s\" pentru a activa autentificarea cu doi " "factori prin intermediul %s." +msgid "" +"Click the \"Add configuration\" button to start setting up your first " +"configuration." +msgstr "" + msgid "Click to toggle this setting" msgstr "Faceți clic pentru a comuta această setare" @@ -12867,6 +13046,10 @@ msgstr "Clonarea acestei conexiuni pentru a crea una nouă" msgid "Clone this element" msgstr "Clonarea acestui element" +#, fuzzy +msgid "Clone this managed robot" +msgstr "Obiecte gestionate" + msgid "Clone this metric" msgstr "Clonați această metrică" @@ -13417,6 +13600,10 @@ msgstr "Finalizați restaurarea" msgid "Complete tree" msgstr "Arbore complet" +#, fuzzy +msgid "Complete variable list" +msgstr "Lista completă de variabile (pentru testare)" + msgid "Complete variable list (for testing)" msgstr "Lista completă de variabile (pentru testare)" @@ -13558,6 +13745,10 @@ msgstr "Fișiere de configurare ('*.mk' sau '*.conf') din etc/checkmk: %s." msgid "Configuration generation" msgstr "Generarea configurației" +#, fuzzy +msgid "Configuration name" +msgstr "Configurație" + msgid "Configuration of Checkmk's Business Intelligence component" msgstr "" "Configurarea componentei Business Intelligence a Checkmk's Business " @@ -13631,6 +13822,10 @@ msgstr "Configurați" msgid "Configure Amazon Web Service (AWS) monitoring in Checkmk" msgstr "Monitorizarea serviciilor web Amazon (AWS)" +#, fuzzy +msgid "Configure Microsoft Azure monitoring in Checkmk" +msgstr "Monitorizarea serviciilor web Amazon (AWS)" + msgid "Configure SNMP related settings using rulesets" msgstr "Configurarea setărilor legate de SNMP utilizând seturi de reguli" @@ -13696,6 +13891,10 @@ msgstr "Adresa de e-mail de rezervă a raportului de accident" msgid "Configure grouping of interfaces" msgstr "Configurați gruparea interfețelor" +#, fuzzy +msgid "Configure host and authority" +msgstr "Configurație" + #, fuzzy msgid "Configure host and regions" msgstr "Configurație" @@ -13922,6 +14121,10 @@ msgstr "" "Configurați numele variabilei de antet de cerere HTTP care urmează să fie " "citită din cererile HTTP primite" +#, fuzzy +msgid "Configure the number of expected interfaces" +msgstr "Configurați descoperirea interfețelor unice" + #, fuzzy, python-format msgid "" "Configure the port to send the real-time data to. The Micro Core of the " @@ -13953,20 +14156,6 @@ msgstr "" "furnizând aici cheia de utilizator sau de grup. Cheia poate fi obținută de " "pe site-ul Pushover." -#, fuzzy -msgid "" -"Configure this to have the notification plug-in connect directly to the SMTP " -"server. This has the advantage of providing better error messages in case of " -"an error, but it does require more configuration and is strictly " -"synchronous. So we advice use only on enterprise installations using the " -"notification spooler." -msgstr "" -"Configurarea acestui lucru pentru ca pluginul de notificare să se conecteze " -"direct la serverul smtp. Acest lucru are avantajul de a oferi mesaje de " -"eroare mai bune în caz de eroare, dar necesită mai multă configurare și este " -"strict sincronă, așa că vă recomandăm să o utilizați numai în cazul " -"instalațiilor de întreprindere care utilizează spoolerul de notificare." - msgid "" "Configure thresholds that apply to clusters based on how many nodes they " "have." @@ -14368,6 +14557,10 @@ msgstr "Contactați" msgid "Contact Name" msgstr "Nume de contact" +#, fuzzy +msgid "Contact group" +msgstr "Grupuri de contact" + msgid "Contact group (effective)" msgstr "Grupul de contact (efectiv)" @@ -14527,6 +14720,10 @@ msgstr "Informații contextuale" msgid "Context information about this connection" msgstr "Informații contextuale despre această conexiune" +#, fuzzy +msgid "Context information about this parameter" +msgstr "Informații contextuale despre această regulă" + msgid "Context information about this rule" msgstr "Informații contextuale despre această regulă" @@ -14778,6 +14975,11 @@ msgstr "Couchbase vBuckets" msgid "Couchbase: Cache" msgstr "Couchbase: Cache" +msgid "" +"Could not access your AWS account. Please check your Access and Secret key " +"and try again." +msgstr "" + #, python-format msgid "" "Could not connect to the license server (%s). Please retry again later. If " @@ -15068,6 +15270,10 @@ msgstr "Creați o copie a acestei conexiuni" msgid "Create a copy of this group" msgstr "Creați o copie a acestui grup" +#, fuzzy +msgid "Create a copy of this notification parameter" +msgstr "Creați o copie a acestei reguli de notificare" + msgid "Create a copy of this notification rule" msgstr "Creați o copie a acestei reguli de notificare" @@ -15154,6 +15360,11 @@ msgstr "Crearea unui serviciu suplimentar pentru solicitările de statistici IO" msgid "Create additional service for system wait" msgstr "Creați un serviciu suplimentar pentru sistemul de așteptare" +msgid "" +"Create an Azure app for Checkmk: Register the app in Azure Active Directory " +"and note down the Application ID." +msgstr "" + msgid "Create an annotation for this period" msgstr "Creați o adnotare pentru această perioadă" @@ -15265,6 +15476,10 @@ msgstr "" msgid "Create regular time-schedule for this report" msgstr "Creați un orar regulat pentru acest raport" +#, fuzzy +msgid "Create robot" +msgstr "Creați gazde" + msgid "Create separate notification bulks based on" msgstr "Creați grupe de notificare separate pe baza" @@ -15368,6 +15583,10 @@ msgstr "A creat o nouă gazdă %s." msgid "Created new host tag group '%s'" msgstr "A creat un nou grup de etichete gazdă '%s'" +#, fuzzy +msgid "Created new notification parameter" +msgstr "A creat o nouă regulă de notificare" + msgid "Created new notification rule" msgstr "A creat o nouă regulă de notificare" @@ -15817,6 +16036,11 @@ msgstr "Proiectare GUI personalizată de %s" msgid "Custom Graph" msgstr "Grafic personalizat" +#, fuzzy +msgid "Custom HTML section (e.g. title, description…)" +msgstr "" +"Adăugați secțiunea HTML deasupra tabelului (de exemplu, titlu, descriere...)" + msgid "Custom Icons" msgstr "Icoane personalizate" @@ -15922,6 +16146,14 @@ msgstr "Localizări personalizate" msgid "Custom logos" msgstr "Logouri personalizate" +#, fuzzy +msgid "Custom macro" +msgstr "Macros pentru clienți" + +#, fuzzy +msgid "Custom macros" +msgstr "Macros pentru clienți" + #, python-format msgid "Custom notification table for user %s" msgstr "Tabel de notificare personalizat pentru utilizatorul %s" @@ -15935,9 +16167,15 @@ msgstr "Starea sondei personalizate" msgid "Custom profile" msgstr "Profil personalizat" +msgid "Custom recipient of \"Reply to\"" +msgstr "" + msgid "Custom search query" msgstr "Interogare de căutare personalizată" +msgid "Custom sender (\"From\")" +msgstr "" + msgid "Custom service attributes" msgstr "Atributele serviciilor personalizate" @@ -16772,9 +17010,6 @@ msgstr "Tarif pe zi" msgid "Days" msgstr "" -msgid "Deactivate" -msgstr "Dezactivați" - msgid "Deactivated" msgstr "Dezactivat" @@ -17067,6 +17302,9 @@ msgstr "Profil de utilizator implicit" msgid "Default value" msgstr "Valoarea implicită" +msgid "Defaults to 'https' when not provided." +msgstr "" + #, fuzzy msgid "Deferred files age" msgstr "Dosare amânate Vârsta" @@ -17124,6 +17362,9 @@ msgstr "" "monitorizare, adică în rezultatul verificării. Aceasta suprascrie " "cartografierea implicită utilizată de verificare." +msgid "Define any events you want to be notified about." +msgstr "" + #, fuzzy msgid "Define host assignment" msgstr "Definiți atribuirea gazdei" @@ -17168,6 +17409,9 @@ msgstr "" msgid "Define name of NetBIOS server" msgstr "Definiți numele serverului NetBIOS" +msgid "Define parameters for HTML mail" +msgstr "" + msgid "" "Define patterns for excluding kernel configuration parameters from the " "inventory." @@ -17417,6 +17661,10 @@ msgstr "Ștergerea cheii de rezervă #%d" msgid "Delete comments" msgstr "Ștergeți comentariile" +#, fuzzy +msgid "Delete comments?" +msgstr "Ștergeți comentariile" + #, fuzzy, python-format msgid "Delete configuration %s" msgstr "Configurație implicită" @@ -17484,6 +17732,14 @@ msgstr "Ștergeți postul #%d" msgid "Delete last alert handler rule" msgstr "Ștergeți ultima regulă de gestionare a alertelor" +#, fuzzy +msgid "Delete managed robot" +msgstr "Obiecte gestionate" + +#, fuzzy, python-format +msgid "Delete notification parameter #%d" +msgstr "Ștergerea regulii de notificare #%d" + #, python-format msgid "Delete notification rule #%d" msgstr "Ștergerea regulii de notificare #%d" @@ -17637,9 +17893,17 @@ msgstr "Ștergeți această cheie" msgid "Delete this logo" msgstr "Ștergeți acest logo" +#, fuzzy +msgid "Delete this managed robot" +msgstr "Ștergeți acest grup de etichete" + msgid "Delete this metric" msgstr "Ștergeți această măsurătoare" +#, fuzzy +msgid "Delete this notification parameter" +msgstr "Ștergeți această regulă de notificare" + msgid "Delete this notification rule" msgstr "Ștergeți această regulă de notificare" @@ -17737,6 +18001,10 @@ msgstr "Dosar șters %s" msgid "Deleted host %s" msgstr "Gazdă ștearsă %s" +#, fuzzy, python-format +msgid "Deleted notification parameter %d" +msgstr "Ștergerea regulii de notificare #%d" + #, python-format msgid "Deleted notification rule %d of user %s" msgstr "Regulă de notificare ștearsă %d a utilizatorului %s" @@ -18673,6 +18941,10 @@ msgstr "Dezactivați gestionarea proxy" msgid "Disable remote configuration" msgstr "Dezactivați configurarea la distanță" +#, fuzzy +msgid "Disable rule" +msgstr "Dezactivați toate" + msgid "Disable service notifications" msgstr "Dezactivarea notificărilor de serviciu" @@ -19043,9 +19315,6 @@ msgstr "" "Afișați un avertisment dacă un LUN nu este numai pentru citire. Fără această " "setare, va fi afișat un avertisment dacă un LUN este numai pentru citire." -msgid "Display additional information" -msgstr "Afișarea de informații suplimentare" - msgid "Display additional messages" msgstr "Afișarea mesajelor suplimentare" @@ -19069,9 +19338,6 @@ msgstr "Afișarea etichetelor axei pentru intervalul de date selectat/automat" msgid "Display dashboard title" msgstr "Afișați titlul tabloului de bord" -msgid "Display graphs among each other" -msgstr "Afișarea graficelor între ele" - msgid "Display historic data since the last" msgstr "Afișarea datelor istorice de la ultima" @@ -19980,6 +20246,10 @@ msgstr "Numărul de documente delta" msgid "Document count growth per minute" msgstr "Creșterea numărului de documente pe minut" +#, fuzzy +msgid "Documentation" +msgstr "URL de documentare" + msgid "Documentation URL" msgstr "URL de documentare" @@ -20766,6 +21036,10 @@ msgstr "Editați" msgid "Edit %s" msgstr "Editare %s" +#, fuzzy, python-format +msgid "Edit %s notification parameter %s" +msgstr "Editarea regulii de notificare %d" + #, python-format msgid "Edit %s: %s" msgstr "Editați %s: %s" @@ -20915,6 +21189,10 @@ msgstr "Editați aspectul" msgid "Edit layout only available if header is enabled" msgstr "Editarea aspectului este disponibilă numai dacă este activat antetul" +#, fuzzy +msgid "Edit managed robots" +msgstr "Obiecte gestionate" + #, fuzzy, python-format msgid "Edit message broker connection %s" msgstr "Editați conexiunea site-ului %s" @@ -21072,6 +21350,14 @@ msgstr "Editați acest element" msgid "Edit this host" msgstr "Editați această gazdă" +#, fuzzy +msgid "Edit this managed robot" +msgstr "Statele administrative" + +#, fuzzy +msgid "Edit this notification parameter" +msgstr "Editați această regulă de notificare" + msgid "Edit this notification rule" msgstr "Editați această regulă de notificare" @@ -21143,6 +21429,9 @@ msgstr "Profil de utilizator editat pentru utilizator %s" msgid "Edition" msgstr "Ediție" +msgid "Effect" +msgstr "" + msgid "Effective State" msgstr "Statul efectiv" @@ -21329,6 +21618,14 @@ msgstr "Adresa de e-mail utilizată pentru identificarea contului" msgid "Email addresses to mail PDF reports to" msgstr "Adresele de e-mail la care să trimiteți rapoartele PDF" +#, fuzzy +msgid "Email body/content" +msgstr "Email trimis" + +#, fuzzy +msgid "Email header" +msgstr "Adresa de e-mail" + msgid "Email sent" msgstr "Email trimis" @@ -22337,6 +22634,10 @@ msgstr "Comentariu la eveniment" msgid "Event console" msgstr "Consola de evenimente" +#, fuzzy +msgid "Event console alerts" +msgstr "Alertele din consola de evenimente" + msgid "Event console performance" msgstr "Performanța consolei de evenimente" @@ -23567,10 +23868,6 @@ msgstr "Nu a reușit să redea valoarea:" msgid "Failed to render value: %r" msgstr "Nu a reușit să redea valoarea: %r." -#, fuzzy, python-format -msgid "Failed to save broker certificates: %s" -msgstr "Nu s-a reușit să se obțină certificatul peer (%s)" - #, python-format msgid "Failed to search rule of ruleset '%s' in folder '%s' (%r): %s" msgstr "" @@ -23681,6 +23978,10 @@ msgstr "" "rezultat al nodurilor suplimentare va declanșa cel puțin o stare de " "AVERTISMENT." +#, fuzzy +msgid "Failure" +msgstr "eșecuri" + msgid "Failures of the join launcher service" msgstr "Eșecuri ale serviciului de lansare a îmbinării" @@ -23976,6 +24277,10 @@ msgstr "Dimensiunea fișierului de mai jos" msgid "File size levels" msgstr "Niveluri de mărime a fișierelor" +#, fuzzy +msgid "File upload" +msgstr "Byte încărcate" + #, python-format msgid "File upload test for remote storage failed. Original error message: %s" msgstr "" @@ -24104,6 +24409,10 @@ msgstr "" "Filtrează toate agregările care se bazează pe informațiile de stare ale " "gazdei respective. Potrivire exactă (fără expresie regulată)" +#, fuzzy +msgid "Filter for hosts/services" +msgstr "Timpul de nefuncționare pentru gazdă/serviciu" + msgid "Filter group (see help)" msgstr "Grup de filtre (a se vedea ajutorul)" @@ -24773,6 +25082,9 @@ msgstr "Rețele" msgid "Form factor" msgstr "Factor de formă" +msgid "FormSpec and internal data structure mismatch" +msgstr "" + msgid "Format" msgstr "Format" @@ -25401,6 +25713,11 @@ msgstr "Generați" msgid "Generate REST API specification" msgstr "Generarea specificației REST API" +msgid "" +"Generate a key for the app: Create a Secret key in the app settings and note " +"it down." +msgstr "" + msgid "Generate backup codes" msgstr "Generarea codurilor de rezervă" @@ -25466,6 +25783,21 @@ msgstr "Rata generică" msgid "Generic string" msgstr "Șir generic" +msgid "Gerrit" +msgstr "" + +#, fuzzy +msgid "Gerrit Version" +msgstr "Versiunea Kernel" + +#, fuzzy +msgid "Gerrit connection" +msgstr "Editați conexiunea" + +#, fuzzy +msgid "Gerrit instance to query." +msgstr "Instanța Jenkins de interogat." + msgid "Get file from SFTP server" msgstr "Obțineți fișierul de pe serverul SFTP" @@ -25524,6 +25856,10 @@ msgstr "Regula de notificare globală" msgid "Global notification rules" msgstr "Reguli globale de notificare" +#, fuzzy +msgid "Global services" +msgstr "Toate serviciile" + msgid "Global services to monitor" msgstr "Servicii globale de monitorizare" @@ -25549,6 +25885,10 @@ msgstr "Model de globbing pentru fișierele de intrare" msgid "Go critical if all licenses are used" msgstr "Devine critic dacă sunt folosite toate licențele" +#, fuzzy +msgid "Go to \"All hosts\"" +msgstr "Toate gazdele" + msgid "Go to AWS root account > Services > IAM." msgstr "" @@ -25561,6 +25901,12 @@ msgstr "Mergeți la pagina principală" msgid "Go to rules of this InfluxDB connection" msgstr "Mergeți la regulile acestei conexiuni InfluxDB" +#, python-format +msgid "" +"Go to the Monitor > All Hosts page or click the Go to All hosts button to " +"start monitoring your %s services." +msgstr "" + msgid "Go to the Saas Admin Panel" msgstr "Mergeți la panoul de administrare Saas" @@ -25724,18 +26070,12 @@ msgstr "Carduri grafice" msgid "Graphs" msgstr "Grafice" -msgid "Graphs are shown among each other" -msgstr "Graficele sunt afișate între ele" - msgid "Graphs for averaged single-core utilizations" msgstr "Grafice pentru media utilizărilor pe un singur nucleu" msgid "Graphs for individual cores" msgstr "Grafice pentru nuclee individuale" -msgid "Graphs per notification (default: 5)" -msgstr "Grafice pe notificare (implicit: 5)" - msgid "Graylog" msgstr "Graylog" @@ -25824,9 +26164,6 @@ msgstr "Grup de bază DN" msgid "Group discovery and activation for up to" msgstr "Descoperirea și activarea grupurilor pentru până la" -msgid "Group execution interval" -msgstr "Intervalul de execuție a grupului" - msgid "Group files based on a regular expression pattern." msgstr "Grupați fișiere pe baza unui model de expresie regulată." @@ -26026,6 +26363,10 @@ msgstr "HPE StoreOnce prin REST API 4.x" msgid "HR: Used memory via SNMP" msgstr "HR: Memorie utilizată prin SNMP" +#, fuzzy +msgid "HTML Email parameters" +msgstr "Parametrii modelului" + #, fuzzy msgid "HTML email" msgstr "Email HTML" @@ -27362,6 +27703,10 @@ msgstr "Ascundeți numele variabilelor de configurare" msgid "Hide notification bulks" msgstr "reguli de notificare" +#, fuzzy +msgid "Hide other recipients: Send individual notifications to each recipient" +msgstr "Trimiteți notificări separate fiecărui destinatar" + msgid "Hide response from socket" msgstr "Ascundeți răspunsul de la soclu" @@ -27427,6 +27772,10 @@ msgstr "Istorie" msgid "History Line Number" msgstr "Numărul liniei de istorie" +#, fuzzy +msgid "History action type" +msgstr "Statul de înregistrare" + msgid "History entries of one specific event" msgstr "Înregistrări istorice ale unui anumit eveniment" @@ -29104,10 +29453,6 @@ msgstr "Prezentare generală a gazdei" msgid "Host parent/child topology" msgstr "Topologia gazdă părinte/copil" -#, fuzzy -msgid "Host path" -msgstr "Alertă gazdă" - msgid "Host performance data" msgstr "Date privind performanța gazdei" @@ -29816,6 +30161,10 @@ msgstr "IP - regiune - ID instanță" msgid "IP Address" msgstr "Adresa IP" +#, fuzzy +msgid "IP Address of Hosts" +msgstr "Adresa IP a gazdei" + msgid "IP address" msgstr "Adresa IP" @@ -31831,21 +32180,6 @@ msgstr "" "face parte din spațiile de nume corespunzătoare, cum ar fi, de exemplu, " "podurile." -#, fuzzy -msgid "" -"If your monitoring produces a notification that is not matched by any of " -"your notification rules, the notification will not be sent out. To prevent " -"that, we recommend configuring either the global setting or enable the " -"fallback contact option for at least one of your users." -msgstr "" -"Avertisment

    Nu ați configurat o >adresă de e-" -"mail de rezervă și nici nu ați activat primirea de e-mailuri de rezervă " -"pentru niciun utilizator. Dacă monitorizarea dvs. produce o notificare care " -"nu se potrivește cu niciuna dintre regulile de notificare, notificarea nu va " -"fi trimisă. Pentru a preveni acest lucru, vă rugăm să configurați fie " -"setarea globală, fie să activați opțiunea de contact de rezervă pentru cel " -"puțin unul dintre utilizatorii dvs." - msgid "Ignore" msgstr "Ignoră" @@ -32837,6 +33171,15 @@ msgstr "" msgid "Indexspace wasted" msgstr "Spațiu de indexare irosit" +#, fuzzy +msgid "" +"Indicates that host is waiting for bulk discovery. It is set to True once it " +"in queue.Removed after discovery is ended." +msgstr "" +"Dacă ultima descoperire în masă a eșuat sau nu. Este setat la True atunci " +"când eșuează și se dezactivează în cazul în care o descoperire ulterioară " +"reușește." + msgid "Indices" msgstr "Indicii" @@ -33506,6 +33849,10 @@ msgstr "Certificat invalid" msgid "Invalid certificate file: %s" msgstr "Fișier de certificat invalid: %s" +#, fuzzy, python-format +msgid "Invalid characters in %s" +msgstr "Parametru nevalabil %r: %s" + msgid "Invalid check parameter" msgstr "Parametru de control invalid" @@ -36315,6 +36662,10 @@ msgstr "Inventarul Linux Multipath" msgid "Linux and Solaris Multipath Count" msgstr "Linux și Solaris Multipath Count" +#, fuzzy +msgid "Linux bonding" +msgstr "Vswitch bonding" + msgid "Linux bonding interface status" msgstr "Starea interfeței Linux bonding" @@ -36902,6 +37253,10 @@ msgstr "" "Înregistrați procesul de înregistrare a agentului de cereri primite prin " "comanda de înregistrare a controlorului agentului Checkmk." +#, fuzzy +msgid "Log the automatic host removal process." +msgstr "Activați eliminarea automată a gazdei" + msgid "Log: Details" msgstr "Jurnal: Detalii" @@ -37411,6 +37766,10 @@ msgstr "" "Numărul total de clienți în așteptare pentru un apel de blocare Nivel " "inferior" +#, fuzzy +msgid "Lower limit of expected interfaces" +msgstr "Lista fișierelor de jurnal așteptate" + msgid "Lowest: No notification, update badge number" msgstr "Cel mai mic: Nici o notificare, actualizarea numărului de legitimație" @@ -37983,10 +38342,25 @@ msgstr "Gestionarea utilizatorilor sistemului de monitorizare." msgid "Managed Robot" msgstr "Obiecte gestionate" +#, fuzzy +msgid "Managed Robots" +msgstr "Obiecte gestionate" + #, fuzzy msgid "Managed objects" msgstr "Obiecte gestionate" +#, fuzzy +msgid "Managed robot deleted." +msgstr "Obiecte gestionate" + +msgid "Managed robot not found while attempting to delete it." +msgstr "" + +#, fuzzy +msgid "Managed robots" +msgstr "Obiecte gestionate" + msgid "Management board" msgstr "Consiliul de administrație" @@ -39545,14 +39919,14 @@ msgstr "Conexiuni minime pe secundă" msgid "Minimum error count" msgstr "Număr minim de erori" -#, fuzzy -msgid "Minimum levels for Voltage" -msgstr "Niveluri minime de tensiune" - #, fuzzy msgid "Minimum levels for load in percent" msgstr "Nivelurile minime pentru sarcină în procente" +#, fuzzy +msgid "Minimum levels for voltage" +msgstr "Niveluri minime de tensiune" + msgid "Minimum levels if using magic factor" msgstr "Nivelurile minime în cazul utilizării factorului magic" @@ -39659,6 +40033,10 @@ msgstr "Durată neprogramată (numai pentru DaemonSet)" msgid "Misscheduled replicas" msgstr "Replici neprogramate" +#, fuzzy +msgid "Missing catalog topic." +msgstr "Variabila lipsă siteid" + #, python-format msgid "Missing config file for agent %s%s" msgstr "Lipsește fișierul de configurare pentru agent %s%s" @@ -41160,6 +41538,11 @@ msgstr "Rezoluția numelui" msgid "Name your %s for easy recognition." msgstr "Dați un nume %s pentru a fi ușor de recunoscut." +msgid "" +"Name your host, define the path and select the authority you would like to " +"monitor" +msgstr "" + msgid "" "Name your host, define the path and select the regions you would like to " "monitor" @@ -41175,13 +41558,13 @@ msgstr "Nume" #, fuzzy msgid "" "Names for files containing additional command line arguments for " -"Robot Framework. The paths are relative to the robot suites base " -"directory. Argument files allow the placing of all or some command line " -"options and arguments into an external file from where they will be read. " -"This is useful for more exotic RF parameters not natively supported by " -"Robotmk or for problematic characters. The arguments given here are used " -"along with possible other command line options. (See also base directory of Robot " +"Framework projects. Argument files allow the placing of all or some " +"command line options and arguments into an external file from where they " +"will be read. This is useful for more exotic RF parameters not natively " +"supported by Robotmk or for problematic characters. The arguments given here " +"are used along with possible other command line options. (See also About argument files)" msgstr "" "Nume pentru fișierele care conțin argumente suplimentare pentru linia de " @@ -41599,6 +41982,29 @@ msgstr "Următoarea notificare" msgid "Next run" msgstr "Următoarea cursă" +#, fuzzy +msgid "Next step: General properties" +msgstr "Proprietăți generale" + +#, fuzzy +msgid "Next step: Notification method (plug-in)" +msgstr "Plugin-uri de notificare" + +#, fuzzy +msgid "Next step: Recipient" +msgstr "Destinatarul" + +msgid "Next step: Saving" +msgstr "" + +#, fuzzy +msgid "Next step: Sending conditions" +msgstr "conexiuni în așteptare" + +#, fuzzy +msgid "Next step: Specify host/services" +msgstr "Tipul de comentariu (gazdă/serviciu)" + msgid "Nginx Server" msgstr "Server Nginx" @@ -41614,6 +42020,10 @@ msgstr "Niveluri de IO agile" msgid "No" msgstr "Nu" +#, fuzzy, python-format +msgid "No %s configuration yet" +msgstr "Configurație gazdă" + #, python-format msgid "No (Error: %s, Code: %d, Depth: %d)" msgstr "Nu (Eroare: %s, Cod: %d, Adâncime: %d)" @@ -41621,6 +42031,10 @@ msgstr "Nu (Eroare: %s, Cod: %d, Adâncime: %d)" msgid "No API integrations, no Checkmk agent" msgstr "Fără integrări API, fără agent Checkmk" +#, fuzzy +msgid "No AWS services found." +msgstr "Nu s-au găsit gazde/servicii." + msgid "No CSRF token received" msgstr "Nu s-a primit niciun token CSRF" @@ -41631,6 +42045,10 @@ msgstr "Fără condiții" msgid "No Configuration Quick setup for %s available" msgstr "Variabila de configurare:" +#, fuzzy, python-format +msgid "No FormSpec implementation for method '%s' found." +msgstr "Regula de notificare modificată %d" + msgid "No IP" msgstr "Fără IP" @@ -41706,10 +42124,6 @@ msgstr "Nu sunt posibile comenzi în această vizualizare" msgid "No conditions" msgstr "Fără condiții" -#, fuzzy -msgid "No configuration yet" -msgstr "Configurație gazdă" - msgid "No configured rules are affected" msgstr "Nu sunt afectate regulile configurate" @@ -41766,6 +42180,14 @@ msgstr "" msgid "No edit configuration bundle implemented for bundle group type '%s'." msgstr "" +#, fuzzy +msgid "No elements available" +msgstr "nu este disponibil" + +#, fuzzy +msgid "No elements selected" +msgstr "Nu este selectat" + msgid "No entries" msgstr "Nu există intrări" @@ -41898,6 +42320,10 @@ msgstr "Nu sunt definite conexiuni" msgid "No need for syncing sites" msgstr "Nu este nevoie de site-uri de sincronizare" +#, fuzzy, python-format +msgid "No notification parameters for method '%s' found" +msgstr "Regula de notificare modificată %d" + msgid "No object type" msgstr "Nici un tip de obiect" @@ -41908,6 +42334,10 @@ msgstr "Nu a fost introdusă nicio parolă. Vă rugăm să introduceți o parol msgid "No password provided" msgstr "Din magazinul de parole" +#, fuzzy +msgid "No password selected" +msgstr "Din magazinul de parole" + msgid "No pending changes" msgstr "Nu există modificări în curs de desfășurare" @@ -41983,6 +42413,10 @@ msgstr "Fără căutare" msgid "No search, specify list of arguments" msgstr "Fără căutare, specificați lista de argumente" +#, fuzzy +msgid "No smarthosts" +msgstr "Smarthost-uri" + msgid "No snapshot to restore available." msgstr "Nu este disponibil niciun instantaneu pentru restaurare." @@ -42444,6 +42878,9 @@ msgstr "Notificare" msgid "Notation: %s" msgstr "Adnotare: %s" +msgid "Note down the generated Access key ID and Secret access key." +msgstr "" + msgid "" "Note that since OpenSSH 7.6, only version 2 is supported. Therefore, newer " "versions neither use nor report this configuration variable anymore." @@ -42610,6 +43047,18 @@ msgstr "Nivelul jurnalului de notificare" msgid "Notification method" msgstr "Metoda de notificare" +#, fuzzy, python-format +msgid "Notification method '%s' does not exist" +msgstr "Colecția de grafice \"%s\" nu există" + +#, fuzzy +msgid "Notification method (plug-in)" +msgstr "Plugin-uri de notificare" + +#, fuzzy +msgid "Notification parameter" +msgstr "Faza de notificare" + #, fuzzy msgid "Notification period" msgstr "Perioada de notificare" @@ -43056,6 +43505,14 @@ msgstr "Numărul de dosare care trebuie create în fiecare nivel" msgid "Number of goroutines" msgstr "Numărul de încercări repetate" +#, fuzzy +msgid "Number of graphs per event (default: 5)" +msgstr "Grafice pe notificare (implicit: 5)" + +#, fuzzy +msgid "Number of graphs per notification (default: 5)" +msgstr "Grafice pe notificare (implicit: 5)" + msgid "Number of healthy hosts lower levels" msgstr "Numărul de gazde sănătoase niveluri inferioare" @@ -43695,8 +44152,9 @@ msgstr "OSN Atenuarea laserului" msgid "OTLP endpoint" msgstr "Punct final" -msgid "OVS bonding interface status" -msgstr "Starea interfeței de conectare OVS" +#, fuzzy +msgid "OVS bonding" +msgstr "Vswitch bonding" msgid "Object" msgstr "Obiect" @@ -45743,6 +46201,10 @@ msgstr "Evenimente curente generale" msgid "Overall latency" msgstr "Latență generală" +#, fuzzy +msgid "Overall response time" +msgstr "Timp mediu de răspuns" + msgid "Overall state of a virtual machine (for example ESX VMs)" msgstr "" "Starea generală a unei mașini virtuale (de exemplu, mașinile virtuale ESX)" @@ -45806,7 +46268,7 @@ msgstr "" "Suprascrieți starea de verificare pe baza ultimului rezultat al construcției" #, fuzzy -msgid "Override current plan settings" +msgid "Override managed plan settings" msgstr "Unitatea de suprascriere a senzorului" msgid "Override unit of sensor" @@ -46399,13 +46861,16 @@ msgstr "Sarcina conexiunilor paralele" msgid "Parallel pings to send" msgstr "Ping-uri paralele de trimis" -#, fuzzy -msgid "Parallel plan groups" -msgstr "Grupuri de execuție a suitei" +msgid "Parallel running sequences of plans" +msgstr "" msgid "Parallelize core config creation" msgstr "Crearea în paralel a configurației de bază" +#, fuzzy +msgid "Parameter" +msgstr "Parametrii" + msgid "Parameter groups" msgstr "Grupuri de parametri" @@ -46415,6 +46880,10 @@ msgstr "Grupuri de parametri pe regiune" msgid "Parameter name" msgstr "Numele parametrului" +#, fuzzy +msgid "Parameter properties" +msgstr "Proprietățile pachetului" + msgid "Parameter rule set" msgstr "Set de reguli de parametri" @@ -46439,6 +46908,10 @@ msgstr "" "gazdei și al serviciului, puteți insera valoarea reală a parametrilor prin " "$HOST$ și $INST$ (încadrate în semne de dolar)." +#, fuzzy +msgid "Parameters for" +msgstr "Parametrii pentru %s" + #, python-format msgid "Parameters for %s" msgstr "Parametrii pentru %s" @@ -46446,6 +46919,10 @@ msgstr "Parametrii pentru %s" msgid "Parameters for input phases of UPSs and PDUs" msgstr "Parametrii pentru fazele de intrare ale UPS-urilor și PDU-urilor" +#, fuzzy +msgid "Parameters for notification methods" +msgstr "Parametrii pentru această gazdă" + msgid "Parameters for output loads of UPSs and PDUs" msgstr "Parametrii pentru sarcinile de ieșire ale UPS-urilor și PDU-urilor" @@ -47480,6 +47957,10 @@ msgstr "Ping la adresa IP normală" msgid "Ping timeout" msgstr "Ping timeout" +#, fuzzy +msgid "Placeholder" +msgstr "VM-uri de tip Placeholder" + msgid "Placeholder VMs" msgstr "VM-uri de tip Placeholder" @@ -47531,6 +48012,10 @@ msgid "" msgstr "" "Combinațiile de nume și etichete ale aplicației suite trebuie să fie unice." +#, fuzzy +msgid "Plan settings" +msgstr "Setări globale" + msgid "Plans" msgstr "" @@ -47557,6 +48042,10 @@ msgstr "Vă rugăm să adăugați cel puțin o coloană la vizualizarea dvs." msgid "Please add at least one endpoint to monitor" msgstr "Vă rugăm să adăugați cel puțin un punct final pentru a monitoriza" +#, fuzzy +msgid "Please add at least one recipient" +msgstr "Vă rugăm să adăugați cel puțin un nod copil." + msgid "" "Please avoid very large subnet sizes/ranges. A netmask value of /21 is " "probably ok, while larger subnets (i.e. smaller netmask values) will lead to " @@ -47618,6 +48107,10 @@ msgstr "Vă rugăm să alegeți o imagine PNG validă." msgid "Please choose an audit log to view:" msgstr "Vă rugăm să alegeți un jurnal de audit pe care să îl vizualizați:" +#, fuzzy +msgid "Please choose one or more regions to continue" +msgstr "Vă rugăm să alegeți un raport de programat" + #, fuzzy msgid "Please choose the check plug-in" msgstr "Vă rugăm să alegeți plugin-ul de verificare" @@ -48279,6 +48772,10 @@ msgstr "Plugin-uri, verificări locale și MRPE pentru utilizatorii non-root" msgid "Plugin" msgstr "Plugin" +#, fuzzy +msgid "Plugin output" +msgstr "Ieșirea plugin-ului" + msgid "Plugins" msgstr "Plugin-uri" @@ -48421,6 +48918,10 @@ msgstr "Potrivire pozitivă (Adăugați gazdele corespunzătoare la set)" msgid "Positive match (Add matching services to the set)" msgstr "Potrivire pozitivă (Adăugați serviciile corespunzătoare la set)" +#, fuzzy +msgid "Positive match (Add services hosts to the set)" +msgstr "Potrivire pozitivă (Adăugați gazdele corespunzătoare la set)" + msgid "Postfix" msgstr "Postfix" @@ -48600,6 +49101,10 @@ msgstr "Prefix text" msgid "Prepare AWS for Checkmk" msgstr "GIT inițializat pentru Checkmk" +#, fuzzy +msgid "Prepare Azure for Checkmk" +msgstr "GIT inițializat pentru Checkmk" + msgid "Prepend namespace prefix for hosts" msgstr "Prefixul de spațiu de nume pentru gazde" @@ -49258,11 +49763,10 @@ msgstr "Executarea plugin-ului agentului Python (UNIX)" msgid "" "Python or YAML file to read variables from. (About variable files) Possible " +"html#variable-files\" target=\"_blank\">About variable files). Possible " "arguments to the variable file can be given after the file path using a " -"colon or a semicolon as a separator. Examples:\n" -"path/vars.yaml\n" -"set_environment.py:testing" +"colon or a semicolon as a separator. Examples:
    path/vars.yaml
    set_environment.py:testing" msgstr "" "Fișier Python sau YAML din care se citesc variabilele. (not available
    because Robotmk Core MKP " +"has been installed)" msgstr "Utilizați SSL pentru conexiune." +#, fuzzy msgid "" "RCC profile configuration: RCC profiles can define settings for this " -"specific RCC environment, for example Proxy settings.
    " +"specific RCC environment, for example proxy settings." msgstr "" "Configurarea profilului RCC: Profilurile RCC pot defini setările pentru " "acest mediu RCC specific, de exemplu, setările Proxy.
    ." @@ -50114,6 +50620,10 @@ msgstr "Destinatarul" msgid "Recipient email address" msgstr "Destinatarul Adresa de e-mail" +#, fuzzy +msgid "Recipients" +msgstr "Destinatarul" + #, python-format msgid "Recipients: %s" msgstr "Beneficiari: %s" @@ -50616,6 +51126,10 @@ msgstr "Viața rămasă" msgid "Remaining Open Slots" msgstr "Sloturi rămase deschise" +#, fuzzy +msgid "Remaining certificate validity time" +msgstr "Perioada de valabilitate rămasă" + msgid "Remaining credits lower levels" msgstr "Credite rămase niveluri inferioare" @@ -50776,9 +51290,6 @@ msgstr "Îndepărtați toate fișierele și subdirectoarele" msgid "Remove downtimes" msgstr "Eliminați timpii de nefuncționare" -msgid "Remove downtimes?" -msgstr "Eliminați timpii de întrerupere?" - msgid "Remove explicit attribute settings" msgstr "Eliminarea setărilor explicite ale atributelor" @@ -50807,6 +51318,10 @@ msgstr "Eliminați perioadele de întrerupere programate?" msgid "Remove service" msgstr "Îndepărtarea serviciului" +#, fuzzy +msgid "Remove smarthost" +msgstr "Eliminați această intrare" + msgid "Remove style" msgstr "Eliminați stilul" @@ -51377,6 +51892,10 @@ msgid "" "version v2.4.1 or higher" msgstr "" +#, fuzzy +msgid "Requests data from a Gerrit instance." +msgstr "Solicită date de la o instanță Jenkins." + #, fuzzy msgid "Requests data from a Jenkins instance." msgstr "Solicită date de la o instanță Jenkins." @@ -51420,6 +51939,10 @@ msgstr "Port necesar" msgid "Required context filters" msgstr "Filtre de context necesare" +#, fuzzy +msgid "Required field missing" +msgstr "Site-ul lipsește" + msgid "Required match (regular expression)" msgstr "Potrivire necesară (expresie regulată)" @@ -51737,6 +52260,10 @@ msgstr "" msgid "Restrict number of processed messages per cycle" msgstr "Limitarea numărului de mesaje procesate pe ciclu" +#, fuzzy +msgid "Restrict previous options to" +msgstr "Limitați severitatea la cel mult" + msgid "Restrict runtime of logfile parsing" msgstr "Restricționarea timpului de execuție a analizei fișierelor jurnal" @@ -51881,6 +52408,11 @@ msgstr "" "Obținerea de informații despre procese utilizând WMI (Windows Management " "Instrumentation)" +msgid "" +"Retrieve required information: Gather Subscription ID, Tenant ID, Client ID, " +"and the Client secret from Azure." +msgstr "" + msgid "Retry" msgstr "Reîncercare" @@ -51905,6 +52437,10 @@ msgstr "Reîncercați acest test" msgid "Retry time" msgstr "Timpul de reintroducere" +#, fuzzy +msgid "Return WARNING if found, OK if not" +msgstr "returnează CRITICAL dacă este găsit, OK dacă nu este găsit" + msgid "Return code class 2xx (success)" msgstr "Cod de returnare clasa 2xx (succes)" @@ -51922,7 +52458,12 @@ msgstr "Timpii de procesare a returului în cadrul datelor de performanță" msgid "" "Return to Checkmk, define a unique AWS account name, and use the Access key " -"and Secret access key below." +"ID and Secret access key below." +msgstr "" + +msgid "" +"Return to Checkmk: Define a unique Azure account name, and use the " +"Subscription ID, Tenant ID, Client ID, and the Client secret below." msgstr "" msgid "" @@ -51945,10 +52486,19 @@ msgstr "Activați modificările străine" msgid "Review and run preview service discovery" msgstr "Salvați & rulați descoperirea serviciilor" +#, fuzzy +msgid "Review and test configuration" +msgstr "Configurație la distanță" + #, fuzzy msgid "Review your configuration and run preview service discovery" msgstr "Salvați & rulați descoperirea serviciilor" +msgid "" +"Review your notification rule before applying it. They will take effect " +"right away without \"Activate changes\"." +msgstr "" + msgid "Revolutions per minute" msgstr "Rotații pe minut" @@ -51999,6 +52549,10 @@ msgstr "Cadrul robotului: %s" msgid "Robot Framework: Last log" msgstr "Cadrul robotului: Ultimul jurnal" +#, fuzzy +msgid "Robot package" +msgstr "Îndepărtați pachetul" + msgid "" "Robotmk (as part of Checkmk Synthetic Monitoring) integrates the results of " "Robot Framework tests as Checkmk services." @@ -53103,12 +53657,14 @@ msgstr "Salvați ca nou aspect pentru această agregare" msgid "Save response" msgstr "Salvați răspunsul" -msgid "Save the generated Access key and Secret access key." -msgstr "" - msgid "Save this host and go to" msgstr "Salvați această gazdă și mergeți la" +msgid "" +"Save your progress and go to the Activate Changes page to enable it. EC2 " +"instances may take a few minutes to show up." +msgstr "" + #, python-format msgid "Saved check configuration of host '%s' with %d services" msgstr "" @@ -53159,9 +53715,6 @@ msgstr "Programarea timpului de oprire pe gazdă" msgid "Schedule downtime on service" msgstr "Programarea timpului de oprire a serviciului" -msgid "Schedule downtime?" -msgstr "Programarea timpilor morți?" - msgid "Schedule downtimes" msgstr "Programarea perioadelor de oprire" @@ -53533,6 +54086,10 @@ msgstr "" msgid "Secret access key" msgstr "Cheia secretă" +#, fuzzy +msgid "Secret access key cannot be empty" +msgstr "Cheia secretă" + msgid "Secret key" msgstr "Cheia secretă" @@ -53704,6 +54261,15 @@ msgstr "Selectați un fișier iCalendar (*.ics) de pe PC-ul dvs." msgid "Select and configure AWS services you would like to monitor" msgstr "Servicii Azure de monitorizat" +#, fuzzy +msgid "" +"Select and configure the Microsoft Azure services you would like to monitor" +msgstr "Servicii Azure de monitorizat" + +#, fuzzy +msgid "Select contact group" +msgstr "Grupuri de contact de reguli" + #, fuzzy msgid "Select datasource" msgstr "Selectați sursa de date" @@ -53925,6 +54491,10 @@ msgstr "Selectați tipul de element de pagină fix" msgid "Select type from list" msgstr "Selectați tipul din listă" +#, fuzzy +msgid "Select user" +msgstr "Ștergeți utilizatorul" + msgid "Select view" msgstr "Selectați vizualizarea" @@ -53962,6 +54532,10 @@ msgstr "Site-urile %s selectate au fost șterse." msgid "Selected credential has been deleted" msgstr "Acreditivul selectat a fost șters" +#, fuzzy +msgid "Selected options" +msgstr "Conexiuni respinse" + msgid "Selected sections will not be executed by the agent." msgstr "Secțiunile selectate nu vor fi executate de către agent." @@ -54032,6 +54606,10 @@ msgstr "Trimiteți date HTTP POST" msgid "Send custom notification" msgstr "Trimiteți o notificare personalizată" +#, fuzzy +msgid "Send custom notification?" +msgstr "Trimiteți o notificare personalizată" + #, fuzzy msgid "Send data" msgstr "Parola" @@ -54078,9 +54656,7 @@ msgid "Send notifications to remote Event Console" msgstr "Trimiteți notificări către consola de evenimente la distanță" #, fuzzy -msgid "" -"Send out HTML/ASCII email notification according to notification rules " -"(uncheck to avoid spam)" +msgid "Send out HTML/ASCII email notification according to notification rules" msgstr "" "Trimiteți notificări în conformitate cu regulile de notificare (debifați " "pentru a evita spam-ul)" @@ -54092,10 +54668,6 @@ msgstr "" "Trimiteți indiferent de restricții, de exemplu, perioada de notificare sau " "notificări dezactivate (forțate)" -#, fuzzy -msgid "Send separate notifications to every recipient" -msgstr "Trimiteți notificări separate fiecărui destinatar" - msgid "Send service metrics to Graphite" msgstr "Trimiteți parametrii serviciului către Graphite" @@ -54139,6 +54711,10 @@ msgstr "Trimiteți prin e-mail" msgid "Sending Power" msgstr "Puterea de trimitere" +#, fuzzy +msgid "Sending conditions" +msgstr "Condiții stabilite" + msgid "Sending reply" msgstr "Trimiterea răspunsului" @@ -54192,7 +54768,11 @@ msgid "September" msgstr "Septembrie" #, fuzzy -msgid "Sequential plans" +msgid "Sequence execution interval" +msgstr "Intervalul de execuție a grupului" + +#, fuzzy +msgid "Sequence of plans" msgstr "Programarea execuției" msgid "Serial" @@ -54428,6 +55008,10 @@ msgstr "Descoperirea serviciilor: Descrierea serviciului" msgid "Service discovery: State" msgstr "Descoperirea serviciilor: Stare" +#, fuzzy +msgid "Service events" +msgstr "Nivelul serviciilor" + msgid "Service goes into critical state" msgstr "Serviciul trece în stare critică" @@ -54780,6 +55364,10 @@ msgstr "Serviciile site-ului" msgid "Services per cluster" msgstr "Servicii per cluster" +#, fuzzy +msgid "Services per region" +msgstr "Servicii de monitorizat pe regiune" + msgid "Services per region to monitor" msgstr "Servicii de monitorizat pe regiune" @@ -55317,7 +55905,7 @@ msgstr "" msgid "" "Sets a limit for the number of notifications in a bulk for which graphs are " "displayed. If you do not use bulk notifications this option is ignored. Note " -"that each graph increases the size of the mail and takes time to renderon " +"that each graph increases the size of the mail and takes time to render on " "the monitoring server. Therefore, large bulks may exceed the maximum size " "for attachements or the plug-in may run into a timeout so that a failed " "notification is produced." @@ -55701,6 +56289,10 @@ msgstr "Afișați casetele de selectare" msgid "Show column headings" msgstr "Afișați titlurile coloanelor" +#, fuzzy +msgid "Show contact groups" +msgstr "Grupuri de contact gazdă" + msgid "Show context" msgstr "Afișați contextul" @@ -55767,9 +56359,17 @@ msgstr "Afișați indicii în meniul 'Utilizator' meniu" msgid "Show historic values" msgstr "Afișați valorile istorice" +#, fuzzy +msgid "Show host labels" +msgstr "Afișați în tabelele gazdă" + msgid "Show host status" msgstr "Afișați starea gazdei" +#, fuzzy +msgid "Show host tags" +msgstr "Afișați starea gazdei" + msgid "Show icon linking to Setup parameter editor for services" msgstr "" "Afișarea pictogramei care face legătura cu editorul de parametri de " @@ -55847,6 +56447,10 @@ msgstr "Arată mai mult / Arată mai puțin" msgid "Show notification bulks" msgstr "reguli de notificare" +#, fuzzy +msgid "Show notification rule that triggered the notification" +msgstr "Ordinea de sortare a notificărilor pentru notificările în masă" + msgid "Show number of groups" msgstr "Afișați numărul de grupuri" @@ -55909,6 +56513,10 @@ msgstr "Afișați regulile folosind acest %s." msgid "Show separate result for each SLA period" msgstr "Afișați un rezultat separat pentru fiecare perioadă SLA" +#, fuzzy +msgid "Show service labels" +msgstr "Etichete de servicii" + #, fuzzy msgid "Show service name" msgstr "Numele serviciului" @@ -56298,6 +56906,11 @@ msgstr "" "îndoială). Puteți suprascrie acest automatism prin specificarea unui nod " "aici." +msgid "" +"Since managed robots are used in bakery rules, you need the permission to " +"edit these rules to access this page." +msgstr "" + msgid "" "Since the sensor description is a user defined text, multiple sensors may " "have the same description. To ensure that items are unique, they are " @@ -57229,6 +57842,10 @@ msgstr "Obiecte specifice" msgid "Specific sites" msgstr "Situri specifice" +#, fuzzy +msgid "Specific users" +msgstr "Situri specifice" + msgid "Specific version" msgstr "Versiune specifică" @@ -57251,13 +57868,6 @@ msgstr "" msgid "Specifies the default line style" msgstr "Specifică stilul de linie implicit" -msgid "" -"Specifies the maximum time that the scheduler allows for a Robot Framework " -"execution. This time, multiplied by the number of repeated executions, may " -"not be greater in total with all other plans in this group than the group " -"execution interval." -msgstr "" - msgid "Specifies whether password authentication is allowed" msgstr "Specifică dacă este permisă autentificarea cu parolă" @@ -57429,17 +58039,6 @@ msgstr "" "trebuie curățat după un anumit timp sau după un anumit număr de execuții de " "test." -#, fuzzy -msgid "" -"Specify here whether the working directory of Robotmk (`C:\\ProgramData" -"\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " -"should be cleaned up either after a certain time or after a certain number " -"of test executions." -msgstr "" -"Specificați aici dacă directorul de lucru al Robotmk de pe gazda țintă " -"trebuie curățat după un anumit timp sau după un anumit număr de execuții de " -"test." - #, fuzzy, python-format msgid "" "Specify how Checkmk will translate the exit code of a task into a monitoring " @@ -57896,6 +58495,11 @@ msgstr "" "Precizați ce trebuie să facem dacă graficul selectat lipsește sau nu poate " "fi recuperat." +msgid "" +"Specify when and how notifications are sent based on frequency, timing, and " +"content criteria." +msgstr "" + msgid "Specify which port types should not be discovered" msgstr "Specificați ce tipuri de porturi nu trebuie să fie descoperite" @@ -58111,6 +58715,10 @@ msgstr "Începutul anului viitor" msgid "Start or end of a scheduled downtime" msgstr "Începutul sau sfârșitul unei perioade de întrerupere programată" +#, fuzzy +msgid "Start or end of downtime" +msgstr "Începutul perioadei de întrerupere" + msgid "Start or end of flapping state" msgstr "Începutul sau sfârșitul stării de fluturare" @@ -58333,6 +58941,14 @@ msgstr "" msgid "State for specific bonding modes" msgstr "Stare pentru anumite moduri de lipire" +#, fuzzy +msgid "State for unexpected number of interfaces" +msgstr "Avertizare privind o interfață activă neașteptată" + +#, fuzzy +msgid "State found during service discovery" +msgstr "Descoperirea serviciilor în așteptare" + msgid "State if 'maintenance' services are found" msgstr "Stabiliți dacă 'întreținere' serviciile sunt găsite" @@ -59373,10 +59989,12 @@ msgstr "Denumirea secțiunii" msgid "Subject for bulk notifications" msgstr "Subiect pentru notificări în masă" -msgid "Subject for host notifications" +#, fuzzy +msgid "Subject line for host notifications" msgstr "Subiect pentru notificările gazdelor" -msgid "Subject for service notifications" +#, fuzzy +msgid "Subject line for service notifications" msgstr "Subiect pentru notificările de serviciu" msgid "Submit" @@ -59771,6 +60389,10 @@ msgstr "Sincronă" msgid "Syncing" msgstr "Sincronizare" +#, fuzzy +msgid "Syncing broker certificates" +msgstr "Certificat de router SAP" + msgid "Synology Updates" msgstr "Actualizări Synology" @@ -60054,6 +60676,10 @@ msgstr "TLS" msgid "TLS Authentication without TLS is not possible" msgstr "TLS Autentificarea fără TLS nu este posibilă" +#, fuzzy +msgid "TLS certificate verification" +msgstr "Verificarea certificatului SSL" + msgid "TLS processed bytes" msgstr "Byte procesați TLS" @@ -60273,6 +60899,16 @@ msgstr "" "Etichetele pot fi utilizate pentru a clasifica gazdele și serviciile într-un " "mod flexibil." +msgid "Tags enabled but no key defined." +msgstr "" + +msgid "Tags enabled but no tags defined." +msgstr "" + +#, fuzzy +msgid "Tags enabled but no values defined." +msgstr "Nu este definită nicio sursă de date." + #, fuzzy, python-format msgid "Tags of the alert.

    %s" msgstr "Etichete de alertă." @@ -60513,6 +61149,10 @@ msgstr "" msgid "Test authentication" msgstr "Test de autentificare" +#, fuzzy +msgid "Test configuration" +msgstr "Configurație gazdă" + msgid "Test connection" msgstr "Conexiune de testare" @@ -60543,6 +61183,9 @@ msgstr "Notificări de testare pe" msgid "Test runtime" msgstr "Timpul de execuție a testului" +msgid "Test the AWS connection based on your configuration settings" +msgstr "" + msgid "Test verification" msgstr "Verificarea testelor" @@ -61796,6 +62439,10 @@ msgstr "" "Site-ul central (%s) și cel de la distanță (%s) nu sunt compatibile. " "Motivul: %s." +#, fuzzy +msgid "The changes have been activated successfully." +msgstr "Nu a fost niciodată activat" + #, python-format msgid "The character %s is not allowed here." msgstr "Caracterul %s nu este permis aici." @@ -62084,6 +62731,11 @@ msgstr "" "Conexiunea creează gazde în acest dosar special. Odată creată, puteți alege " "să mutați gazda într-un alt dosar." +msgid "" +"The connection to AWS was successful, but no services were found. If this is " +"unintentional, please verify your configuration." +msgstr "" + msgid "The connection to this site has been disabled." msgstr "Conexiunea la acest site a fost dezactivată." @@ -62349,25 +63001,6 @@ msgstr "Elementul nu poate fi găsit în tabloul de bord." msgid "The element does not exist." msgstr "Elementul nu există." -msgid "" -"The email address and visible name used in the From header of notifications " -"messages. If no email address is specified the default address is " -"OMD_SITE@FQDN is used. If the environment variable OMD_SITE is not set it defaults to checkmk." -msgstr "" -"Adresa de e-mail și numele vizibil utilizate în antetul From (De la) al " -"mesajelor de notificare. Dacă nu se specifică nicio adresă de e-mail, se " -"utilizează adresa implicită OMD_SITE@FQDN. Dacă variabila de mediu " -"OMD_SITE nu este setată, se utilizează în mod implicit checkmk." - -msgid "" -"The email address and visible name used in the Reply-To header of " -"notifications messages." -msgstr "" -"Adresa de e-mail și numele vizibil utilizate în antetul Reply-To al " -"mesajelor de notificare." - #, fuzzy msgid "" "The email address is optional and is needed if the user is a monitoring " @@ -62734,12 +63367,6 @@ msgstr "Lipsește specificația grafică" msgid "The graph template id '%s' is disabled" msgstr "Șablonul grafic id '%s' este dezactivat" -msgid "" -"The group execution interval must be greater than the sum of the individual " -"plan runtime limits. The runtime limit of a plan is calculated as follows: " -"limit_per_attempt x (1 + max_number_of_reexecutions)." -msgstr "" - msgid "" "The handled messages (see subject matching) can be cleaned up by " "either deleting them or moving them to a subfolder. By default nothing is " @@ -62976,13 +63603,6 @@ msgstr "" "Numele instanței, numele bazei de date și numele tablespace-ului combinate " "astfel db2wps8:WPSCOMT8.USERSPACE1" -msgid "" -"The interval at which an execution group is executed. The interval must be " -"larger than the sum of the individual plan runtime limits. The runtime limit " -"of a plan is calculated as follows: limit_per_attempt x (1 + " -"max_number_of_reexecutions)." -msgstr "" - msgid "" "The interval the connection will be executed to check the available " "piggyback and update the configuration." @@ -63366,6 +63986,12 @@ msgstr "" "serviciu să intre în stare de alertă/critică. Această alarmă se aplică numai " "la gazda țintă, nu și la salturile intermediare." +msgid "" +"The maximum time that the Robotmk scheduler allows for a single Robot " +"Framework execution. This time, when multiplied by the number of executions, " +"sets the total runtime limit for the execution of a plan." +msgstr "" + msgid "The maximum value length is 256 characters." msgstr "Lungimea maximă a valorii este de 256 de caractere." @@ -65036,6 +65662,20 @@ msgstr "" "Pragurile pentru wait_duration_ms. Va suprascrie starea implicită stabilită " "mai sus." +msgid "" +"The time interval for the execution of a sequence of plans must be longer " +"than the sum of all total plan runtime limits. The total runtime limit of a " +"plan is calculated as follows: limit_per_attempt x (1 + " +"max_number_of_reexecutions)." +msgstr "" + +msgid "" +"The time interval for the execution of a sequence of plans. This interval " +"must be longer than the sum of all total plan runtime limits. The total " +"runtime limit of a plan is calculated as follows: limit_per_attempt x (1 " +"+ max_number_of_reexecutions)." +msgstr "" + msgid "The time interval statistical data is saved to disk" msgstr "Intervalul de timp în care datele statistice sunt salvate pe disc" @@ -65190,6 +65830,14 @@ msgid "The username returned by the %s connector is not of type string (%r)." msgstr "" "Numele de utilizator returnat de conectorul %s nu este de tip string (%r)." +#, fuzzy +msgid "" +"The username that should be used for accessing the Gerrit API. Must have (at " +"least) read permissions." +msgstr "" +"Numele de utilizator care trebuie utilizat pentru accesarea API Graylog. " +"Trebuie să aibă cel puțin permisiuni de citire." + msgid "" "The username that should be used for accessing the Graylog API. Has to have " "read permissions at least." @@ -65497,8 +66145,8 @@ msgstr "Nu există niciun instantaneu de configurare care să fie restaurat." msgid "There is no backup job configured" msgstr "Nu este configurată nicio sarcină de backup" -#, python-format -msgid "There is no graph template with the id '%s'" +#, fuzzy, python-format +msgid "There is no graph graph_plugin with the id '%s'" msgstr "Nu există niciun șablon de grafic cu id '%s'" msgid "There is no manpage for this check." @@ -65672,7 +66320,7 @@ msgstr "Aceste noduri se află doar în agregarea înghețată" msgid "" "These options allow specifying the most common command line parameters for " "the Robot Framework. In order to use other parameters, you can use the " -"option \"Arguments file\"" +"option \"Arguments file\"." msgstr "" "Aceste opțiuni permit specificarea celor mai comuni parametri de linie de " "comandă pentru Robot Framework.Pentru a utiliza alți parametri (a se vedea " @@ -65999,6 +66647,9 @@ msgstr "" "agentului de pe gazda monitorizată (consultați `cmk-agent-ctl help`)." +msgid "This action will affect all pending changes you have made." +msgstr "" + msgid "" "This active check sends out special emails to a defined mail address using " "either the SMTP protocol or an EWS connection and then tries to receive " @@ -66741,10 +67392,11 @@ msgid "" "service in the following table." msgstr "" +#, fuzzy msgid "" "This is essentially the raw agent updater script that gets packaged within " "the binary versions. You have to care for the dependencies by yourself. The " -"script requires a Python 3.4 (or greater) installation and matching python " +"script requires a Python 3.7 (or greater) installation and matching python " "packages \"requests\", \"PySocks\" and \"cryptography\" installed on the " "target hosts. Requirements may change eventually without announcement. " "However, this might be the right choice for experienced users or users that " @@ -67600,8 +68252,7 @@ msgstr "" #, fuzzy msgid "" -"This permission allows users to administrate (add, delete, modify) managed " -"robots." +"This permission allows users to edit (add, delete, modify) managed robots." msgstr "" "Această permisiune permite utilizatorilor să migreze alți utilizatori către " "o altă conexiune" @@ -68217,13 +68868,6 @@ msgstr "" "va duce la modificări frecvente în inventarul HW/SW, ceea ce poate umple " "rapid sistemul de fișiere temporare." -msgid "" -"This rule allows monitoring of VMware ESX via the vSphere API. You can " -"configure your connection settings here." -msgstr "" -"Această regulă permite monitorizarea VMware ESX prin intermediul vSphere " -"API. Puteți configura aici setările de conectare." - msgid "" "This rule allows querying an AppDynamics server for information about Java " "applicationsvia the AppDynamics REST API. You can configure your connection " @@ -68922,15 +69566,6 @@ msgstr "" "Checkmk normal și permite monitorizarea prin intermediul NetApp Ontap REST " "API." -msgid "" -"This rule set selects the special agent for HPE StoreOnce Appliances instead " -"of the normal Checkmk agent and allows monitoring via REST API v4.x or " -"higher. " -msgstr "" -"Acest set de reguli selectează agentul special pentru HPE StoreOnce " -"Appliances în locul agentului Checkmk normal și permite monitorizarea prin " -"REST API v4.x sau o versiune mai recentă. " - msgid "" "This rule sets limits to the current number of connections through a Check " "Point firewall." @@ -73692,9 +74327,16 @@ msgstr "" msgid "Tried to register incompatible rulespec: %r" msgstr "A încercat să înregistreze o specificație de reguli incompatibilă: %r." +#, fuzzy +msgid "Triggering events" +msgstr "Arhiva evenimentelor" + msgid "Trivial change" msgstr "Schimbare banală" +msgid "Troubleshooting/testing settings" +msgstr "" + msgid "" "Truncate content at this amount of characters.A zero value mean not to " "truncate" @@ -74886,6 +75528,14 @@ msgstr "Încărcați răspunsul" msgid "Upload verification response file" msgstr "Încărcați fișierul de răspuns la verificare" +#, fuzzy +msgid "Uploaded" +msgstr "Încărcați" + +#, fuzzy +msgid "Uploaded by" +msgstr "Încărcați cheia" + #, python-format msgid "Uploaded custom GUI logo: %s" msgstr "A fost încărcat un logo personalizat pentru GUI: %s." @@ -76284,6 +76934,12 @@ msgstr "" "mode=mkeventd_edit_configvar&site=&varname=event_limit\">limita globală a " "evenimentului de regulă
    " +#, fuzzy +msgid "Use this option to query a non-standard port." +msgstr "" +"Utilizați această opțiune pentru a interoga un port diferit de portul " +"standard 443." + msgid "" "Use this option to query a port which is different from standard port 443." msgstr "" @@ -76325,6 +76981,15 @@ msgstr "" "interogat următorul server (fallback). Verificarea va emite date numai de la " "prima gazdă care trimite un răspuns." +#, fuzzy +msgid "" +"Use this option to set which instance should be checked by the special " +"agent. Please add the host name here, e.g. my_gerrit.com." +msgstr "" +"Utilizați această opțiune pentru a seta instanța care trebuie verificată de " +"către agentul special. Vă rugăm să adăugați aici numele de gazdă, de exemplu " +"my_graylog.com." + #, fuzzy msgid "" "Use this option to set which instance should be checked by the special " @@ -76728,7 +77393,8 @@ msgstr "Mesaje de utilizator" msgid "User name" msgstr "Numele utilizatorului" -msgid "User name on the storage system. Read only permissions are sufficient." +#, fuzzy +msgid "User name on the storage system. Read-only permissions are sufficient." msgstr "" "Numele de utilizator pe sistemul de stocare. Permisiunile de numai citire " "sunt suficiente." @@ -76826,6 +77492,10 @@ msgstr "" "Utilizatorii care figurează aici au în continuare dreptul de a modifica " "lucruri." +#, fuzzy +msgid "Users of contact groups" +msgstr "Membri ai grupurilor de contact" + msgid "Users using a cifs share" msgstr "Utilizatori care utilizează o partajare cifs" @@ -77872,6 +78542,10 @@ msgstr "Verificarea certificatelor" msgid "Verify SSL certificate (not verifying is insecure)" msgstr "Ignoră erorile de certificat (nesigur)" +#, fuzzy +msgid "Verify TLS certificate (not verifying is insecure)" +msgstr "Ignoră erorile de certificat (nesigur)" + msgid "Verify certificates" msgstr "Verificarea certificatelor" @@ -77935,6 +78609,9 @@ msgstr "Versiunea dispozitivului PKI" msgid "Version of Server" msgstr "Versiunea serverului" +msgid "Version will only appear in summary if non-OK state set." +msgstr "" + #, python-format msgid "Version: %s" msgstr "Versiunea: %s" @@ -78392,6 +79069,10 @@ msgstr "Conexiuni în așteptare" msgid "Waiting containers" msgstr "Containere în așteptare" +#, fuzzy +msgid "Waiting for discovery" +msgstr "Descoperirea portului Netapp" + msgid "" "Waiting for first status update from the job. In case this message is shown " "for a longer time, the startup got interrupted." @@ -78775,6 +79456,9 @@ msgstr "Care este ocazia?" msgid "What is the purpose?" msgstr "Care este scopul?" +msgid "What should be send out?" +msgstr "" + msgid "" "When Multisite is running in debug mode, internal Python error messages are " "being displayed and various debug information in other places is also " @@ -79848,6 +80532,10 @@ msgstr "" msgid "Who" msgstr "Cine" +#, fuzzy +msgid "Who should receive the notification?" +msgstr "permite utilizatorilor să dezactiveze această notificare" + msgid "WiFi connection types" msgstr "Tipuri de conexiuni WiFi" @@ -80010,7 +80698,7 @@ msgstr "" #, fuzzy msgid "" "With the help of the RCC binary, the robotmk scheduler can generate the Python " +"\"_blank\">RCC binary, the Robotmk scheduler can generate the Python " "environments required for the execution of Robot Framework suites. This " "eliminates the need to install and configure Python and all of its library " "packages on the target hosts. RCC environments are created right after the " @@ -80334,6 +81022,13 @@ msgstr "" "configurați parametri. Acest lucru poate crea confuzie.Această " "regulă ar trebui configurată numai în etapele inițiale." +msgid "" +"Without a fallback email address, you may miss alerts that are not covered " +"by a notification rule. To ensure full notification coverage, we recommend " +"that you configure the fallback email address to which all alerts that don't " +"match a notification rule are sent." +msgstr "" + msgid "" "Without authentication everybody can send notifications to the spooler. If " "you choose Authentication with TLS this site must trust the SiteCA " @@ -81261,6 +81956,14 @@ msgstr "Nu puteți șterge conexiunea cu site-ul local." msgid "You can not delete this %s because it is in use." msgstr "Nu puteți șterge acest %s, deoarece este în uz." +#, fuzzy, python-format +msgid "" +"You can not delete this managed robot because it is in use in the following " +"rules:%s" +msgstr "" +"Nu puteți șterge această țintă, deoarece este utilizată de aceste lucrări de " +"backup: %s." + #, python-format msgid "" "You can not delete this target because it is used by these backup jobs: %s" @@ -82081,6 +82784,10 @@ msgstr "" "Nu ați creat încă niciun agent signature keys. Acest lucru este necesar." +#, fuzzy +msgid "You have not created any parameters for this notification method yet." +msgstr "Parametrii pentru această gazdă" + msgid "" "You have not created any rule packs yet. The Event Console is useless unless " "you have activated Force message archiving in the global settings." @@ -84002,9 +84709,6 @@ msgstr "" msgid "mm" msgstr "mm" -msgid "monitor" -msgstr "monitor" - msgid "month" msgstr "luna" @@ -84920,6 +85624,9 @@ msgstr "{actual} este prea mare. Valoarea maximă admisă este {bound}." msgid "{actual} is too low. The minimum allowed value is {bound}." msgstr "{actual} este prea mică. Valoarea minimă admisă este {bound}." +msgid "{checkname} - {check['title']}" +msgstr "" + #, python-brace-format msgid "{region} ({id_})" msgstr "" @@ -84928,6 +85635,146 @@ msgstr "" msgid "© %s Checkmk GmbH. All Rights Reserved." msgstr "© %s Checkmk GmbH. Toate drepturile rezervate." +#, fuzzy +msgid "⚠ not available because Robotmk Core MKP has been installed" +msgstr "Utilizați SSL pentru conexiune." + +#, fuzzy +#~ msgid "" +#~ "Specify here whether the working directory of Robotmk (`C:\\ProgramData" +#~ "\\checkmk\\agent\\robotmk_output\\working\\suites`) on the target host " +#~ "should be cleaned up either after a certain time or after a certain " +#~ "number of test executions." +#~ msgstr "" +#~ "Specificați aici dacă directorul de lucru al Robotmk de pe gazda țintă " +#~ "trebuie curățat după un anumit timp sau după un anumit număr de execuții " +#~ "de test." + +#~ msgid "API key from password store" +#~ msgstr "Cheia API din magazinul de parole" + +#, fuzzy +#~ msgid "Host Path" +#~ msgstr "Alertă gazdă" + +#, fuzzy, python-format +#~ msgid "Failed to save broker certificates: %s" +#~ msgstr "Nu s-a reușit să se obțină certificatul peer (%s)" + +#, fuzzy +#~ msgid "" +#~ "If your monitoring produces a notification that is not matched by any of " +#~ "your notification rules, the notification will not be sent out. To " +#~ "prevent that, we recommend configuring either the global setting or " +#~ "enable the fallback contact option for at least one of your users." +#~ msgstr "" +#~ "Avertisment

    Nu ați configurat o
    >adresă de e-" +#~ "mail de rezervă și nici nu ați activat primirea de e-mailuri de " +#~ "rezervă pentru niciun utilizator. Dacă monitorizarea dvs. produce o " +#~ "notificare care nu se potrivește cu niciuna dintre regulile de " +#~ "notificare, notificarea nu va fi trimisă. Pentru a preveni acest lucru, " +#~ "vă rugăm să configurați fie setarea globală, fie să activați opțiunea de " +#~ "contact de rezervă pentru cel puțin unul dintre utilizatorii dvs." + +#~ msgid "Bulk notifications with graphs (default: 5)" +#~ msgstr "Notificări în masă cu grafice (implicit: 5)" + +#~ msgid "" +#~ "By default all multiple graphs in emails are displayed floating nearby. " +#~ "You can enable this option to show the graphs among each other." +#~ msgstr "" +#~ "În mod implicit, toate graficele multiple din e-mailuri sunt afișate în " +#~ "mod plutitor în apropiere. Puteți activa această opțiune pentru a afișa " +#~ "graficele unele printre altele." + +#, fuzzy +#~ msgid "" +#~ "Configure this to have the notification plug-in connect directly to the " +#~ "SMTP server. This has the advantage of providing better error messages in " +#~ "case of an error, but it does require more configuration and is strictly " +#~ "synchronous. So we advice use only on enterprise installations using the " +#~ "notification spooler." +#~ msgstr "" +#~ "Configurarea acestui lucru pentru ca pluginul de notificare să se " +#~ "conecteze direct la serverul smtp. Acest lucru are avantajul de a oferi " +#~ "mesaje de eroare mai bune în caz de eroare, dar necesită mai multă " +#~ "configurare și este strict sincronă, așa că vă recomandăm să o utilizați " +#~ "numai în cazul instalațiilor de întreprindere care utilizează spoolerul " +#~ "de notificare." + +#~ msgid "Display additional information" +#~ msgstr "Afișarea de informații suplimentare" + +#~ msgid "Display graphs among each other" +#~ msgstr "Afișarea graficelor între ele" + +#~ msgid "Graphs are shown among each other" +#~ msgstr "Graficele sunt afișate între ele" + +#~ msgid "" +#~ "The email address and visible name used in the From header of " +#~ "notifications messages. If no email address is specified the default " +#~ "address is OMD_SITE@FQDN is used. If the environment variable " +#~ "OMD_SITE is not set it defaults to checkmk." +#~ msgstr "" +#~ "Adresa de e-mail și numele vizibil utilizate în antetul From (De la) al " +#~ "mesajelor de notificare. Dacă nu se specifică nicio adresă de e-mail, se " +#~ "utilizează adresa implicită OMD_SITE@FQDN. Dacă variabila de " +#~ "mediu OMD_SITE nu este setată, se utilizează în mod implicit " +#~ "checkmk." + +#~ msgid "" +#~ "The email address and visible name used in the Reply-To header of " +#~ "notifications messages." +#~ msgstr "" +#~ "Adresa de e-mail și numele vizibil utilizate în antetul Reply-To al " +#~ "mesajelor de notificare." + +#~ msgid "Activate" +#~ msgstr "Activați" + +#~ msgid "Deactivate" +#~ msgstr "Dezactivați" + +#~ msgid "" +#~ "This rule allows monitoring of VMware ESX via the vSphere API. You can " +#~ "configure your connection settings here." +#~ msgstr "" +#~ "Această regulă permite monitorizarea VMware ESX prin intermediul vSphere " +#~ "API. Puteți configura aici setările de conectare." + +#~ msgid "" +#~ "This rule set selects the special agent for HPE StoreOnce Appliances " +#~ "instead of the normal Checkmk agent and allows monitoring via REST API v4." +#~ "x or higher. " +#~ msgstr "" +#~ "Acest set de reguli selectează agentul special pentru HPE StoreOnce " +#~ "Appliances în locul agentului Checkmk normal și permite monitorizarea " +#~ "prin REST API v4.x sau o versiune mai recentă. " + +#~ msgid "monitor" +#~ msgstr "monitor" + +#, fuzzy +#~ msgid "AWS account name" +#~ msgstr "Numele contului de stocare" + +#, fuzzy +#~ msgid "Parallel plan groups" +#~ msgstr "Grupuri de execuție a suitei" + +#~ msgid "(not supported)" +#~ msgstr "(neacceptat)" + +#~ msgid "Remove downtimes?" +#~ msgstr "Eliminați timpii de întrerupere?" + +#~ msgid "Schedule downtime?" +#~ msgstr "Programarea timpilor morți?" + +#~ msgid "OVS bonding interface status" +#~ msgstr "Starea interfeței de conectare OVS" + #~ msgid "Common Name" #~ msgstr "Denumire comună" @@ -85055,10 +85902,6 @@ msgstr "© %s Checkmk GmbH. Toate drepturile rezervate." #~ msgid "Used quota: Absolute or relative upper levels" #~ msgstr "Cota utilizată: Niveluri superioare absolute sau relative" -#, fuzzy -#~ msgid "Changes have been activated" -#~ msgstr "Nu a fost niciodată activat" - #, fuzzy #~ msgid "Decimal places" #~ msgstr "Tablespaces" @@ -85356,10 +86199,6 @@ msgstr "© %s Checkmk GmbH. Toate drepturile rezervate." #~ msgid "%s operations" #~ msgstr "%s operațiuni" -#, fuzzy, python-format -#~ msgid "%s requests" -#~ msgstr "%s Cereri" - #~ msgid "" #~ "Amount of time that the application of redo data on the standby database " #~ "lags behind the primary database" @@ -85727,9 +86566,6 @@ msgstr "© %s Checkmk GmbH. Toate drepturile rezervate." #~ msgid "InfluxDB Queue Usage" #~ msgstr "InfluxDB Queue Utilizare" -#~ msgid "Kernel Version" -#~ msgstr "Versiunea Kernel" - #~ msgid "Levels Helper usage Check" #~ msgstr "Niveluri Verificarea utilizării Helper" diff --git a/notifications/templates/.f12 b/notifications/templates/.f12 new file mode 100755 index 00000000000..dae16488a6a --- /dev/null +++ b/notifications/templates/.f12 @@ -0,0 +1,22 @@ +#!/bin/bash +# 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. + +set -e + +SITE=${SITE:-$(until [ "${PWD}" = / ]; do if [ -e .site ]; then + cat .site + break +else cd ..; fi; done)} +SITE=${SITE:-$(omd sites --bare | head -n 1)} +ROOT=/omd/sites/$SITE + +TARGET="${ROOT}/share/check_mk/notifications/templates/" +mkdir -p "$TARGET" +rsync \ + -vrlD \ + --exclude="__pycache__" \ + --exclude ".mypy_cache" \ + . \ + "${TARGET}" diff --git a/notifications/templates/mail/additional.html b/notifications/templates/mail/additional.html new file mode 100644 index 00000000000..375c364177a --- /dev/null +++ b/notifications/templates/mail/additional.html @@ -0,0 +1,156 @@ + +{% macro additional_tr(data, title, key) %} + + {{ title }}: + {{ data[key] }} + +{% endmacro %} + + + + + + + + + + +
    +   +
    + + Additional details +
    + + {%for element in data.PARAMETER_ELEMENTSS.split(' ') %} + {% if element =="ack_author" %} + {% if service_notification %} + {{additional_tr(data,"Acknowledgment author", "data.SERVICEACKAUTHOR") }} + {% else%} + {{additional_tr(data, "Acknowledgment author", "data.HOSTACKAUTHOR") }} + {%endif %} + {% elif element == "ack_comment" %} + {% if service_notification %} + {{additional_tr(data, "Acknowledgment comment", "data.SERVICEACKCOMMENT") }} + {%else %} + {{ additional_tr(data, "Acknowledgment comment","data.HOSTACKCOMMENT")}} + {% endif %} + {% elif element == "notification_author" %} + {% if service_notification %} + {{ additional_tr(data, "Notification author","data.SERVICEACKAUTHOR") }} + {% else %} + {{ additional_tr(data, "Notification author", "data.HOSTACKAUTHOR") }} + {% endif %} + {% elif element == "notification_comment" %} + {% if service_notification %} + {{ additional_tr(data, "Notification comment", "data.SERVICEACKCOMMENT") }} + {% else%} + {{additional_tr(data, "Notification comment", "data.HOSTACKCOMMENT") }} + {% endif %} + {% elif element == "omdsite" %} + {{ additional_tr(data, "Site", "OMD_SITE") }} + {% elif element == "reltime" %} + {% if service_notification %} + {{additional_tr(data, "Relative time", "LASTSERVICESTATECHANGE_REL") }} + {% else %} + {{ additional_tr(data, "Relative time", "LASTHOSTSTATECHANGE_REL") }} + {% endif %} + {% elif element == "perfdata" %} + {% if service_notification %} + {{additional_tr(data, "Service metrics", "SERVICEPERFDATA") }} + {% else %} + {{additional_tr(data, "Host metrics", "HOSTPERFDATA") }} + {% endif %} + {% elif element == "notesurl" %} + {% if service_notification %} + {{ additional_tr(data,"Custom service notes URL", "SERVICENOTESURL") }} + {% else %} + {{additional_tr(data, "Custom host notes URL", "HOSTNOTESURL") }} + {% endif %} + {%elif element == "context" %} + + + + + + + {% endif %} + {% endfor %} +
    + Complete variable list: +
    + + {% for key, value in data.items() %} + + + + + {% endfor %} +
    + {{ key }} + + + {{ value }} +
    +
    +
    diff --git a/notifications/templates/mail/base.html b/notifications/templates/mail/base.html new file mode 100644 index 00000000000..e07b2c15461 --- /dev/null +++ b/notifications/templates/mail/base.html @@ -0,0 +1,208 @@ + + + + HTML Email template + + + + {% import 'macros.html' as macros %} + + {% set service_notification = data.WHAT == 'SERVICE' %} + + {% if service_notification %} + {% set href = data.LINKEDSERVICEDESC.split('"')[1] %} + {% else %} + {% set href = data.LINKEDHOSTNAME.split('"')[1] %} + {% endif %} + + {% if data.PARAMETER_ELEMENTSS %} + {% set elements = data.PARAMETER_ELEMENTSS.split() %} + {% else %} + {% set elements = ["graph"] %} + {% endif %} + + {% set elements_without_graph = elements | reject("equalto", "graph") | list %} + + {% set state_mapping = { + "OK":"background-color: #13D389; color: #000000;", + "UP": "background-color: #13D389; color: #000000;", + "WARNING":"background-color: #FFD703; color: #000000;", + "CRITICAL": "background-color: #C83232; color: #ffffff;", + "DOWN":"background-color: #C83232; color: #ffffff;", + "UNKNOWN": "background-color: #ff8800; color: #ffffff;", + "UNREACHABLE":"background-color: #ff8800; color: #ffffff;", + "PENDING":"background-color: #888888; color: #ffffff;", } + %} + + + + + +
    + + {{ macros.margin_tr() }} + + +
    + {% if not is_bulk or bulk_summary %} + + + + +
    + Checkmk Logo +
    + + + + + +
    + + + + +
    + + +   + +
    +
    + {% endif %} + + + {% if bulk_summary %} + {% include 'bulk.html' %} + {% endif %} + + {% if insert %} +
    +
    + {{ insert|safe }} +
    +
    + {% endif %} + + {% include 'summary.html' %} + + + {% include 'event_overview.html' %} + + {% if graphs and 'graph' in elements %} + {% include 'graph.html' %} + {% endif %} + + + {% if elements_without_graph %} + {% include 'additional.html' %} + {% endif %} + + {% if data.PARAMETER_CONTACT_GROUPS %} + {% include 'contact_groups.html' %} + {% endif %} + + {% if service_notification and data.PARAMETER_SVC_LABELS%} + {% include 'service_labels.html' %} + {% endif %} + + {% if data.PARAMETER_HOST_LABELS %} + {% include 'host_labels.html' %} + {% endif %} + + {% if data.PARAMETER_HOST_TAGS %} + {% include 'host_tags.html' %} + {% endif %} + + {% if href %} + {{ macros.view_issue_button(href) }} + {% endif %} +
    +
    +
    + {% if not is_bulk or last_bulk_entry %} + + + + +
    +

    + Checkmk GmbH
    Kellerstraße 27, München, Bayern 81667, Germany
    +49 89 998209700 +

    +
    + {% endif %} + + diff --git a/notifications/templates/mail/bulk.html b/notifications/templates/mail/bulk.html new file mode 100644 index 00000000000..3f88f663b18 --- /dev/null +++ b/notifications/templates/mail/bulk.html @@ -0,0 +1,162 @@ + + + + + + + + + {% for entry in bulk_summary %} + {% set bulk_service_notification = entry.WHAT == 'SERVICE' %} + + + + + + + {% endfor %} +
    + Host + + Service + + Event + + Event date +
    + {{ entry.LINKEDHOSTNAME | safe }} + + {% if bulk_service_notification %} + {{ entry.LINKEDSERVICEDESC | safe }} + {% endif %} + + + + + + + +
    +
    + {% if service_notification %} + {{ data.PREVIOUSSERVICEHARDSTATE[:4] }} + {% else %} + {{ data.PREVIOUSHOSTHARDSTATE[:4] }} + {% endif %} +
    +
    + +
    + –› +
    + +
    +
    + {% if service_notification %} + {{ data.SERVICESTATE[:4] }} + {% else %} + {{ data.HOSTSTATE[:4] }} + {% endif %} +
    +
    +
    + {{ entry.LONGDATETIME }} +
    + + + + + + + +
    + + View event history + +
    +   +
    diff --git a/notifications/templates/mail/contact_groups.html b/notifications/templates/mail/contact_groups.html new file mode 100644 index 00000000000..9430318f7c1 --- /dev/null +++ b/notifications/templates/mail/contact_groups.html @@ -0,0 +1,49 @@ + + + + + + + + + + + +
    +   +
    + + Contact groups +
    + {% for item in data.HOSTCONTACTGROUPNAMES.split(',') %} + + • {{ item }} + + {% endfor %} +
    diff --git a/notifications/templates/mail/event_overview.html b/notifications/templates/mail/event_overview.html new file mode 100644 index 00000000000..68f7b545930 --- /dev/null +++ b/notifications/templates/mail/event_overview.html @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + {% if service_notification %} + + + +
    +   +
    + Event overview + Event overview +
    + Event date: + + {{ data.LONGDATETIME }} +
    + Address: + + {{ data.HOSTADDRESS }} +
    + Site: + + {{ data.OMD_SITE }} +
    + Summary: + + {% if service_notification %} + {{ macros.replace_statemarker(data.SERVICEOUTPUT_HTML) }} + {% else %} + {{ macros.replace_statemarker(data.HOSTOUTPUT_HTML) }} + {%endif %} +
    + Service details: +
    + + + + + {% endif %} +
    +

    + {% if data.LONGSERVICEOUTPUT_HTML %} + {{ macros.replace_statemarker(data.LONGSERVICEOUTPUT_HTML) }} + {% else %} + No details available + {%endif %} +

    +
    diff --git a/notifications/templates/mail/graph.html b/notifications/templates/mail/graph.html new file mode 100644 index 00000000000..b2d4a8ea240 --- /dev/null +++ b/notifications/templates/mail/graph.html @@ -0,0 +1,73 @@ + + + + + + + + + + + +
    +   +
    + Graph Icon + Graph +
    + {% for graph in graphs %} + Graph Image + {% endfor %} +
    + + + + + +
    + + View graph to inspect + +
    diff --git a/notifications/templates/mail/host_labels.html b/notifications/templates/mail/host_labels.html new file mode 100644 index 00000000000..cb1390186f2 --- /dev/null +++ b/notifications/templates/mail/host_labels.html @@ -0,0 +1,64 @@ + + + + + + + + + + + +
    +   +
    + + Host labels +
    + {% for key, value in data.items() %} {% if + key.startswith('HOSTLABEL_') %} + + {{ key[10:] }}:{{ value }} + + {% endif %} {% endfor %} +
    diff --git a/notifications/templates/mail/host_tags.html b/notifications/templates/mail/host_tags.html new file mode 100644 index 00000000000..c12f8dac653 --- /dev/null +++ b/notifications/templates/mail/host_tags.html @@ -0,0 +1,61 @@ + + + + + + + + + + + +
    +   +
    + + Host tags +
    + {% for tag_with_id in data.HOSTTAGS.split(' ') %} + + {{ tag_with_id }} + + {% endfor %} +
    diff --git a/notifications/templates/mail/macros.html b/notifications/templates/mail/macros.html new file mode 100644 index 00000000000..30558c97801 --- /dev/null +++ b/notifications/templates/mail/macros.html @@ -0,0 +1,116 @@ +{% macro td_first_child(width, padding="0") %} + style=" + padding: {{ padding }}; + font-size: 14px; + color: #2c3844; + font-weight: 600; + width: {{ width }}; + height:33px; + " +{%endmacro %} + +{% macro td_last_child() %} + style=" + font-size: 14px; color:#2c3844; + " +{% endmacro %} + +{% macro replace_statemarker(data) %} + {% set default_style = 'margin-left: 2px;padding: 1px 3px;border-radius: 4px; + font-size: 7pt;border: 1px solid #666;position: relative;top: -1px;' %} + {{ data | replace('(.)','OK') | replace('(!)', 'WARN') | replace('(!!)', 'CRIT') | replace('(?)', 'UNKN') | safe }} +{% endmacro %} + +{% macro view_issue_button(href) %} + + + + +
    + + + + View issue + + +
    +{% endmacro %} + +{% macro event_marker_style() %} +border-radius: 8px; +width: 70px; +height: 28px; +font-size: 16px; +font-weight: 700; +text-align: center; +line-height: 28px; +{% endmacro %} + +{% macro event_marker_bulk_style() %} +border-radius: 8px; +width: 50px; +height: 20px; +font-size: 10px; +font-weight: 700; +text-align: center; +line-height: 21px; +{% endmacro %} + +{% macro margin_tr() %} + + +   + + +{% endmacro %} diff --git a/notifications/templates/mail/service_labels.html b/notifications/templates/mail/service_labels.html new file mode 100644 index 00000000000..9da23cfce24 --- /dev/null +++ b/notifications/templates/mail/service_labels.html @@ -0,0 +1,78 @@ + + + + + + + + + + + +
    +   +
    + + Service labels +
    + {% set ns = namespace(has_labels = false) %} + {% for key, value in data.items() %} + {% if key.startswith('SERVICELABEL_')%} + {% set ns.has_labels = true %} + + {{ key[13:] }}:{{ value }} + + {% endif %} + {% endfor %} + {% if not ns.has_labels %} +

    + No Service labels +

    + {% endif %} +
    diff --git a/notifications/templates/mail/summary.html b/notifications/templates/mail/summary.html new file mode 100644 index 00000000000..fdbe8ddbca9 --- /dev/null +++ b/notifications/templates/mail/summary.html @@ -0,0 +1,171 @@ + + + + + + + + +
    + + + + + + {% if service_notification %} + + + + + {% endif %} + + + + +
    + Event: + + + + + + + +
    +
    + {% if service_notification %} + {{ data.PREVIOUSSERVICEHARDSTATE[:4] }} + {% else %} + {{ data.PREVIOUSHOSTHARDSHORTSTATE[:4] }} + {% endif %} +
    +
    + +
    + –› +
    + +
    +
    + {% if service_notification %} + {{ data.SERVICESTATE[:4] }} + {% else %} + {{ data.HOSTSTATE[:4] }} + {% endif %} +
    +
    +
    + Service: + + {{ data.LINKEDSERVICEDESC | safe }} +
    + Host: + + {{ data.LINKEDHOSTNAME | safe }} +
    +
    + {% if href %} + {{ macros.view_issue_button(href) }} + {% endif %} +
    diff --git a/omd/BUILD b/omd/BUILD index 7d211023fe6..bc80ef26cea 100644 --- a/omd/BUILD +++ b/omd/BUILD @@ -24,7 +24,8 @@ PACKAGES_INT = [ "//packages/cmk-messaging:pkg_tar", "//packages/cmk-rulesets:pkg_tar", "//packages/cmk-server-side-calls:pkg_tar", - "//packages/cmk-livestatus-client:pkg_tar", + "//packages/cmk-livestatus-client:cmk_livestatus_client_pkg_tar", + "//packages/cmk-livestatus-client:cmk_livestatus_pkg_tar", "//packages/cmk-trace:pkg_tar", ] diff --git a/omd/Pipfile.lock b/omd/Pipfile.lock index bd25d2af575..c6b645ce158 100644 --- a/omd/Pipfile.lock +++ b/omd/Pipfile.lock @@ -51,99 +51,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "checkmk-dev-tools": { "hashes": [ @@ -196,69 +211,70 @@ }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396", + "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38", + "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a", + "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8", + "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b", + "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad", + "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a", + "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a", + "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da", + "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6", + "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8", + "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344", + "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a", + "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8", + "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5", + "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7", + "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170", + "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132", + "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9", + "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd", + "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9", + "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346", + "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc", + "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589", + "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5", + "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915", + "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295", + "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453", + "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea", + "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b", + "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d", + "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b", + "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4", + "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b", + "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7", + "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf", + "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f", + "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91", + "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd", + "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50", + "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b", + "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583", + "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a", + "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984", + "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c", + "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c", + "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25", + "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa", + "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4", + "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3", + "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97", + "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1", + "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd", + "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772", + "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a", + "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729", + "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca", + "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6", + "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635", + "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b", + "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "markers": "python_version >= '3.9'", + "version": "==3.0.1" }, "mdurl": { "hashes": [ @@ -489,11 +505,11 @@ }, "rich": { "hashes": [ - "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", - "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "six": { "hashes": [ diff --git a/omd/packages/bazel_iwyu/mappings/check_mk.imp b/omd/packages/bazel_iwyu/mappings/check_mk.imp index 888c1caf3b9..b97174c74d1 100644 --- a/omd/packages/bazel_iwyu/mappings/check_mk.imp +++ b/omd/packages/bazel_iwyu/mappings/check_mk.imp @@ -25,6 +25,9 @@ { include: ["", private, "", public ] }, { include: ["", private, "", public ] }, { include: ["", private, "", public ] }, + { include: ["", private, "", public ] }, + { include: ["", private, "", public ] }, + { include: ["", private, "", public ] }, { include: ["", private, "", public ] }, { include: ["", private, "", public ] }, { include: ["", private, "", public ] }, @@ -43,4 +46,5 @@ { symbol: ["std::filesystem", private, "", public ] }, { symbol: ["std::hash", private, "", public ] }, { symbol: ["std::__tuple_element_t", private, "", public ] }, + { symbol: ["std::vector", private, "", public ] }, ] diff --git a/omd/packages/bazel_iwyu/mappings/gcc.stl.headers.imp b/omd/packages/bazel_iwyu/mappings/gcc.stl.headers.imp index c6893e92a91..76faffcbfbd 100644 --- a/omd/packages/bazel_iwyu/mappings/gcc.stl.headers.imp +++ b/omd/packages/bazel_iwyu/mappings/gcc.stl.headers.imp @@ -1,307 +1,412 @@ -# GCC STL headers +# GNU libstdc++ mappings generated with: +# +# mapgen/iwyu-mapgen-libstdcxx.py --lang=imp /usr/include/c++/14 \ +# /usr/include/x86_64-linux-gnu/c++/14 +# +# Do not edit! [ - # Note: make sure to sync this setting with iwyu_include_picker.cc - - # Headers explicitly annotated with `@headername` - # ( cd /usr/include/c++/10 && grep -r headername | perl -nle 'm/^([^:]+).*@headername\{([^,]*)\}/ && print qq@ { "include": ["<$1>", "private", "<$2>", "public"] },@' | sort -u ) - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # ( cd /usr/include/x86_64-linux-gnu/c++/11 && grep -r headername | grep -v "c++config.h" | perl -nle 'm/^([^:]+).*@headername\{([^,]*)\}/ && print qq@ { "include": ["<$1>", "private", "<$2>", "public"] },@' | sort -u ) - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # ( cd /usr/crosstool/v12/gcc-4.3.1-glibc-2.3.6-grte/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/include/c++/4.3.1 && grep '^ *# *include' {ext/,tr1/,}* | perl -nle 'm/^([^:]+).*<([^>]+)>/ && print qq@ { "include": ["<$2>", "private", "<$1>", "public"] },@' | grep -e bits/ -e tr1_impl/ | sort -u) - # I removed a lot of 'meaningless' dependencies -- for instance, - # //includes , but if someone is - # using strings, isn't enough to satisfy iwyu. - # We may need to add other dirs in future versions of gcc. - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # Hash and hashtable-based containers. - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # All .tcc files are gcc internal-include files. We get them from - # ( cd /usr/crosstool/v12/gcc-4.3.1-glibc-2.3.6-grte/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/include/c++/4.3.1 && grep -R '^ *# *include.*tcc' * | perl -nle 'm/^([^:]+).*[<"]([^>"]+)[>"]/ && print qq@ { "include": ["<$2>", "private", "<$1>", "public"] },@' | sort ) - # I had to manually edit some of the entries to say the map-to is private. - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "private"] }, - # Some bits->bits //includes: A few files in bits re-export - # symbols from other files in bits. - # ( cd /usr/crosstool/v12/gcc-4.3.1-glibc-2.3.6-grte/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/include/c++/4.3.1 && grep '^ *# *include.*bits/' bits/* | perl -nle 'm/^([^:]+).*<([^>]+)>/ && print qq@ { "include": ["<$2>", "private", "<$1>", "private"] },@' | grep bits/ | sort -u) - # and carefully picked reasonable-looking results (algorithm - # *uses* pair but doesn't *re-export* pair, for instance). - { "include": ["", "private", "", "private"] }, - { "include": ["", "private", "", "private"] }, - { "include": ["", "private", "", "private"] }, - { "include": ["", "private", - "", "private"] }, - { "include": ["", "private", "", "private"] }, - # I don't think we want to be having people move to 'backward/' - # yet. (These hold deprecated STL classes that we still use - # actively.) These are the ones that turned up in an analysis of - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # We have backward as part of the -I search path now, so have the - # non-backwards-prefix version as well. - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - # (This one should perhaps be found automatically somehow.) - { "include": ["", "private", "", "public"] }, - # The location of exception_defines.h varies by GCC version. It should - # never be included directly. - { "include": ["", "private", "", "public"] }, - - # post libstdc++-10 stuff which is not automatically caught by commands above - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, - { "include": ["", "private", "", "public"] }, + # Private-to-public #include mappings. + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + { "include": [ "", "private", "", "public"] }, + # Private-to-private #include mappings. + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, + { "include": ["", "private", "", "private"] }, ] diff --git a/omd/packages/bazel_iwyu/mappings/gcc.symbols.imp b/omd/packages/bazel_iwyu/mappings/gcc.symbols.imp index 02e232fbffe..1596bcdc061 100644 --- a/omd/packages/bazel_iwyu/mappings/gcc.symbols.imp +++ b/omd/packages/bazel_iwyu/mappings/gcc.symbols.imp @@ -82,6 +82,7 @@ { "symbol": [ "sockaddr", "private", "", "public"] }, { "symbol": [ "socklen_t", "private", "", "public"] }, { "symbol": [ "ssize_t", "private", "", "public"] }, + { "symbol": [ "stack_t", "private", "", "public"] }, { "symbol": [ "stat", "private", "", "public"] }, { "symbol": [ "suseconds_t", "private", "", "public"] }, { "symbol": [ "time_t", "private", "", "public"] }, @@ -94,7 +95,6 @@ { "symbol": [ "uid_t", "private", "", "public"] }, { "symbol": [ "useconds_t", "private", "", "public"] }, { "symbol": [ "wchar_t", "private", "", "public"] }, - { "symbol": [ "wchar_t", "private", "", "public"] }, { "symbol": [ "wint_t", "private", "", "public"] }, { "symbol": [ "sig_atomic_t", "private", "", "public"] }, { "symbol": [ "size_t", "private", "", "public"] }, @@ -124,8 +124,6 @@ { "symbol": [ "va_copy", "private", "", "public"] }, { "symbol": [ "va_end", "private", "", "public"] }, { "symbol": [ "va_list", "private", "", "public"] }, - { "symbol": [ "va_list", "private", "", "public"] }, - { "symbol": [ "va_list", "private", "", "public"] }, { "symbol": [ "va_start", "private", "", "public"] }, # These are symbols that could be defined in either stdlib.h or # malloc.h, but we always want the stdlib location. diff --git a/omd/packages/check_mk/check_mk.make b/omd/packages/check_mk/check_mk.make index 2edd1601f4a..34d877428f1 100644 --- a/omd/packages/check_mk/check_mk.make +++ b/omd/packages/check_mk/check_mk.make @@ -92,9 +92,12 @@ $(CHECK_MK_INTERMEDIATE_INSTALL): $(SOURCE_BUILT_AGENTS) $(CHECK_MK_BUILD) $(PAC find $(CHECK_MK_INSTALL_DIR)/share/check_mk/checks -name "*.py" -type f | sed -e 'p;s~.py$$~~' | xargs -n2 mv $(MKDIR) $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications - install -m 755 $(REPO_PATH)/notifications/* $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications + find $(REPO_PATH)/notifications/ -maxdepth 1 -type f ! -name ".*" -exec install -m 755 {} $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications \; chmod 644 $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications/README + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications/templates/mail + find $(REPO_PATH)/notifications/templates/mail/ -maxdepth 1 -type f ! -name ".*" -exec install -m 644 {} $(CHECK_MK_INSTALL_DIR)/share/check_mk/notifications/templates/mail \; + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/share/check_mk/web/htdocs tar -c -C $(REPO_PATH)/packages/cmk-frontend/dist \ $(CHECK_MK_TAROPTS) \ @@ -195,16 +198,16 @@ $(CHECK_MK_INTERMEDIATE_INSTALL): $(SOURCE_BUILT_AGENTS) $(CHECK_MK_BUILD) $(PAC $(MKDIR) $(CHECK_MK_INSTALL_DIR)/lib $(LN) -sf python3/cmk $(CHECK_MK_INSTALL_DIR)/lib/check_mk # ... and ensure the same for the local hierarchy - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk $(LN) -sf python3/cmk $(CHECK_MK_INSTALL_DIR)/skel/local/lib/check_mk # Create the plugin namespaces - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk_addons/plugins - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/base/plugins/agent_based - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/plugins - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/special_agents - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/gui/plugins/views - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/gui/plugins/dashboard - $(MKDIR) -p $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk_addons/plugins + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk_addons/plugins + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/base/plugins/agent_based + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/plugins + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/special_agents + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/gui/plugins/views + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk/gui/plugins/dashboard + $(MKDIR) $(CHECK_MK_INSTALL_DIR)/skel/local/lib/python3/cmk_addons/plugins # Install the diskspace cleanup plugin diff --git a/omd/packages/check_mk/skel/etc/init.d/piggyback-hub b/omd/packages/check_mk/skel/etc/init.d/piggyback-hub index de9009c79b0..62811dfa4c4 100755 --- a/omd/packages/check_mk/skel/etc/init.d/piggyback-hub +++ b/omd/packages/check_mk/skel/etc/init.d/piggyback-hub @@ -28,14 +28,9 @@ force_kill() { kill -9 "${PID}" } -exit_successfully() { - printf "%s\n" "${1}" - exit 0 -} - -exit_failure() { - printf "%s\n" "${1}" - exit 1 +exit_with_code() { + printf "%s\n" "${2}" + exit "${1}" } contains_string() { @@ -55,53 +50,61 @@ distributed_piggyback_enabled() { return 0 } -if ! distributed_piggyback_enabled; then - exit 5 -fi case "$1" in start) printf "Starting piggyback-hub..." + + distributed_piggyback_enabled || exit_with_code 5 'disabled.' + if process_is_running; then - exit_successfully 'already running.' + exit_with_code 0 'already running.' fi "$DAEMON" "$PIDFILE" "$LOGFILE" "$OMD_ROOT" - exit_successfully 'OK' + exit_with_code 0 'OK' ;; stop) - echo -n "Stopping piggyback-hub..." + printf "Stopping piggyback-hub..." + + if distributed_piggyback_enabled; then + code=0 + msg="" + else + code=5 + msg="(disabled)" + fi if [ -z "$PID" ]; then - exit_successfully 'not running' + exit_with_code "${code}" "not running ${msg}" fi if ! process_is_running; then rm "$PIDFILE" - exit_successfully "not running (PID file orphaned)" + exit_with_code "${code}" "not running (PID file orphaned) ${msg}" fi echo -n "killing $PID..." if ! kill "$PID" 2>/dev/null; then rm "$PIDFILE" - exit_successfully 'OK' + exit_with_code "${code}" "OK ${msg}" fi # Signal could be sent # Patiently wait for the process to stop if await_process_stop 60; then - exit_successfully 'OK' + exit_with_code "${code}" "OK ${msg}" fi # Insist on killing the process force_kill if await_process_stop 10; then - exit_successfully 'OK' + exit_with_code "${code}" "OK ${msg}" fi - exit_failure 'failed' + exit_with_code 1 "failed ${msg}" ;; restart | reload) @@ -110,19 +113,28 @@ case "$1" in ;; status) - echo -n 'Checking status of piggyback-hub...' + printf 'Checking status of piggyback-hub...' + + if distributed_piggyback_enabled; then + code=1 + msg="" + else + code=5 + msg="(disabled)" + fi + if [ -z "$PID" ]; then - exit_failure 'not running (PID file missing)' + exit_with_code "${code}" "not running ${msg}" fi if ! process_is_running; then - exit_failure 'not running (PID file orphaned)' + exit_with_code "${code}" "not running ${msg}(PID file orphaned)" fi - exit_successfully 'running' + exit_with_code 0 "running ${msg}" ;; *) - exit_failure "Usage: ${0} {start|stop|restart|reload|status}" + exit_with_code 1 "Usage: ${0} {start|stop|restart|reload|status}" ;; esac diff --git a/omd/packages/libgsf/libgsf.make b/omd/packages/libgsf/libgsf.make index 18a2274afe8..6d60b159993 100644 --- a/omd/packages/libgsf/libgsf.make +++ b/omd/packages/libgsf/libgsf.make @@ -9,19 +9,19 @@ LIBGSF_BUILD_DIR := $(PACKAGE_BUILD_DIR)/$(LIBGSF) .PHONY: $(LIBGSF_BUILD) $(LIBGSF_BUILD): -ifneq ($(filter $(DISTRO_CODE),sles15 sles15sp3 sles15sp4 sles15sp5 sles15sp6),) +ifneq ($(filter sles15%,$(DISTRO_CODE)),) $(BAZEL_CMD) build @$(LIBGSF)//:$(LIBGSF) endif .PHONY: $(LIBGSF_INTERMEDIATE_INSTALL) $(LIBGSF_INTERMEDIATE_INSTALL): $(LIBGSF_BUILD) -ifneq ($(filter $(DISTRO_CODE),sles15 sles15sp3 sles15sp4 sles15sp5 sles15sp6),) +ifneq ($(filter sles15%,$(DISTRO_CODE)),) $(MKDIR) $(LIBGSF_INSTALL_DIR) $(RSYNC) --chmod=u+w $(BAZEL_BIN_EXT)/$(LIBGSF)/$(LIBGSF)/ $(LIBGSF_INSTALL_DIR)/ endif .PHONY: $(LIBGSF_INSTALL) $(LIBGSF_INSTALL): $(LIBGSF_INTERMEDIATE_INSTALL) -ifneq ($(filter $(DISTRO_CODE),sles15 sles15sp3 sles15sp4 sles15sp5 sles15sp6),) +ifneq ($(filter sles15%,$(DISTRO_CODE)),) $(RSYNC) $(LIBGSF_INSTALL_DIR)/ $(DESTDIR)$(OMD_ROOT)/ endif diff --git a/omd/packages/monitoring-plugins/BUILD.monitoring-plugins.bazel b/omd/packages/monitoring-plugins/BUILD.monitoring-plugins.bazel index bee8ad16c55..bf0420fd465 100644 --- a/omd/packages/monitoring-plugins/BUILD.monitoring-plugins.bazel +++ b/omd/packages/monitoring-plugins/BUILD.monitoring-plugins.bazel @@ -87,6 +87,10 @@ POSTFIX_SCRIPT = """ rm -f "$INSTALLDIR/libexec/check_ifoperstatus" "$INSTALLDIR/libexec/check_ifstatus" \ "$INSTALLDIR/libexec/check_disk_smb" + # check_ircd requires the perl module IO::Socket::IP since https://github.com/monitoring-plugins/monitoring-plugins/commit/93cd51bc6221ffc846c69135f2746120683b44c5 + # We don't want to deploy yet another perl module nor cannot guarantee that the required perl version is available under all distros. + rm -f "$INSTALLDIR/libexec/check_ircd" + mkdir -p "$INSTALLDIR/share/doc/monitoring-plugins" cp ACKNOWLEDGEMENTS AUTHORS CODING COPYING FAQ NEWS README REQUIREMENTS SUPPORT THANKS \ "$INSTALLDIR/share/doc/monitoring-plugins" diff --git a/omd/packages/monitoring-plugins/monitoring-plugins_http.bzl b/omd/packages/monitoring-plugins/monitoring-plugins_http.bzl index 1cbb3176c82..07a0f009b94 100644 --- a/omd/packages/monitoring-plugins/monitoring-plugins_http.bzl +++ b/omd/packages/monitoring-plugins/monitoring-plugins_http.bzl @@ -2,7 +2,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("//:bazel_variables.bzl", "UPSTREAM_MIRROR_URL") def monitoring_plugins_workspace(): - version_str = "2.3.3" + version_str = "2.4.0" filename = "monitoring-plugins-" + version_str + ".tar.gz" http_archive( name = "monitoring-plugins", @@ -11,7 +11,7 @@ def monitoring_plugins_workspace(): "https://www.monitoring-plugins.org/download/" + filename, UPSTREAM_MIRROR_URL + filename, ], - sha256 = "7023b1dc17626c5115b061e7ce02e06f006e35af92abf473334dffe7ff3c2d6d", + sha256 = "e5dfd4ad8fde0a40da50aab3aff6d9a27020b8f283e332bc4da6ef9914f4028c", strip_prefix = "monitoring-plugins-" + version_str, patches = [ "//omd/packages/monitoring-plugins:patches/0001-check-icmp-allows-pl-of-101.dif", @@ -20,6 +20,8 @@ def monitoring_plugins_workspace(): "//omd/packages/monitoring-plugins:patches/0009-check_dns-case-insensitive.dif", "//omd/packages/monitoring-plugins:patches/0010-get_omd_root_in_checks.dif", "//omd/packages/monitoring-plugins:patches/0011-check_http-sanitise-http-response-body.dif", + "//omd/packages/monitoring-plugins:patches/0012-fixup-ssl-linking.diff", + "//omd/packages/monitoring-plugins:patches/0013-link-root-plugins-statically.diff", ], patch_args = ["-p1"], patch_tool = "patch", diff --git a/omd/packages/monitoring-plugins/patches/0001-check-icmp-allows-pl-of-101.dif b/omd/packages/monitoring-plugins/patches/0001-check-icmp-allows-pl-of-101.dif index a2ab46971df..344d42d580c 100644 --- a/omd/packages/monitoring-plugins/patches/0001-check-icmp-allows-pl-of-101.dif +++ b/omd/packages/monitoring-plugins/patches/0001-check-icmp-allows-pl-of-101.dif @@ -1,44 +1,42 @@ -Only in monitoring-plugins-2.0: config.log -diff -ru monitoring-plugins-2.0.orig/plugins-root/check_icmp.c monitoring-plugins-2.0/plugins-root/check_icmp.c ---- monitoring-plugins-2.0.orig/plugins-root/check_icmp.c 2014-07-06 19:55:03.000000000 +0200 -+++ monitoring-plugins-2.0/plugins-root/check_icmp.c 2014-09-11 13:58:42.693502323 +0200 -@@ -940,7 +940,9 @@ - * conspicuosly as missing entries in perfparse and cacti */ +diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c +index f788d428..923c2df8 100644 +--- a/plugins-root/check_icmp.c ++++ b/plugins-root/check_icmp.c +@@ -1313,7 +1313,8 @@ finish(int sig) + * conspicuously as missing entries in perfparse and cacti */ pl = 100; rta = 0; - status = STATE_CRITICAL; + if (pl >= crit.pl) + status = STATE_CRITICAL; -+ /* up the down counter if not already counted */ if(!(host->flags & FLAG_LOST_CAUSE) && targets_alive) targets_down++; - } -@@ -964,7 +966,7 @@ - host = host->next; - } + } else { +@@ -1449,7 +1450,7 @@ finish(int sig) + + /* this is inevitable */ - if(!targets_alive) status = STATE_CRITICAL; + if(!targets_alive && crit.pl <= 100) status = STATE_CRITICAL; if(min_hosts_alive > -1) { if(hosts_ok >= min_hosts_alive) status = STATE_OK; else if((hosts_ok + hosts_warn) >= min_hosts_alive) status = STATE_WARNING; -@@ -980,7 +982,8 @@ +@@ -1466,7 +1467,8 @@ finish(int sig) } i++; if(!host->icmp_recv) { - status = STATE_CRITICAL; + if (pl >= crit.pl) + status = STATE_CRITICAL; + host->rtmin=0; + host->jitter_min=0; if(host->flags & FLAG_LOST_CAUSE) { - printf("%s: %s @ %s. rta nan, lost %d%%", - host->name, -@@ -1246,7 +1249,7 @@ +@@ -1927,7 +1929,7 @@ get_threshold(char *str, threshold *th) if(!th->rta) return -1; - + if(th->rta > MAXTTL * 1000000) th->rta = MAXTTL * 1000000; - if(th->pl > 100) th->pl = 100; + if(th->pl > 101) th->pl = 101; - + return 0; } -Only in monitoring-plugins-2.0/plugins-root: check_icmp.c.orig diff --git a/omd/packages/monitoring-plugins/patches/0003-cmk-password-store.dif b/omd/packages/monitoring-plugins/patches/0003-cmk-password-store.dif index ab8c7a210c8..32d818637e8 100644 --- a/omd/packages/monitoring-plugins/patches/0003-cmk-password-store.dif +++ b/omd/packages/monitoring-plugins/patches/0003-cmk-password-store.dif @@ -1,6 +1,8 @@ +diff --git a/plugins/Makefile.am b/plugins/Makefile.am +index 49086b7a..3994374d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am -@@ -83,7 +83,7 @@ +@@ -83,7 +83,7 @@ check_fping_LDADD = $(NETLIBS) check_game_LDADD = $(BASEOBJS) check_http_LDADD = $(SSLOBJS) check_hpjd_LDADD = $(NETLIBS) @@ -9,9 +11,11 @@ check_load_LDADD = $(BASEOBJS) check_mrtg_LDADD = $(BASEOBJS) check_mrtgtraf_LDADD = $(BASEOBJS) +diff --git a/plugins/Makefile.in b/plugins/Makefile.in +index 49086b7a..3994374d 100644 --- a/plugins/Makefile.in +++ b/plugins/Makefile.in -@@ -1613,7 +1613,7 @@ +@@ -2231,7 +2231,7 @@ check_game_LDADD = $(BASEOBJS) check_http_LDADD = $(SSLOBJS) check_hpjd_LDADD = $(NETLIBS) @@ -20,13 +24,14 @@ check_load_LDADD = $(BASEOBJS) check_mrtg_LDADD = $(BASEOBJS) check_mrtgtraf_LDADD = $(BASEOBJS) -diff -Nur monitoring-plugins-2.1.1.orig/plugins/check_http.c monitoring-plugins-2.1.1/plugins/check_http.c ---- monitoring-plugins-2.1.1.orig/plugins/check_http.c 2014-11-30 11:36:26.000000000 +0100 -+++ monitoring-plugins-2.1.1/plugins/check_http.c 2016-07-28 16:02:08.820778404 +0200 -@@ -145,9 +145,12 @@ - void print_help (void); +diff --git a/plugins/check_http.c b/plugins/check_http.c +index cdf768c9..2e1b9fbc 100644 +--- a/plugins/check_http.c ++++ b/plugins/check_http.c +@@ -153,9 +153,12 @@ void print_help (void); void print_usage (void); - + char *unchunk_content(const char *content); + +#include "cmk_password_store.h" + int @@ -34,40 +39,40 @@ diff -Nur monitoring-plugins-2.1.1.orig/plugins/check_http.c monitoring-plugins- { + CMK_REPLACE_PASSWORDS; int result = STATE_UNKNOWN; - + setlocale (LC_ALL, ""); diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c -index bc7bd44c..c6020a91 100644 +index 868ffc1e..b7d0f8a1 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c -@@ -79,10 +79,12 @@ int verbose = 0; - +@@ -79,10 +79,13 @@ bool verbose = false; + char *SERVICE = "LDAP"; - + +#include "cmk_password_store.h" + int main (int argc, char *argv[]) { -- + + CMK_REPLACE_PASSWORDS; LDAP *ld; LDAPMessage *result; - + diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c -index d37c57c8..cdc2ef24 100644 +index 986c3e18..89c80386 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c -@@ -112,10 +112,12 @@ enum { +@@ -120,10 +120,12 @@ enum { }; - int ignore_send_quit_failure = FALSE; - + bool ignore_send_quit_failure = false; + +#include "cmk_password_store.h" - + int main (int argc, char **argv) { + CMK_REPLACE_PASSWORDS; - short supports_tls=FALSE; + bool supports_tls = false; int n = 0; double elapsed_time; diff --git a/omd/packages/monitoring-plugins/patches/0010-get_omd_root_in_checks.dif b/omd/packages/monitoring-plugins/patches/0010-get_omd_root_in_checks.dif index 37b16a212f5..67c389e3964 100644 --- a/omd/packages/monitoring-plugins/patches/0010-get_omd_root_in_checks.dif +++ b/omd/packages/monitoring-plugins/patches/0010-get_omd_root_in_checks.dif @@ -1,30 +1,37 @@ ---- a/plugins/check_snmp.c 2021-04-10 14:13:41.000000000 +0200 -+++ b/plugins/check_snmp.c 2022-04-04 15:54:22.705840165 +0200 -@@ -299,9 +299,11 @@ +diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c +index 295aa9b5..5fd9325f 100644 +--- a/plugins/check_snmp.c ++++ b/plugins/check_snmp.c +@@ -311,12 +311,14 @@ main (int argc, char **argv) snmpcmd = strdup (PATH_TO_SNMPGET); } + char *absolute_snmpcmd_path= get_absolute_snmp_cmd_path(snmpcmd); + /* 10 arguments to pass before context and authpriv options + 1 for host and numoids. Add one for terminating NULL */ - command_line = calloc (10 + numcontext + numauthpriv + 1 + numoids + 1, sizeof (char *)); -- command_line[0] = snmpcmd; -+ command_line[0] = absolute_snmpcmd_path; - command_line[1] = strdup ("-Le"); - command_line[2] = strdup ("-t"); - xasprintf (&command_line[3], "%d", timeout_interval); -@@ -324,7 +326,7 @@ - /* This is just for display purposes, so it can remain a string */ - xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s %s:%s", -- snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[context]", "[authpriv]", -+ absolute_snmpcmd_path, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[context]", "[authpriv]", - server_address, port); + unsigned index = 0; + command_line = calloc (11 + numcontext + numauthpriv + 1 + numoids + 1, sizeof (char *)); - for (i = 0; i < numoids; i++) { ---- a/plugins/check_hpjd.c 2022-10-19 12:50:27.000000000 +0000 -+++ b/plugins/check_hpjd.c 2023-01-13 12:09:34.120943312 +0000 -@@ -37,6 +37,7 @@ +- command_line[index++] = snmpcmd; ++ command_line[index++] = absolute_snmpcmd_path; + command_line[index++] = strdup ("-Le"); + command_line[index++] = strdup ("-t"); + xasprintf (&command_line[index++], "%d", timeout_interval); +@@ -328,7 +330,7 @@ main (int argc, char **argv) + command_line[index++] = strdup (proto); + + xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s", +- snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto); ++ absolute_snmpcmd_path, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto); + + if (ignore_mib_parsing_errors) { + command_line[index++] = "-Pe"; +diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c +index c34bb082..b24ff677 100644 +--- a/plugins/check_hpjd.c ++++ b/plugins/check_hpjd.c +@@ -37,6 +37,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "popen.h" #include "utils.h" #include "netutils.h" @@ -32,7 +39,7 @@ #define DEFAULT_COMMUNITY "public" #define DEFAULT_PORT "161" -@@ -121,12 +122,9 @@ +@@ -121,12 +122,9 @@ main (int argc, char **argv) HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); /* get the command to run */ @@ -48,9 +55,13 @@ /* run the command */ child_process = spopen (command_line); ---- a/lib/utils_cmd.h 2021-04-10 14:13:41.000000000 +0200 -+++ b/lib/utils_cmd.h 2022-04-04 15:45:58.801463952 +0200 -@@ -23,6 +23,7 @@ +diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c +index 7957ec14..a776b6ba 100644 +diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h +index 061f5d4f..a93ed6e6 100644 +--- a/lib/utils_cmd.h ++++ b/lib/utils_cmd.h +@@ -23,6 +23,7 @@ typedef struct output output; int cmd_run (const char *, output *, output *, int); int cmd_run_array (char *const *, output *, output *, int); int cmd_file_read (char *, output *, int); @@ -58,10 +69,10 @@ /* only multi-threaded plugins need to bother with this */ void cmd_init (void); ---- a/lib/utils_cmd.c 2021-04-10 14:13:41.000000000 +0200 -+++ b/lib/utils_cmd.c 2022-04-04 15:45:58.801463952 +0200 -@@ -383,6 +383,22 @@ - return 0; +--- a/lib/utils_cmd.c ++++ b/lib/utils_cmd.c +@@ -387,6 +387,22 @@ cmd_file_read ( char *filename, output *out, int flags) + return 0; } +char * get_absolute_snmp_cmd_path(char* relativ_snmp_cmd) diff --git a/omd/packages/monitoring-plugins/patches/0012-fixup-ssl-linking.diff b/omd/packages/monitoring-plugins/patches/0012-fixup-ssl-linking.diff new file mode 100644 index 00000000000..50c207a65f3 --- /dev/null +++ b/omd/packages/monitoring-plugins/patches/0012-fixup-ssl-linking.diff @@ -0,0 +1,48 @@ +# This patch fixes linking of some plugins against our own openssl +# In a bright future, we should completely avoid letting autotools perform any magic and have hermetic builds in bazel... +--- a/plugins/Makefile.am 2024-09-16 15:33:48.465903341 +0200 ++++ b/plugins/Makefile.am 2024-09-16 15:34:23.762761627 +0200 +@@ -89,17 +89,17 @@ + check_mrtgtraf_LDADD = $(BASEOBJS) + check_mysql_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) +-check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) ++check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) $(SSLOBJS) + check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) +-check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) ++check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) $(SSLOBJS) + check_nagios_LDADD = $(BASEOBJS) + check_nt_LDADD = $(NETLIBS) + check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) + check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) + check_nwstat_LDADD = $(NETLIBS) + check_overcr_LDADD = $(NETLIBS) +-check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) ++check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) $(SSLOBJS) + check_ping_LDADD = $(NETLIBS) + check_procs_LDADD = $(BASEOBJS) + check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) +--- a/plugins/Makefile.in 2024-09-16 15:36:24.107267031 +0200 ++++ b/plugins/Makefile.in 2024-09-16 15:36:13.751310226 +0200 +@@ -2237,17 +2237,17 @@ + check_mrtgtraf_LDADD = $(BASEOBJS) + check_mysql_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) +-check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) ++check_mysql_LDADD = $(NETLIBS) $(MYSQLLIBS) $(SSLOBJS) + check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) + check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) +-check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) ++check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) $(SSLOBJS) + check_nagios_LDADD = $(BASEOBJS) + check_nt_LDADD = $(NETLIBS) + check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) + check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) + check_nwstat_LDADD = $(NETLIBS) + check_overcr_LDADD = $(NETLIBS) +-check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) ++check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) $(SSLOBJS) + check_ping_LDADD = $(NETLIBS) + check_procs_LDADD = $(BASEOBJS) + check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) diff --git a/omd/packages/monitoring-plugins/patches/0013-link-root-plugins-statically.diff b/omd/packages/monitoring-plugins/patches/0013-link-root-plugins-statically.diff new file mode 100644 index 00000000000..54cee8db30e --- /dev/null +++ b/omd/packages/monitoring-plugins/patches/0013-link-root-plugins-statically.diff @@ -0,0 +1,26 @@ +--- a/plugins-root/Makefile.in 2024-09-19 15:00:43.792941585 +0200 ++++ b/plugins-root/Makefile.in 2024-10-02 08:50:34.566617482 +0200 +@@ -1969,8 +1969,8 @@ + + ############################################################################## + # the actual targets +-check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) $(LIB_CRYPTO) +-check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) $(LIB_CRYPTO) ++check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) "-l:libcrypto.a" ++check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) "-l:libcrypto.a" + + # -m64 needed at compiler and linker phase + pst3_CFLAGS = @PST3CFLAGS@ +--- a/plugins-root/Makefile.am 2024-10-02 08:55:14.509697886 +0200 ++++ b/plugins-root/Makefile.am 2024-10-02 08:50:07.336291483 +0200 +@@ -80,8 +80,8 @@ + + ############################################################################## + # the actual targets +-check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) $(LIB_CRYPTO) +-check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) $(LIB_CRYPTO) ++check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) "-l:libcrypto.a" ++check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) "-l:libcrypto.a" + + # -m64 needed at compiler and linker phase + pst3_CFLAGS = @PST3CFLAGS@ diff --git a/omd/packages/msitools/msitools.make b/omd/packages/msitools/msitools.make index 5689905adc1..409a1838e85 100755 --- a/omd/packages/msitools/msitools.make +++ b/omd/packages/msitools/msitools.make @@ -11,7 +11,7 @@ $(MSITOOLS_BUILD): # are built somewhere else without --define git-ssl-no-verify=true being specified, likely # resulting in different builds $(BAZEL_CMD) build \ - $(if $(filter $(DISTRO_CODE),sles15 sles15sp1 sles15sp2 sles15sp3 sles15sp4 sles15sp5 sles15sp6),--define omd-libgsf=true) \ + $(if $(filter sles15%,$(DISTRO_CODE)),--define omd-libgsf=true) \ @$(MSITOOLS)//:$(MSITOOLS) .PHONY: $(MSITOOLS_INSTALL) diff --git a/omd/packages/nagvis/nagvis-1.9.43.tar.gz b/omd/packages/nagvis/nagvis-1.9.43.tar.gz deleted file mode 100644 index 137aafba3d5..00000000000 Binary files a/omd/packages/nagvis/nagvis-1.9.43.tar.gz and /dev/null differ diff --git a/omd/packages/nagvis/nagvis-1.9.44.tar.gz b/omd/packages/nagvis/nagvis-1.9.44.tar.gz new file mode 100644 index 00000000000..7367b290210 Binary files /dev/null and b/omd/packages/nagvis/nagvis-1.9.44.tar.gz differ diff --git a/omd/packages/nagvis/nagvis.make b/omd/packages/nagvis/nagvis.make index f158bcf882f..e09bc28e30d 100644 --- a/omd/packages/nagvis/nagvis.make +++ b/omd/packages/nagvis/nagvis.make @@ -1,5 +1,5 @@ NAGVIS := nagvis -NAGVIS_VERS := 1.9.43 +NAGVIS_VERS := 1.9.44 NAGVIS_DIR := $(NAGVIS)-$(NAGVIS_VERS) NAGVIS_PATCHING := $(BUILD_HELPER_DIR)/$(NAGVIS_DIR)-patching diff --git a/omd/packages/omd/omd.make b/omd/packages/omd/omd.make index 12e8b3c7692..ad600216976 100644 --- a/omd/packages/omd/omd.make +++ b/omd/packages/omd/omd.make @@ -19,11 +19,9 @@ $(OMD_INSTALL): omdlib-install install -m 755 $(PACKAGE_DIR)/$(OMD)/omd.bin $(DESTDIR)$(OMD_ROOT)/bin/omd sed -i 's|###OMD_VERSION###|$(OMD_VERSION)|g' $(DESTDIR)$(OMD_ROOT)/bin/omd # SUP-10161: our openssl is incompatible with some system executables on various sles15sp* -ifneq ($(filter $(DISTRO_CODE), sles15sp3 sles15sp4 sles15sp5 sles15sp6),) +ifneq ($(filter sles15%,$(DISTRO_CODE)),) install -m 755 $(PACKAGE_DIR)/$(OMD)/use_system_openssl $(DESTDIR)$(OMD_ROOT)/bin/ssh install -m 755 $(PACKAGE_DIR)/$(OMD)/use_system_openssl $(DESTDIR)$(OMD_ROOT)/bin/scp -endif -ifneq ($(filter $(DISTRO_CODE),el8 el9 sles15sp4 sles15sp5 sles15sp6),) install -m 755 $(PACKAGE_DIR)/$(OMD)/use_system_openssl $(DESTDIR)$(OMD_ROOT)/bin/pdftoppm install -m 755 $(PACKAGE_DIR)/$(OMD)/use_system_openssl $(DESTDIR)$(OMD_ROOT)/bin/curl endif diff --git a/omd/packages/omd/omdlib/main.py b/omd/packages/omd/omdlib/main.py index ef6d0f081a6..b69f1cbebca 100644 --- a/omd/packages/omd/omdlib/main.py +++ b/omd/packages/omd/omdlib/main.py @@ -2258,10 +2258,10 @@ def finalize_site_as_user( # Run all hooks in order to setup things according to the # configuration settings config_set_all(site, ignored_hooks) - _update_cmk_core_config(site) initialize_site_ca(site) initialize_agent_ca(site) save_site_conf(site) + _update_cmk_core_config(site) if command_type in [CommandType.create, CommandType.copy, CommandType.restore_as_new_site]: save_instance_id(file_path=get_instance_id_file_path(Path(site.dir)), instance_id=uuid4()) diff --git a/omd/packages/packages.make b/omd/packages/packages.make index 8c71bbd066a..c2ae7571735 100644 --- a/omd/packages/packages.make +++ b/omd/packages/packages.make @@ -37,7 +37,7 @@ $(INTERMEDIATE_INSTALL_BAZEL): # are built somewhere else without --define git-ssl-no-verify=true being specified, likely # resulting in different builds $(BAZEL_CMD) build \ - $(if $(filter $(DISTRO_CODE),sles15 sles15sp1 sles15sp2 sles15sp3 sles15sp4 sles15sp5 sles15sp6),--define git-ssl-no-verify=true) \ + $(if $(filter sles15%,$(DISTRO_CODE)),--define git-ssl-no-verify=true) \ //omd:intermediate_install tar -C $(BUILD_BASE_DIR) -xf $(BAZEL_BIN)/omd/intermediate_install.tar.gz @@ -211,7 +211,6 @@ include \ packages/xmlsec1/xmlsec1.make \ packages/robotmk/robotmk.make \ packages/redfish_mkp/redfish_mkp.make \ - packages/rabbitmq/rabbitmq.make \ ifeq ($(EDITION),enterprise) include \ @@ -235,8 +234,9 @@ include \ packages/saas/saas.make else # Ship nagvis for all but saas edition: CMK-14926 -# also exclude jaeger +# also exclude jaeger and rabbitmq include \ packages/nagvis/nagvis.make \ + packages/rabbitmq/rabbitmq.make \ packages/jaeger/jaeger.make endif diff --git a/omd/packages/rabbitmq/skel/etc/rabbitmq/advanced_conf.d/00-advanced.conf b/omd/packages/rabbitmq/skel/etc/rabbitmq/advanced_conf.d/00-advanced.conf index 9bc309a8355..62cc83d81a4 100644 --- a/omd/packages/rabbitmq/skel/etc/rabbitmq/advanced_conf.d/00-advanced.conf +++ b/omd/packages/rabbitmq/skel/etc/rabbitmq/advanced_conf.d/00-advanced.conf @@ -15,7 +15,7 @@ [{amqp_client, [ {ssl_options, [ - {cacertfile, "###ROOT###/etc/rabbitmq/ssl/ca_cert.pem"}, + {cacertfile, "###ROOT###/etc/rabbitmq/ssl/trusted_cas.pem"}, {certfile, "###ROOT###/etc/rabbitmq/ssl/cert.pem"}, {keyfile, "###ROOT###/etc/rabbitmq/ssl/key.pem"}, {verify, verify_peer} diff --git a/omd/packages/rabbitmq/skel/etc/rabbitmq/conf.d/00-default.conf b/omd/packages/rabbitmq/skel/etc/rabbitmq/conf.d/00-default.conf index 5e0aad0ae23..66effe3ec1f 100644 --- a/omd/packages/rabbitmq/skel/etc/rabbitmq/conf.d/00-default.conf +++ b/omd/packages/rabbitmq/skel/etc/rabbitmq/conf.d/00-default.conf @@ -29,6 +29,6 @@ auth_mechanisms.1 = EXTERNAL ssl_cert_login_from = common_name # Server key files. -ssl_options.cacertfile = $(OMD_ROOT)/etc/rabbitmq/ssl/ca_cert.pem +ssl_options.cacertfile = $(OMD_ROOT)/etc/rabbitmq/ssl/trusted_cas.pem ssl_options.certfile = $(OMD_ROOT)/etc/rabbitmq/ssl/cert.pem ssl_options.keyfile = $(OMD_ROOT)/etc/rabbitmq/ssl/key.pem diff --git a/omd/packages/robotmk/robotmk.make b/omd/packages/robotmk/robotmk.make index 46ac37a56a3..4d5b5a3a7af 100644 --- a/omd/packages/robotmk/robotmk.make +++ b/omd/packages/robotmk/robotmk.make @@ -13,11 +13,12 @@ $(ROBOTMK_BUILD): .PHONY: $(ROBOTMK_INTERMEDIATE_INSTALL) $(ROBOTMK_INTERMEDIATE_INSTALL): $(ROBOTMK_BUILD) - $(MKDIR) $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/linux + $(MKDIR) $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/robotmk/linux + $(MKDIR) $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/robotmk/windows $(MKDIR) $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/plugins $(MKDIR) $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/windows/plugins - install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_scheduler $(ROBOTMK_BAZEL_OUT)/rcc $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/linux - install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_scheduler.exe $(ROBOTMK_BAZEL_OUT)/rcc.exe $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/windows + install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_scheduler $(ROBOTMK_BAZEL_OUT)/rcc $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/robotmk/linux + install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_scheduler.exe $(ROBOTMK_BAZEL_OUT)/rcc.exe $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/robotmk/windows install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_agent_plugin $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/plugins install -m 755 $(ROBOTMK_BAZEL_OUT)/robotmk_agent_plugin.exe $(ROBOTMK_INSTALL_DIR)/share/check_mk/agents/windows/plugins diff --git a/omd/packages/rrdtool/BUILD.rrdtool-native.bazel b/omd/packages/rrdtool/BUILD.rrdtool-native.bazel index 30fce9dab18..73e55604e07 100644 --- a/omd/packages/rrdtool/BUILD.rrdtool-native.bazel +++ b/omd/packages/rrdtool/BUILD.rrdtool-native.bazel @@ -1,3 +1,4 @@ +load("@aspect_rules_py//py:defs.bzl", "py_library") load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") load("@rules_python//python:packaging.bzl", "py_wheel") @@ -202,6 +203,12 @@ cc_shared_library( deps = [":rrdtoolmodule"], ) +py_library( + name = "rrdtool_python_lib", + data = [":rrdtoolmodule_shared"], + visibility = ["//visibility:public"], +) + py_wheel( name = "rrdtool_python_wheel", distribution = "rrdtool", diff --git a/omd/packages/rules/package_wheel.bzl b/omd/packages/rules/package_wheel.bzl index 29fe20daa53..b3a147b1c01 100644 --- a/omd/packages/rules/package_wheel.bzl +++ b/omd/packages/rules/package_wheel.bzl @@ -3,29 +3,35 @@ load("@rules_pkg//pkg:mappings.bzl", "pkg_files") load("@rules_pkg//pkg:tar.bzl", "pkg_tar") load("@rules_python//python:pip.bzl", "whl_filegroup") -def package_wheel(wheel_target): - """Packages a python wheel into our omd site-packages.""" +def package_wheel( + name, + whl, + visibility = None): + """Packages a python wheel into our omd site-packages. + + Args: + name: Name of this target. + whl: Wheel to be packaged. + visibility: The visibility attribute on the target. + + """ + whl_filegroup_name = name + "_fg" + pkg_files_name = name + "_pkg_files" whl_filegroup( - name = "whl_filegroup", - whl = wheel_target, + name = whl_filegroup_name, + whl = whl, ) - pkg_files( - name = "pkg_files", - srcs = [ - ":whl_filegroup", - ], + name = pkg_files_name, + srcs = [whl_filegroup_name], # TODO: As soon as we have all omd/packages in bazel, we won't need the intermediate install target anymore. # Then we can also completely remove the "python3-modules" prefix - currently it will be deployed to $(DESTDIR) via # $(PYTHON3_MODULES_INSTALL) in python3-modules.make prefix = "python3-modules/lib/python%s/site-packages" % PYTHON_MAJOR_DOT_MINOR, - strip_prefix = "whl_filegroup", + strip_prefix = whl_filegroup_name, ) - pkg_tar( - name = "pkg_tar", - srcs = [ - ":pkg_files", - ], - visibility = ["//visibility:public"], + name = name, + srcs = [pkg_files_name], + visibility = visibility, ) diff --git a/omd/packages/rules/repo_license.bzl b/omd/packages/rules/repo_license.bzl new file mode 100644 index 00000000000..041d218b4b1 --- /dev/null +++ b/omd/packages/rules/repo_license.bzl @@ -0,0 +1,18 @@ +"""Detects whether the repo is pure GPL or enterprise and GPL.""" + +def _repo_license_impl(repository_ctx): + if repository_ctx.path(Label("//:non-free")).exists: + license = "gpl+enterprise" + else: + license = "gpl" + license_bzl = "license.bzl" + repository_ctx.file( + license_bzl, + content = "REPO_LICENSE = %r" % license, + executable = False, + ) + repository_ctx.file("BUILD.bazel", 'exports_files(["' + license_bzl + '"])') + +detect_repo_license = repository_rule( + implementation = _repo_license_impl, +) diff --git a/packages/cmk-agent-based/BUILD b/packages/cmk-agent-based/BUILD index c3fefec1bcf..95de5d97fab 100644 --- a/packages/cmk-agent-based/BUILD +++ b/packages/cmk-agent-based/BUILD @@ -4,9 +4,16 @@ load("@cmk_agent_based//:requirements.bzl", "requirement") load("@omd_packages//omd/packages/rules:package_wheel.bzl", "package_wheel") load("@rules_python//python:packaging.bzl", "py_wheel") load("@rules_python//python:pip.bzl", "compile_pip_requirements") +load(":linters.bzl", "ruff_test") + +exports_files(["pyproject.toml"]) compile_pip_requirements( name = "requirements", + extra_args = [ + "--no-strip-extras", # reconsider this? (https://github.com/jazzband/pip-tools/issues/1613) + "--quiet", + ], requirements_in = "pyproject.toml", requirements_txt = "requirements_lock.txt", # shall exist, emtpy is okay ) @@ -35,24 +42,32 @@ py_library( "cmk/agent_based/v2/clusterize.py", "cmk/agent_based/v2/render.py", ], - visibility = ["//visibility:public"], + imports = ["."], + visibility = ["//cmk:__pkg__"], deps = [ requirement("pydantic"), ], ) +ruff_test( + name = "ruff_lint", + size = "small", + srcs = [ + ":cmk-agent-based", + ":unit", + ], +) + py_pytest_main( name = "__test__", ) py_test( name = "unit", + size = "small", srcs = glob(["tests/**/*.py"]) + [":__test__.py"], - # TODO: Duplicated from pyproject.toml - args = [ - "--import-mode=importlib", - "--doctest-modules", - ], + args = ["--config-file=$(location pyproject.toml)"], + data = ["pyproject.toml"], imports = ["."], main = ":__test__.py", deps = [ @@ -73,9 +88,11 @@ py_wheel( strip_path_prefixes = ["packages/cmk-agent-based"], # TODO: Duplicated from pyproject.toml version = "1.0.0", - deps = [ - ":cmk-agent-based", - ], + deps = [":cmk-agent-based"], ) -package_wheel(wheel_target = "wheel") +package_wheel( + name = "pkg_tar", + visibility = ["//visibility:public"], + whl = "wheel", +) diff --git a/packages/cmk-agent-based/Pipfile b/packages/cmk-agent-based/Pipfile index 353b44e3e4f..6723aef415c 100644 --- a/packages/cmk-agent-based/Pipfile +++ b/packages/cmk-agent-based/Pipfile @@ -7,7 +7,6 @@ name = "pypi" bandit = "*" ruff = "*" mypy = "*" -pylint = "*" pytest = "*" # LSP server stuff for IDEs pylsp-mypy = "*" diff --git a/packages/cmk-agent-based/Pipfile.lock b/packages/cmk-agent-based/Pipfile.lock index 7c586843f0f..3f4226d9214 100644 --- a/packages/cmk-agent-based/Pipfile.lock +++ b/packages/cmk-agent-based/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c607b1401a0876a1a9f7acb32830b236c3833be4c40f51f384491e18558a047a" + "sha256": "1bfa7b49c68873b9a078b68eda290f4b59309b4069a24ee8654789177548fa89" }, "pipfile-spec": 6, "requires": { @@ -173,30 +173,14 @@ } }, "develop": { - "astroid": { - "hashes": [ - "sha256:2d79acfd3c594b6a2d4141fea98a1d62ab4a52e54332b1f1ddcf07b652cc5c0f", - "sha256:63f8c5370d9bad8294163c87b2d440a7fdf546be6c72bbeac0549c93244dbd72" - ], - "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.3" - }, "bandit": { "hashes": [ - "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec", - "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61" + "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b", + "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.7.9" - }, - "dill": { - "hashes": [ - "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", - "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" - ], - "markers": "python_version >= '3.11'", - "version": "==0.3.8" + "version": "==1.7.10" }, "docstring-to-markdown": { "hashes": [ @@ -214,14 +198,6 @@ "markers": "python_version >= '3.7'", "version": "==2.0.0" }, - "isort": { - "hashes": [ - "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", - "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" - ], - "markers": "python_full_version >= '3.8.0'", - "version": "==5.13.2" - }, "jedi": { "hashes": [ "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", @@ -238,14 +214,6 @@ "markers": "python_version >= '3.8'", "version": "==3.0.0" }, - "mccabe": { - "hashes": [ - "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", - "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" - ], - "markers": "python_version >= '3.6'", - "version": "==0.7.0" - }, "mdurl": { "hashes": [ "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", @@ -296,14 +264,6 @@ "markers": "python_version >= '2.6'", "version": "==6.1.0" }, - "platformdirs": { - "hashes": [ - "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", - "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb" - ], - "markers": "python_version >= '3.8'", - "version": "==4.3.6" - }, "pluggy": { "hashes": [ "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", @@ -320,15 +280,6 @@ "markers": "python_version >= '3.8'", "version": "==2.18.0" }, - "pylint": { - "hashes": [ - "sha256:02dce1845f68974b9b03045894eb3bf05a8b3c7da9fd10af4de3c91e69eb92f1", - "sha256:c685fe3c061ee5fb0ce7c29436174ab84a2f525fce2a268b1986e921e083fe22" - ], - "index": "pypi", - "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.0" - }, "pylsp-mypy": { "hashes": [ "sha256:9b73ece2977b22b5fc75dfec1cc491bf2031955e3da4062d924a5cc22a278151", @@ -424,20 +375,20 @@ }, "rich": { "hashes": [ - "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", - "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "ruff": { "hashes": [ - "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", - "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b" + "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", + "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.6.7" + "version": "==0.6.9" }, "stevedore": { "hashes": [ @@ -447,14 +398,6 @@ "markers": "python_version >= '3.8'", "version": "==5.3.0" }, - "tomlkit": { - "hashes": [ - "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", - "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79" - ], - "markers": "python_version >= '3.8'", - "version": "==0.13.2" - }, "typing-extensions": { "hashes": [ "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", diff --git a/packages/cmk-agent-based/ci.json b/packages/cmk-agent-based/ci.json index 0183a142766..09acb2a48b5 100644 --- a/packages/cmk-agent-based/ci.json +++ b/packages/cmk-agent-based/ci.json @@ -1,4 +1,4 @@ { - "command_line": "./run --clean --all", + "command_line": "BAZEL_CMD=../../scripts/run-bazel.sh ./run --clean --all", "maintainers": ["team-nile@checkmk.com"] } diff --git a/packages/cmk-agent-based/cmk/agent_based/v1/_check_levels.py b/packages/cmk-agent-based/cmk/agent_based/v1/_check_levels.py index 5cc0db0e78f..36818d8f00d 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v1/_check_levels.py +++ b/packages/cmk-agent-based/cmk/agent_based/v1/_check_levels.py @@ -14,7 +14,7 @@ from ._checking_classes import Metric, Result, State -# pylint: disable=too-many-arguments +# ruff: noqa: PLR0913 def _do_check_levels( diff --git a/packages/cmk-agent-based/cmk/agent_based/v1/_regex.py b/packages/cmk-agent-based/cmk/agent_based/v1/_regex.py index 8c23d130389..e35516c55fb 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v1/_regex.py +++ b/packages/cmk-agent-based/cmk/agent_based/v1/_regex.py @@ -9,8 +9,8 @@ if TYPE_CHECKING: F = TypeVar("F") - def lru_cache(maxsize: int) -> Callable[[F], F]: # pylint: disable=unused-argument - pass + def lru_cache(maxsize: int) -> Callable[[F], F]: + del maxsize else: from functools import lru_cache diff --git a/packages/cmk-agent-based/cmk/agent_based/v1/_value_store_utils.py b/packages/cmk-agent-based/cmk/agent_based/v1/_value_store_utils.py index bd6c0baab49..5cfb99c3a10 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v1/_value_store_utils.py +++ b/packages/cmk-agent-based/cmk/agent_based/v1/_value_store_utils.py @@ -4,9 +4,6 @@ # conditions defined in the file COPYING, which is part of this source code package. """Helper functions to work with persisted values""" - -# pylint: disable=duplicate-code - from collections.abc import MutableMapping from typing import Any, cast diff --git a/packages/cmk-agent-based/cmk/agent_based/v1/render.py b/packages/cmk-agent-based/cmk/agent_based/v1/render.py index 7d9c934cbc6..a563e38d300 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v1/render.py +++ b/packages/cmk-agent-based/cmk/agent_based/v1/render.py @@ -171,7 +171,7 @@ def disksize(bytes_: float) -> str: return f"{value_str if unit != 'B' else value_str.split('.')[0]} {unit}" -def bytes(bytes_: float) -> str: # pylint: disable=redefined-builtin +def bytes(bytes_: float) -> str: # noqa: A001 """Render a number of bytes using an appropriate IEC prefix Example: diff --git a/packages/cmk-agent-based/cmk/agent_based/v1/value_store.py b/packages/cmk-agent-based/cmk/agent_based/v1/value_store.py index 7cbe44f62ae..547d62b5aeb 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v1/value_store.py +++ b/packages/cmk-agent-based/cmk/agent_based/v1/value_store.py @@ -85,7 +85,7 @@ def set_value_store_manager( This class is not to be used by plug-ins, and not part of the plug-in API. """ # ^- and yet it sits in this package. That's what you get for using a global state. - global _active_host_value_store # pylint: disable=global-statement + global _active_host_value_store # noqa: PLW0603 pushed_back_store = _active_host_value_store diff --git a/packages/cmk-agent-based/cmk/agent_based/v2/__init__.py b/packages/cmk-agent-based/cmk/agent_based/v2/__init__.py index 172dc4c3798..861a47026bc 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v2/__init__.py +++ b/packages/cmk-agent-based/cmk/agent_based/v2/__init__.py @@ -67,7 +67,6 @@ On popular demand we add a function to render a number of seconds that might be negative. """ -# pylint: disable=duplicate-code from cmk.agent_based.v1 import ( all_of, diff --git a/packages/cmk-agent-based/cmk/agent_based/v2/_check_levels.py b/packages/cmk-agent-based/cmk/agent_based/v2/_check_levels.py index 151fea29b29..e21d9a96ea0 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v2/_check_levels.py +++ b/packages/cmk-agent-based/cmk/agent_based/v2/_check_levels.py @@ -21,7 +21,7 @@ ] # The name is part of the offial API, we have to live with the suppression. -LevelsT = Union[NoLevelsT, FixedLevelsT[_NumberT], PredictiveLevelsT[_NumberT]] # pylint: disable=invalid-name +LevelsT = Union[NoLevelsT, FixedLevelsT[_NumberT], PredictiveLevelsT[_NumberT]] class Direction(StrEnum): @@ -81,7 +81,7 @@ def _check_fixed_levels( return CheckLevelsResult(Type.FIXED, State.OK, levels) -def _check_predictive_levels( # pylint: disable=too-many-arguments,too-many-positional-arguments +def _check_predictive_levels( # noqa: PLR0913 value: float, metric_name: str, predicted_value: float | None, @@ -168,7 +168,7 @@ def _summarize_predictions( return predictions, f"(upper levels {upper_text}, lower levels {lower_text})" -def check_levels( # pylint: disable=too-many-arguments,too-many-locals +def check_levels( # noqa: PLR0913 value: float, *, levels_upper: LevelsT[_NumberT] | None = None, diff --git a/packages/cmk-agent-based/cmk/agent_based/v2/_plugins.py b/packages/cmk-agent-based/cmk/agent_based/v2/_plugins.py index 399921399e7..eecb6d15791 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v2/_plugins.py +++ b/packages/cmk-agent-based/cmk/agent_based/v2/_plugins.py @@ -4,8 +4,6 @@ # conditions defined in the file COPYING, which is part of this source code package. """All objects defined here are intended to be exposed in the API""" -# pylint: disable=too-many-instance-attributes - import functools from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass @@ -106,7 +104,7 @@ class AgentSection(Generic[_Section]): supersedes: list[str] | None = None @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -120,7 +118,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -134,7 +132,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -147,7 +145,7 @@ def __init__( # pylint: disable=too-many-arguments supersedes: list[str] | None = None, ): ... - def __init__( # pylint: disable=too-many-arguments + def __init__( # noqa: PLR0913 self, *, name: str, @@ -266,7 +264,7 @@ def unpacking_parse_function(string_table: Sequence[_TableTypeT]) -> _Section | return unpacking_parse_function @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -282,7 +280,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -298,7 +296,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -313,7 +311,7 @@ def __init__( # pylint: disable=too-many-arguments supersedes: list[str] | None = None, ): ... - def __init__( # pylint: disable=too-many-arguments + def __init__( # noqa: PLR0913 self, *, name: str, @@ -423,7 +421,7 @@ class SNMPSection(Generic[_TableTypeT, _Section]): supersedes: list[str] | None = None @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -439,7 +437,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -455,7 +453,7 @@ def __init__( # pylint: disable=too-many-arguments ): ... @overload - def __init__( # pylint: disable=too-many-arguments + def __init__( self, *, name: str, @@ -470,7 +468,7 @@ def __init__( # pylint: disable=too-many-arguments supersedes: list[str] | None = None, ): ... - def __init__( # pylint: disable=too-many-arguments + def __init__( # noqa: PLR0913 self, *, name: str, diff --git a/packages/cmk-agent-based/cmk/agent_based/v2/render.py b/packages/cmk-agent-based/cmk/agent_based/v2/render.py index 26db7366046..a44195b6a4a 100644 --- a/packages/cmk-agent-based/cmk/agent_based/v2/render.py +++ b/packages/cmk-agent-based/cmk/agent_based/v2/render.py @@ -9,9 +9,7 @@ a string. """ -# pylint: disable=duplicate-code - -from cmk.agent_based.v1.render import ( # pylint: disable=redefined-builtin +from cmk.agent_based.v1.render import ( bytes, date, datetime, diff --git a/packages/cmk-agent-based/linters.bzl b/packages/cmk-agent-based/linters.bzl new file mode 100644 index 00000000000..b57abf4fcdd --- /dev/null +++ b/packages/cmk-agent-based/linters.bzl @@ -0,0 +1,11 @@ +load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test") +load("@aspect_rules_lint//lint:ruff.bzl", "lint_ruff_aspect") + +ruff = lint_ruff_aspect( + binary = "@multitool//tools/ruff", + configs = [ + "@@//packages/cmk-agent-based:pyproject.toml", + ], +) + +ruff_test = lint_test(aspect = ruff) diff --git a/packages/cmk-agent-based/pyproject.toml b/packages/cmk-agent-based/pyproject.toml index 7035e9ebeb5..32bc61c1a93 100644 --- a/packages/cmk-agent-based/pyproject.toml +++ b/packages/cmk-agent-based/pyproject.toml @@ -16,6 +16,16 @@ build-backend = "setuptools.build_meta" target-version = "py312" line-length = 100 +[tool.ruff.lint] +# (not yet) implemented pylint rules under ruff (by the time writting...): +# | too-many-instance-attributes rule (R0902) +# | too-many-function-args (E1121) +# | duplicate-code (R0801) +select = ["A", "ARG", "E", "F", "W", "C90", "PL", "RUF100", "SLF"] +ignore = [ + "PLR2004", # Magic value used in comparison, consider replacing `FOO` with a constant variable +] + [tool.ruff.lint.isort] order-by-type = false @@ -51,19 +61,6 @@ warn_unreachable = true disable_bytearray_promotion = true disable_memoryview_promotion = true -[tool.pylint.format] -max-line-length = 100 -persistent = "no" -score = "no" - -[tool.pylint.messages_control] -disable = [ - # We should at least document modules and classes. :-/ - "missing-module-docstring", - "missing-class-docstring", - "missing-function-docstring", -] - [tool.pytest.ini_options] pythonpath = ["."] testpaths = ["cmk", "tests"] diff --git a/packages/cmk-agent-based/run b/packages/cmk-agent-based/run index ab3a03dfd92..4dd52b56a8d 100755 --- a/packages/cmk-agent-based/run +++ b/packages/cmk-agent-based/run @@ -6,6 +6,7 @@ set -e JOBS=6 +readonly BAZEL_CMD=${BAZEL_CMD:-bazel} failure() { test ${#@} -eq 0 || echo "$(basename "$0"):" "$@" >&2 @@ -20,7 +21,7 @@ usage() { echo " -u, --unit-tests run unit tests" echo " -F, --check-format check for correct formatting" echo " -m, --mypy run mypy" - echo " -p, --pylint run pylint" + echo " -r, --ruff run ruff linter" echo " -B, --bandit run bandit" echo " -a, --all shortcut for -u -F -m -p -B -C" echo " -f, --format format sources" @@ -35,12 +36,12 @@ parse_options() { RUN_UNIT_TESTS=no RUN_CHECK_FORMAT=no RUN_MYPY=no - RUN_PYLINT=no + RUN_RUFF=no RUN_BANDIT=no RUN_FORMAT=no RUN_DOCUMENTATION=no - if ! OPTIONS=$(getopt --options 'cuFmpBafDj:h' --long 'clean,unit-tests,check-format,mypy,pylint,bandit,all,format,documentation,jobs:,help' --name "$(basename "$0")" -- "$@"); then + if ! OPTIONS=$(getopt --options 'cuFmrBafDj:h' --long 'clean,unit-tests,check-format,mypy,ruff,bandit,all,format,documentation,jobs:,help' --name "$(basename "$0")" -- "$@"); then usage >&2 failure fi @@ -69,8 +70,8 @@ parse_options() { shift continue ;; - '-p' | '--pylint') - RUN_PYLINT=yes + '-r' | '--ruff') + RUN_RUFF=yes shift continue ;; @@ -83,7 +84,7 @@ parse_options() { RUN_UNIT_TESTS=yes RUN_CHECK_FORMAT=yes RUN_MYPY=yes - RUN_PYLINT=yes + RUN_RUFF=yes RUN_BANDIT=yes shift continue @@ -116,7 +117,7 @@ parse_options() { esac done - readonly RUN_CLEAN RUN_UNIT_TESTS RUN_CHECK_FORMAT RUN_MYPY RUN_PYLINT RUN_BANDIT RUN_FORMAT RUN_DOCUMENTATION JOBS + readonly RUN_CLEAN RUN_UNIT_TESTS RUN_CHECK_FORMAT RUN_MYPY RUN_RUFF RUN_BANDIT RUN_FORMAT RUN_DOCUMENTATION JOBS } run_pipenv() { @@ -148,14 +149,14 @@ run_clean() { } run_unit_tests() { - ../../scripts/run-bazel.sh test //packages/cmk-agent-based:all + "${BAZEL_CMD}" test //packages/cmk-agent-based:all } run_check_format() { command -v taplo >/dev/null && RUST_LOG=warn taplo format --check --diff pyproject.toml setup_venv ruff check --select I --diff cmk tests - ../../scripts/run-bazel.sh run :format.check "$(realpath cmk)" "$(realpath tests)" + "${BAZEL_CMD}" run :format.check "$(realpath cmk)" "$(realpath tests)" } run_mypy() { @@ -163,9 +164,8 @@ run_mypy() { mypy } -run_pylint() { - setup_venv - PYTHONPATH=. pylint --jobs="${JOBS}" cmk tests +run_ruff() { + "${BAZEL_CMD}" lint :all } run_bandit() { @@ -180,7 +180,7 @@ run_format() { command -v taplo >/dev/null && RUST_LOG=warn taplo format pyproject.toml setup_venv ruff check --select I --fix cmk tests - ../../scripts/run-bazel.sh run :format "$(realpath cmk)" "$(realpath tests)" + "${BAZEL_CMD}" run :format "$(realpath cmk)" "$(realpath tests)" } run_documentation() { @@ -196,7 +196,7 @@ main() { test ${RUN_UNIT_TESTS} = yes && run_unit_tests test ${RUN_CHECK_FORMAT} = yes && run_check_format test ${RUN_MYPY} = yes && run_mypy - test ${RUN_PYLINT} = yes && run_pylint + test ${RUN_RUFF} = yes && run_ruff test ${RUN_BANDIT} = yes && run_bandit test ${RUN_DOCUMENTATION} = yes && run_documentation test ${RUN_FORMAT} = yes && run_format diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/test_v1_namespace.py b/packages/cmk-agent-based/tests/cmk/agent_based/test_v1_namespace.py index b71b3af0712..6777777d1a6 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/test_v1_namespace.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/test_v1_namespace.py @@ -13,8 +13,6 @@ +---------------------------------------------------------+ """ -# pylint: disable=duplicate-code - from types import ModuleType from cmk.agent_based import v1 diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/test_v2_namespace.py b/packages/cmk-agent-based/tests/cmk/agent_based/test_v2_namespace.py index 42041188910..0ae37a78c9c 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/test_v2_namespace.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/test_v2_namespace.py @@ -13,8 +13,6 @@ +---------------------------------------------------------+ """ -# pylint: disable=duplicate-code - from types import ModuleType from cmk.agent_based import v2 diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_checking_classes.py b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_checking_classes.py index 7f5fab9c9ba..03e6e0f68dd 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_checking_classes.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_checking_classes.py @@ -39,7 +39,7 @@ def test_service_invalid(item: object, parameters: object, labels: object) -> No def test_service_kwargs_only() -> None: with pytest.raises(TypeError): - _ = Service(None) # type: ignore[misc] # pylint: disable=too-many-function-args + _ = Service(None) # type: ignore[misc] def test_service_features() -> None: @@ -121,7 +121,7 @@ def test_best_state( def test_metric_kwarg() -> None: with pytest.raises(TypeError): - _ = Metric("universe", 42, (23, 23)) # type: ignore[misc] # pylint: disable=too-many-function-args + _ = Metric("universe", 42, (23, 23)) # type: ignore[misc] @pytest.mark.parametrize( @@ -148,7 +148,7 @@ def test_metric() -> None: assert metric1.levels == (2.4, 3.0) assert metric1.boundaries == (0.0, None) - assert metric1 == metric1 # pylint: disable=comparison-with-itself # noqa: PLR0124 + assert metric1 == metric1 # noqa: PLR0124 assert metric1 != metric2 diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_inventory_classes.py b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_inventory_classes.py index c9100785d1f..9f780ab86ad 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_inventory_classes.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_inventory_classes.py @@ -61,7 +61,7 @@ def test_attributes_instanciated() -> None: status_attributes={"vendor": "camembert"}, inventory_attributes={"version": "42"}, ) - assert attr == attr # pylint: disable= comparison-with-itself # noqa: PLR0124 + assert attr == attr # noqa: PLR0124 assert attr2 != attr @@ -111,5 +111,5 @@ def test_tablerow_instanciated() -> None: status_columns={"packages": 42}, inventory_columns={"vendor": "gorgonzola"}, ) - assert table_row == table_row # pylint: disable= comparison-with-itself # noqa: PLR0124 + assert table_row == table_row # noqa: PLR0124 assert table_row2 != table_row diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_render_api.py b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_render_api.py index 1ac4e553d6f..b2da05136cb 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_render_api.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/v1/test_render_api.py @@ -71,7 +71,7 @@ def test_timespan_negative() -> None: ], ) def test__digits_left(value: float, output: int) -> None: - assert output == render._digits_left(value) # pylint: disable=protected-access + assert output == render._digits_left(value) # noqa: SLF001 @pytest.mark.parametrize( @@ -89,7 +89,7 @@ def test__digits_left(value: float, output: int) -> None: ], ) def test__auto_scale(value: float, use_si_units: bool, output: tuple[str, str]) -> None: - assert output == render._auto_scale(value, use_si_units) # pylint: disable=protected-access + assert output == render._auto_scale(value, use_si_units) # noqa: SLF001 @pytest.mark.parametrize( diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_check_levels.py b/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_check_levels.py index 9c5047ee2e0..cdb16c59c01 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_check_levels.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_check_levels.py @@ -259,7 +259,7 @@ def test_summarize_predictions( ), ], ) -def test_check_levels( # pylint: disable=too-many-arguments,too-many-positional-arguments +def test_check_levels( # noqa: PLR0913 value: float, levels_upper: NoLevelsT | FixedLevelsT[float] | None, levels_lower: NoLevelsT | FixedLevelsT[float] | None, @@ -344,7 +344,7 @@ def test_check_levels( # pylint: disable=too-many-arguments,too-many-positional ), ], ) -def test_check_levels_with_metric( # pylint: disable=too-many-arguments,too-many-positional-arguments +def test_check_levels_with_metric( # noqa: PLR0913 value: float, levels_upper: LevelsT[float] | None, levels_lower: LevelsT[float] | None, diff --git a/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_render_api.py b/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_render_api.py index e69ea906692..a3b4491d760 100644 --- a/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_render_api.py +++ b/packages/cmk-agent-based/tests/cmk/agent_based/v2/test_render_api.py @@ -3,7 +3,6 @@ # 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. -# pylint: disable=duplicate-code import time diff --git a/packages/cmk-agent-receiver/BUILD b/packages/cmk-agent-receiver/BUILD index d0f291a82da..46c70e104f2 100644 --- a/packages/cmk-agent-receiver/BUILD +++ b/packages/cmk-agent-receiver/BUILD @@ -19,6 +19,8 @@ py_library( "cmk/agent_receiver/utils.py", "cmk/agent_receiver/worker.py", ], + imports = ["."], + visibility = ["//cmk:__pkg__"], ) py_wheel( @@ -32,4 +34,8 @@ py_wheel( ], ) -package_wheel(wheel_target = "wheel") +package_wheel( + name = "pkg_tar", + visibility = ["//visibility:public"], + whl = "wheel", +) diff --git a/packages/cmk-agent-receiver/Pipfile.lock b/packages/cmk-agent-receiver/Pipfile.lock index 9be745f6dc3..d5a4acf9d1d 100644 --- a/packages/cmk-agent-receiver/Pipfile.lock +++ b/packages/cmk-agent-receiver/Pipfile.lock @@ -115,99 +115,114 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", + "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", + "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", + "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", + "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", + "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", + "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", + "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", + "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", + "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", + "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", + "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", + "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", + "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", + "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", + "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", + "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", + "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", + "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", + "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", + "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", + "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", + "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", + "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", + "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", + "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", + "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", + "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", + "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", + "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", + "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", + "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", + "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", + "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", + "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", + "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", + "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", + "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", + "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", + "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", + "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", + "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", + "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", + "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", + "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", + "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", + "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", + "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", + "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", + "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", + "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", + "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", + "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", + "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", + "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", + "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", + "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", + "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", + "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", + "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", + "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", + "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", + "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", + "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", + "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", + "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", + "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", + "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", + "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", + "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", + "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", + "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", + "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", + "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", + "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", + "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", + "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", + "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", + "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", + "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", + "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", + "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", + "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", + "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", + "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", + "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", + "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", + "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", + "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", + "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", + "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" ], "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.2" + "version": "==3.4.0" }, "click": { "hashes": [ @@ -415,11 +430,11 @@ }, "python-multipart": { "hashes": [ - "sha256:2b06ad9e8d50c7a8db80e3b56dab590137b323410605af2be20d62a5f1ba1dc8", - "sha256:46eb3c6ce6fdda5fb1a03c7e11d490e407c6930a2703fe7aef4da71c374688fa" + "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb", + "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf" ], "markers": "python_version >= '3.8'", - "version": "==0.0.10" + "version": "==0.0.12" }, "requests": { "hashes": [ @@ -474,11 +489,11 @@ "standard" ], "hashes": [ - "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", - "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5" + "sha256:adc42d9cac80cf3e51af97c1851648066841e7cfb6993a4ca8de29ac1548ed41", + "sha256:f5167919867b161b7bcaf32646c6a94cdbd4c3aa2eb5c17d36bb9aa5cfd8c493" ], "markers": "python_version >= '3.8'", - "version": "==0.30.6" + "version": "==0.31.1" } }, "develop": { @@ -492,20 +507,20 @@ }, "astroid": { "hashes": [ - "sha256:2d79acfd3c594b6a2d4141fea98a1d62ab4a52e54332b1f1ddcf07b652cc5c0f", - "sha256:63f8c5370d9bad8294163c87b2d440a7fdf546be6c72bbeac0549c93244dbd72" + "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d", + "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8" ], "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.3" + "version": "==3.3.5" }, "bandit": { "hashes": [ - "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec", - "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61" + "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b", + "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.7.9" + "version": "==1.7.10" }, "certifi": { "hashes": [ @@ -517,11 +532,11 @@ }, "dill": { "hashes": [ - "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", - "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" + "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", + "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c" ], "markers": "python_version >= '3.11'", - "version": "==0.3.8" + "version": "==0.3.9" }, "docstring-to-markdown": { "hashes": [ @@ -541,11 +556,11 @@ }, "httpcore": { "hashes": [ - "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", - "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", + "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f" ], "markers": "python_version >= '3.8'", - "version": "==1.0.5" + "version": "==1.0.6" }, "httpx": { "hashes": [ @@ -680,12 +695,12 @@ }, "pylint": { "hashes": [ - "sha256:02dce1845f68974b9b03045894eb3bf05a8b3c7da9fd10af4de3c91e69eb92f1", - "sha256:c685fe3c061ee5fb0ce7c29436174ab84a2f525fce2a268b1986e921e083fe22" + "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9", + "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e" ], "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.0" + "version": "==3.3.1" }, "pylsp-mypy": { "hashes": [ @@ -792,20 +807,20 @@ }, "rich": { "hashes": [ - "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", - "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "ruff": { "hashes": [ - "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", - "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b" + "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", + "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.6.7" + "version": "==0.6.9" }, "sniffio": { "hashes": [ @@ -833,12 +848,12 @@ }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", + "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" + "version": "==2.9.0.20241003" }, "types-requests": { "hashes": [ diff --git a/packages/cmk-crypto/BUILD b/packages/cmk-crypto/BUILD index 9aa339cb283..1b6ed9cb7af 100644 --- a/packages/cmk-crypto/BUILD +++ b/packages/cmk-crypto/BUILD @@ -17,6 +17,8 @@ py_library( "cmk/crypto/symmetric.py", "cmk/crypto/totp.py", ], + imports = ["."], + visibility = ["//cmk:__pkg__"], ) py_wheel( @@ -30,4 +32,8 @@ py_wheel( ], ) -package_wheel(wheel_target = "wheel") +package_wheel( + name = "pkg_tar", + visibility = ["//visibility:public"], + whl = "wheel", +) diff --git a/packages/cmk-crypto/Pipfile.lock b/packages/cmk-crypto/Pipfile.lock index 6ace9aecb31..f194c7fe55f 100644 --- a/packages/cmk-crypto/Pipfile.lock +++ b/packages/cmk-crypto/Pipfile.lock @@ -185,111 +185,100 @@ }, "time-machine": { "hashes": [ - "sha256:008bd668d933b1a029c81805bcdc0132390c2545b103cf8e6709e3adbc37989d", - "sha256:014589d0edd4aa14f8d63985745565e8cbbe48461d6c004a96000b47f6b44e78", - "sha256:0302568338c8bd333ed0698231dbb781b70ead1a5579b4ac734b9bf88313229f", - "sha256:0630a32e9ebcf2fac3704365b31e271fef6eabd6fedfa404cd8dbd244f7fc84d", - "sha256:09fd839a321a92aa8183206c383b9725eaf4e0a28a70e4cb87db292b352eeefb", - "sha256:0b2d28daf4cabc698aafb12135525d87dc1f2f893cbd29a8a6fe0d8d36d1342c", - "sha256:1168eebd7af7e6e3e2fd378c16ca917b97dd81c89a1f1f9e1daa985c81699d90", - "sha256:18fc4740073e67071472c48355775ec6d1b93af5c675524b7de2474e0dcd8741", - "sha256:1dee3a0dd1866988c49a5d00564404db9bcdf49ca92f9c4e8b6c99609d64e698", - "sha256:245ef73f9927b7d4909d554a6a0284dbc5dee9730adea599e430b37c9e9fa203", - "sha256:29b988b1f09f2a083b12b6b054787b799ae91ee15bb0e9de3e48f880e4d68674", - "sha256:31af56399bf7c9ef76a3f7b6d9471dffa8f06ee373c194a374b69523f9061de9", - "sha256:3862dda89bdb05f9d521b08fdcb24b19a7dd9f559ae324f4301ba7a07b6eea64", - "sha256:3b177d334a35bf2ce103bfe4e0e416e4ee824dd33386ea73fa7491c17cc61897", - "sha256:3f7eadd820e792de33a9ec91f8178a2b9088e4e8b9a166953419ddc4ec5f7cfe", - "sha256:4428bdae507996aa3fdeb4727bca09e26306fa64a502e7335207252684516cbf", - "sha256:4601fe7a6b74c6fd9207e614d9db2a20dd4befd4d314677a0feac13a67189707", - "sha256:4cd9f057457d12604be18b623bcd5ae7d0b917ad66cb510ee1135d5f123666e2", - "sha256:4e83fd6112808d1d14d1a57397c6fa3bd71bb2f3b8800036e12366e3680819b9", - "sha256:52468a0784544eba708c0ae6bc5e8c5dcfd685495a60f7f74028662c984bd9cd", - "sha256:5d4073b754f90b19f28d036ec5143d3fca3a75e4d4241d78790a6178b00bb373", - "sha256:5f7add997684bc6141e1c80f6ba0c38ffe316ba277a4074e61b1b7b4f5a172bf", - "sha256:5ff655716cd13a242eef8cf5d368074e8b396ff86508a5933e7cff4f2b3eb3c2", - "sha256:617c9a92d8d8f60d5ef39e76596620503752a09f834a218e5b83be352fdd6c91", - "sha256:6425001e50a0c82108caed438233066cea04d42a8fc9c49bfcf081a5b96e5b4e", - "sha256:658ea8477fa020f08435fb7277635eb0b50cd5206b9d4cbe10e9a5466b01f855", - "sha256:65d395211736d9844537a530287a7c64b9fda1d353e899a0e1723986a0859154", - "sha256:660810cd27a8a94cb5e845e8f28a95e70b01ff0c45466d394c4a0cba5a0ae279", - "sha256:671e88a6209a1cf415dc0f8c67d2b2d3b55b436cc63801a518f9800ebd752959", - "sha256:674097dd54a0bbd555e7927092c74428c4c07268ad52bca38cfccc3214707e50", - "sha256:6f021aa2dbd8fbfe54d3fa2258518129108b7496922b3bcff2cf5991078eec67", - "sha256:704abc7f3403584cca9c01c5809812e0bd70632ea4251389fae4f45e11aad94f", - "sha256:73a8c8160d2a170dadcad5b82fb5ee53236a19cec0996651cf4d21da0a2574d5", - "sha256:768d33b484a35da93731cc99bdc926b539240a78673216cdc6306833d9072350", - "sha256:79bf1ef6850182e09d86e61fa31717da56014a3b2234afb025fca1f2a43ac07b", - "sha256:838a6d117739f1ae6ecc45ec630fa694f41a85c0d07b1f3b1db2a6cc52c1808b", - "sha256:8817b0f7d7830215261b18db83c9c3ef1da6bb64da5c292d7c70b9a46e5a6745", - "sha256:892d016789b59950989b2db188dcd46cf16d34e8daf2343e33b679b0c5fd1001", - "sha256:899f1a856b3bebb82b6cbc3c0014834b583b83f246b28e462a031ec1b766130b", - "sha256:8c2b1c91b437133c672e374857eccb1dd2c2d9f8477ae3b35138382d5ef19846", - "sha256:9479530e3fce65f6149058071fa4df8150025f15b43b103445f619842981a87c", - "sha256:95c8e7036cf442480d0bf6f5fde371e1eb6dbbf5391d7bdb8db73bd8a732b538", - "sha256:97dc6793e512a62ba9eab250134a2e67372c16ae9948e73d27c2ef355356e2e1", - "sha256:9a6a9342fae113b12aab42c790880c549d9ba695b8deff27ee08096eedd67569", - "sha256:a22f47c34ee1fcf7d93a8c5c93135499aac879d9d5d8f820bd28571a30fdabcd", - "sha256:a731c03bc00552ee6cc685a59616d36003124e7e04c6ddf65c2c47f1c3d85480", - "sha256:b095a1de40ca1afaeae8df3f45e26b645094a1912e6e6871e725fcf06ecdb74a", - "sha256:b48abd7745caec1a78a16a048966cde14ff6ccb04d471a7201532648d3f77d14", - "sha256:b5f3ab4185c1f72010846ca9fccb08349e23a2b52982a18d9870e848ce9f1c86", - "sha256:b684f8ecdeacd6baabc17b15ac1b054ca62029193e6c5367ef00b3516671de80", - "sha256:b7b647684eb2e1fd1e5e6b101249d5fe9d6117c117b5e336ad8dd75af48d2d1f", - "sha256:bcbb25029ee8756f10c6473cea5ef21707a1d9a8752cdf29fad3a5f34aa4a313", - "sha256:c0473dfa8f17c6a9a250b2bd6a5b62af3aa7d22518f701649115f1085d5e35ab", - "sha256:c08800c28160f4d32ca510128b4e201a43c813e7a2dd53178fa79ebe050eba13", - "sha256:c344eb09fcfbf71e5b5847d4f188fec98e1c3a976125ef571eac5f1c39e7a5e5", - "sha256:c596920d6017702a36e3a43fd8110a84e87d6229f30b84bd5640cbae9b5145da", - "sha256:c947135750d20f35acac290c34f1acf5771fc166a3fbc0e3816a97c756aaa5f5", - "sha256:d24d2ec74923b49bce7618e3e7762baa6be74e624d9829d5632321de102bf386", - "sha256:d828721dcbcb94b904a6b25df67c2513ecd24cd9e36694f38b9f0fa71c7c6103", - "sha256:ddad27a62df2ea47b7b483009fbfcf167a71d702cbd8e2eefd9ddc1c93146658", - "sha256:df6f618b98f0848fd8d07039541e10f23db679d8283f8719e870a98e1ef8e639", - "sha256:e1790481a6b9ce38888f22ce30710244067898c3ac4805a0e061e381f3db3506", - "sha256:e6776840aea3ff5ab6924b50117957da62db51b109b3b491c0d5817a804b1a8e", - "sha256:e99689f6c6b9ca6e2fc7a75d140e38c5a7985dab61fe1f4e506268f7e9844e05", - "sha256:ebd2e63baa117ded04b978813fcd1279d3fc6be2149c9cac75c716b6f1db774c", - "sha256:f50f10058b884d45cd8a50423bf561b1f9f9df7058abeb8b318700c8bcf4bb54", - "sha256:f5b94cba3edfc54bcb3ab5be616a2f50fa48be438e5af970824efdf882d1bc31" - ], - "markers": "python_version >= '3.8'", - "version": "==2.15.0" + "sha256:01bc257e9418980a4922de94775be42a966e1a082fb01a1635917f9afc7b84ca", + "sha256:09531af59fdfb39bfd24d28bd1e837eff5a5d98318509a31b6cfd57d27801e52", + "sha256:0c766bea27a0600e36806d628ebc4b47178b12fcdfb6c24dc0a566a9c06bfe7f", + "sha256:12474fcdbc475aa6fe5275fe7224e685c5b9777f5939647f35980e9614ae7558", + "sha256:15ec236b6571730236a193d9d6c11d472432fc6ab54e85eac1c16d98ddcd71bf", + "sha256:1784edf173ca840ba154de6eed000b5727f65ab92972c2f88cec5c4d6349c5f2", + "sha256:1e0dcc97cfec12ae306e3036746e7631cc7ef65c31889f7264c25217d4938367", + "sha256:23c5283c01b4f80b7dfbc88f3d8088c06c301b94b7c35366be498c2d7b308549", + "sha256:2552f0767bc10c9d668f108fef9b487809cdeb772439ce932e74136365c69baf", + "sha256:265462c77dc9576267c3c7f20707780a171a9fdbac93ac22e608c309efd68c33", + "sha256:298aa423e07c8b21b991782f01d7749c871c792319c2af3e9755f9ab49033212", + "sha256:2e08a4015d5d1aab2cb46c780e85b33efcd5cbe880bb363b282a6972e617b8bb", + "sha256:2f5876a5682ce1f517e55d7ace2383432627889f6f7e338b961f99d684fd9e8d", + "sha256:317b68b56a9c3731e0cf8886e0f94230727159e375988b36c60edce0ddbcb44a", + "sha256:32d445ce20d25c60ab92153c073942b0bac9815bfbfd152ce3dcc225d15ce988", + "sha256:4149e17018af07a5756a1df84aea71e6e178598c358c860c6bfec42170fa7970", + "sha256:43e1e18279759897be3293a255d53e6b1cb0364b69d9591d0b80c51e461c94b0", + "sha256:4a99acc273d2f98add23a89b94d4dd9e14969c01214c8514bfa78e4e9364c7e2", + "sha256:4d3843143c46dddca6491a954bbd0abfd435681512ac343169560e9bab504129", + "sha256:503e7ff507c2089699d91885fc5b9c8ff16774a7b6aff48b4dcee0c0a0685b61", + "sha256:520a814ea1b2706c89ab260a54023033d3015abef25c77873b83e3d7c1fafbb2", + "sha256:5886e23ede3478ca2a3e0a641f5d09dd784dfa9e48c96e8e5e31fc4fe77b6dc0", + "sha256:64c205ea37b8c4ba232645335fc3b75bc2d03ce30f0a34649e36cae85652ee96", + "sha256:667b150fedb54acdca2a4bea5bf6da837b43e6dd12857301b48191f8803ba93f", + "sha256:6895e3e84119594ab12847c928f619d40ae9cedd0755515dc154a5b5dc6edd9f", + "sha256:6dae82ab647d107817e013db82223e20a9853fa88543fec853ae326382d03c2e", + "sha256:7751bf745d54e9e8b358c0afa332815da9b8a6194b26d0fd62876ab6c4d5c9c0", + "sha256:7c29616e18e2349a8766d5b6817920fc74e39c00fa375d202231e9d525a1b882", + "sha256:806672529a2e255cd901f244c9033767dc1fa53466d0d3e3e49565a1572a64fe", + "sha256:8243664438bb468408b29c6865958662d75e51f79c91842d2794fa22629eb697", + "sha256:84788f4d62a8b1bf5e499bb9b0e23ceceea21c415ad6030be6267ce3d639842f", + "sha256:8f936566ef9f09136a3d5db305961ef6d897b76b240c9ff4199144aed6dd4fe5", + "sha256:92d0b0f3c49f34dd76eb462f0afdc61ed1cb318c06c46d03e99b44ebb489bdad", + "sha256:9d26d79de1c63a8c6586c75967e09b0ff306aa7e944a1eaddb74595c9b1839ca", + "sha256:9db5e5b3ccdadaafa5730c2f9db44c38b013234c9ad01f87738907e19bdba268", + "sha256:ac2df0fa564356384515ed62cb6679f33f1f529435b16b0ec0f88414635dbe39", + "sha256:ac95ae4529d7d85b251f9cf0f961a8a408ba285875811268f469d824a3b0b15a", + "sha256:c0fca3025266d88d1b48be162a43b7c2d91c81cc5b3bee9f01194678ffb9969a", + "sha256:c1906ec6e26e6b803cd6aab28d420c87285b9c209ff2a69f82d12f82278f78bb", + "sha256:c1ceb6035a64cb00650e3ab203cf3faffac18576a3f3125c24df468b784077c7", + "sha256:c761d32d0c5d1fe5b71ac502e1bd5edec4598a7fc6f607b9b906b98e911148ce", + "sha256:c76caf539fa4941e1817b7c482c87c65c52a1903fea761e84525955c6106fafb", + "sha256:cac3e2b4101db296b150cb665e5461c03621e6ede6117fc9d5048c0ec96d6e7c", + "sha256:cedc989717c8b44a3881ac3d68ab5a95820448796c550de6a2149ed1525157f0", + "sha256:d0b6ff3ccde9b16bbc694a2b5facf2d8890554f3135ff626ed1429e270e3cc4f", + "sha256:d5fe7a6284e3dce87ae13a25029c53542dd27a28d151f3ef362ec4dd9c3e45fd", + "sha256:da3ae1028af240c0c46c79adf9c1acffecc6ed1701f2863b8132f5ceae6ae4b5", + "sha256:ddfab1c622342f2945942c5c2d6be327656980e8f2d2b2ce0c022d0aa3711361", + "sha256:dfb76674db946a74f0ca6e3b81caa8265e35dafe9b7005c7d2b8dd5bbd3825cf", + "sha256:dfe92412bd11104c4f0fb2da68653e6c45b41f7217319a83a8b66ed4f20148b3", + "sha256:e3391ae9c484736850bb44ef125cbad52fe2d1b69e42c95dc88c43af8ead2cc7", + "sha256:e43adb22def972a29d2b147999b56897116085777a0fea182fd93ee45730611e", + "sha256:e46bd09c944ec7a20868abd2b83d7d7abdaf427775e9df3089b9226a122b340f", + "sha256:eee7b0fc4fbab2c6585ea17606c6548be83919c70deea0865409fe9fc2d8cdce", + "sha256:ef768e14768eebe3bb1196c0dece8e14c1c6991605721214a0c3c68cf77eb216", + "sha256:f6927dda86425f97ffda36131f297b1a601c64a6ee6838bfa0e6d3149c2f0d9f" + ], + "markers": "python_version >= '3.9'", + "version": "==2.16.0" }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", + "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446" ], "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" + "version": "==2.9.0.20241003" } }, "develop": { "astroid": { "hashes": [ - "sha256:2d79acfd3c594b6a2d4141fea98a1d62ab4a52e54332b1f1ddcf07b652cc5c0f", - "sha256:63f8c5370d9bad8294163c87b2d440a7fdf546be6c72bbeac0549c93244dbd72" + "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d", + "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8" ], "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.3" + "version": "==3.3.5" }, "bandit": { "hashes": [ - "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec", - "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61" + "sha256:59ed5caf5d92b6ada4bf65bc6437feea4a9da1093384445fed4d472acc6cff7b", + "sha256:665721d7bebbb4485a339c55161ac0eedde27d51e638000d91c8c2d68343ad02" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.7.9" + "version": "==1.7.10" }, "dill": { "hashes": [ - "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", - "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" + "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", + "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c" ], "markers": "python_version >= '3.11'", - "version": "==0.3.8" + "version": "==0.3.9" }, "docstring-to-markdown": { "hashes": [ @@ -415,12 +404,12 @@ }, "pylint": { "hashes": [ - "sha256:02dce1845f68974b9b03045894eb3bf05a8b3c7da9fd10af4de3c91e69eb92f1", - "sha256:c685fe3c061ee5fb0ce7c29436174ab84a2f525fce2a268b1986e921e083fe22" + "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9", + "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e" ], "index": "pypi", "markers": "python_full_version >= '3.9.0'", - "version": "==3.3.0" + "version": "==3.3.1" }, "pylsp-mypy": { "hashes": [ @@ -518,20 +507,20 @@ }, "rich": { "hashes": [ - "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06", - "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a" + "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c", + "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.8.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==13.9.2" }, "ruff": { "hashes": [ - "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5", - "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b" + "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", + "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.6.7" + "version": "==0.6.9" }, "stevedore": { "hashes": [ diff --git a/packages/cmk-frontend-vue/.eslintrc.cjs b/packages/cmk-frontend-vue/.eslintrc.cjs index ea0789e30d8..4e4fa5f46bf 100644 --- a/packages/cmk-frontend-vue/.eslintrc.cjs +++ b/packages/cmk-frontend-vue/.eslintrc.cjs @@ -2,7 +2,7 @@ require('@rushstack/eslint-patch/modern-module-resolution') module.exports = { - ignorePatterns: ['.eslintrc.cjs', 'vite.config.ts', 'tailwind.config.js'], + ignorePatterns: ['.eslintrc.cjs', 'vite.config.demo.ts', 'vite.config.ts', 'tailwind.config.js'], root: true, extends: [ 'plugin:@typescript-eslint/recommended', @@ -45,6 +45,9 @@ module.exports = { varsIgnorePattern: '^_' } ], + eqeqeq: 'error', + 'vue/eqeqeq': 'error', + 'no-var': 'error', curly: 'error', 'prefer-template': 'error', 'vue/prefer-template': 'error', diff --git a/packages/cmk-frontend-vue/.prettierignore b/packages/cmk-frontend-vue/.prettierignore index e2bf071a38b..260072a95e3 100644 --- a/packages/cmk-frontend-vue/.prettierignore +++ b/packages/cmk-frontend-vue/.prettierignore @@ -1 +1,2 @@ -src/form/components/vue_formspec_components.ts \ No newline at end of file +src/form/components/vue_formspec_components.ts +src/notification/type_defs.ts \ No newline at end of file diff --git a/packages/cmk-frontend-vue/README.md b/packages/cmk-frontend-vue/README.md index d0a27a97968..d37596513a2 100644 --- a/packages/cmk-frontend-vue/README.md +++ b/packages/cmk-frontend-vue/README.md @@ -30,6 +30,17 @@ vite dev server is used. Checkmk should then automatically reload as soon as you change a file of the cmk-frontend-vue project. +### testing components outsite a site + +* run `npm ci` in this folder, and also in `../cmk-frontend` + * yes, we should not need to execute `npm ci` in another package, but this + is the current reality: the code in `cmk-frontend-vue` is not really + independent of `cmk-frontend`. The styling of `cmk-frontend` is necessary + for many `FormEdit` sub-components. +* run `npm run -- dev --config vite.config.demo.ts` +* surf to `http://localhost:5173/` + + ### Location of files and folders src/ form/ # files for form rendering @@ -55,3 +66,11 @@ src/ graph-designer/ # upcoming: reworked graph designer GraphDesignerApp.vue components/ # Files for the graph-designer feature + notification/ + NotificationOverviewApp.vue # Overview page for notifications + NotificationParametersOverviewApp.vue # Overview page for notification parameter + components/ + CoreStats.vue # Core statistics on notification overview page + FallbackWarning.vue # Warning about missing fallback Email address on notification overview page + NotificationRules.vue # Notification rule list on notification overview page + NotificationStats.vue # Notification statistics on notification overview page diff --git a/packages/cmk-frontend-vue/package-lock.json b/packages/cmk-frontend-vue/package-lock.json index 7204d200d83..1495eebdccc 100644 --- a/packages/cmk-frontend-vue/package-lock.json +++ b/packages/cmk-frontend-vue/package-lock.json @@ -12,21 +12,18 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "core-js": "^3.38.0", - "crossfilter2": "^1.5.4", - "d3": "^7.9.0", - "jquery": "^3.7.1", "lucide-vue-next": "^0.427.0", - "radix-vue": "^1.9.4", + "radix-vue": "^1.9.7", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", - "vue": "^3.5.5" + "vue": "^3.5.5", + "vue-router": "^4.4.5" }, "devDependencies": { "@rushstack/eslint-patch": "^1.10.4", "@testing-library/jest-dom": "^6.5.0", "@testing-library/vue": "^8.1.0", "@tsconfig/node20": "^20.1.4", - "@types/d3": "^7.4.3", "@types/node": "^20.14.2", "@vitejs/plugin-vue": "^5.1.2", "@vue/eslint-config-prettier": "^9.0.0", @@ -38,6 +35,7 @@ "jsdom": "^24.1.1", "npm-run-all2": "^6.2.2", "prettier": "^3.3.3", + "sass-embedded": "^1.79.4", "typescript": "~5.5.4", "vite": "^5.4.0", "vitest": "^1.6.0", @@ -217,6 +215,12 @@ "node": ">=6.9.0" } }, + "node_modules/@bufbuild/protobuf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.1.0.tgz", + "integrity": "sha512-+2Mx67Y3skJ4NCD/qNSdBJNWtu6x6Qr53jeNg+QcwiL6mt0wK+3jwHH2x1p7xaYH6Ve2JKOVn0OxU35WsmqI9A==", + "dev": true + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -952,214 +956,225 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@ranfdev/deepobj": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@ranfdev/deepobj/-/deepobj-1.0.2.tgz", - "integrity": "sha512-FM3y6kfJaj5MCoAjdv24EDCTDbuFz+4+pgAunbjYfugwIE4O/xx8mPNji1n/ouG8pHCntSnBr1xwTOensF23Gg==" - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", - "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz", - "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz", - "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz", - "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz", - "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz", - "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz", - "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz", - "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz", - "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz", - "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz", - "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz", - "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz", - "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz", - "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz", - "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz", - "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -1302,271 +1317,12 @@ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true }, - "node_modules/@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dev": true, - "dependencies": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", - "dev": true - }, - "node_modules/@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", - "dev": true - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "dev": true - }, - "node_modules/@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "dev": true, - "dependencies": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "dev": true - }, - "node_modules/@types/d3-dispatch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", - "dev": true - }, - "node_modules/@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", - "dev": true - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", - "dev": true - }, - "node_modules/@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "dev": true, - "dependencies": { - "@types/d3-dsv": "*" - } - }, - "node_modules/@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", - "dev": true - }, - "node_modules/@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", - "dev": true - }, - "node_modules/@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "dev": true, - "dependencies": { - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", - "dev": true - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dev": true, - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", - "dev": true - }, - "node_modules/@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", - "dev": true - }, - "node_modules/@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", - "dev": true - }, - "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", - "dev": true - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dev": true, - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==", - "dev": true - }, - "node_modules/@types/d3-selection": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", - "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==", - "dev": true - }, - "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "dev": true, - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==", - "dev": true - }, - "node_modules/@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", - "dev": true - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", - "dev": true - }, - "node_modules/@types/d3-transition": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", - "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "dev": true, - "dependencies": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "node_modules/@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", - "dev": true - }, "node_modules/@types/node": { "version": "20.14.14", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", @@ -2115,6 +1871,11 @@ "he": "^1.2.0" } }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, "node_modules/@vue/eslint-config-prettier": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", @@ -2570,6 +2331,12 @@ "node": ">=8" } }, + "node_modules/buffer-builder": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", + "integrity": "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg==", + "dev": true + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -2736,6 +2503,12 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2747,14 +2520,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, "node_modules/computeds": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", @@ -2806,14 +2571,6 @@ "node": ">= 8" } }, - "node_modules/crossfilter2": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/crossfilter2/-/crossfilter2-1.5.4.tgz", - "integrity": "sha512-oOGqOM0RocwQFOXJnEaUKqYV6Mc1TNCRv3LrNUa0QlofQTutGAXyQaLW1aGKLls2sfnbwBEtsa6tPD3jY+ycqQ==", - "dependencies": { - "@ranfdev/deepobj": "1.0.2" - } - }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -2854,511 +2611,133 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, - "node_modules/d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, "dependencies": { - "internmap": "1 - 2" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "engines": { - "node": ">=12" - } + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" + "ms": "2.1.2" }, "engines": { - "node": ">=12" - } - }, - "node_modules/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "dependencies": { - "d3-path": "1 - 3" + "node": ">=6.0" }, - "engines": { - "node": ">=12" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "engines": { - "node": ">=12" - } + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true }, - "node_modules/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "dependencies": { - "d3-array": "^3.2.0" - }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, "dependencies": { - "delaunator": "5" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "engines": { - "node": ">=12" - } + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, - "node_modules/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "dependencies": { - "d3-dsv": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "d3-selection": "2 - 3" - } - }, - "node_modules/d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==" - }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "dependencies": { - "robust-predicates": "^3.0.2" - } + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==" }, "node_modules/delayed-stream": { "version": "1.0.0", @@ -4304,6 +3683,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -4320,6 +3700,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -4391,14 +3777,6 @@ "node": ">= 0.4" } }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" - } - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -4737,11 +4115,6 @@ "jiti": "bin/jiti.js" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" - }, "node_modules/js-beautify": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", @@ -5855,9 +5228,9 @@ ] }, "node_modules/radix-vue": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/radix-vue/-/radix-vue-1.9.4.tgz", - "integrity": "sha512-d950wxB+MVVU6L9h39OsNzAdk2BiGDDfhXJiHsksPAIK5pCR8W4U0RB0WLQEdjmmL9p1aXOYm4FBDq0oIo2G/w==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/radix-vue/-/radix-vue-1.9.7.tgz", + "integrity": "sha512-1xleWzWNFPfAMmb81gu/4/MV8dXMvc7j2EIjutBpBcKwxdJfeIcQg4k9De18L2rL1/GZg5wA9KykeKTM4MjWow==", "dependencies": { "@floating-ui/dom": "^1.6.7", "@floating-ui/vue": "^1.1.0", @@ -6052,16 +5425,12 @@ "node": "*" } }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, "node_modules/rollup": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", - "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -6073,22 +5442,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.20.0", - "@rollup/rollup-android-arm64": "4.20.0", - "@rollup/rollup-darwin-arm64": "4.20.0", - "@rollup/rollup-darwin-x64": "4.20.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.20.0", - "@rollup/rollup-linux-arm-musleabihf": "4.20.0", - "@rollup/rollup-linux-arm64-gnu": "4.20.0", - "@rollup/rollup-linux-arm64-musl": "4.20.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0", - "@rollup/rollup-linux-riscv64-gnu": "4.20.0", - "@rollup/rollup-linux-s390x-gnu": "4.20.0", - "@rollup/rollup-linux-x64-gnu": "4.20.0", - "@rollup/rollup-linux-x64-musl": "4.20.0", - "@rollup/rollup-win32-arm64-msvc": "4.20.0", - "@rollup/rollup-win32-ia32-msvc": "4.20.0", - "@rollup/rollup-win32-x64-msvc": "4.20.0", + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", "fsevents": "~2.3.2" } }, @@ -6120,15 +5489,398 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass-embedded": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.79.4.tgz", + "integrity": "sha512-3AATrtStMgxYjkit02/Ix8vx/P7qderYG6DHjmehfk5jiw53OaWVScmcGJSwp/d77kAkxDQ+Y0r+79VynGmrkw==", + "dev": true, + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "buffer-builder": "^0.2.0", + "colorjs.io": "^0.5.0", + "immutable": "^4.0.0", + "rxjs": "^7.4.0", + "supports-color": "^8.1.1", + "varint": "^6.0.0" + }, + "bin": { + "sass": "dist/bin/sass.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "optionalDependencies": { + "sass-embedded-android-arm": "1.79.4", + "sass-embedded-android-arm64": "1.79.4", + "sass-embedded-android-ia32": "1.79.4", + "sass-embedded-android-riscv64": "1.79.4", + "sass-embedded-android-x64": "1.79.4", + "sass-embedded-darwin-arm64": "1.79.4", + "sass-embedded-darwin-x64": "1.79.4", + "sass-embedded-linux-arm": "1.79.4", + "sass-embedded-linux-arm64": "1.79.4", + "sass-embedded-linux-ia32": "1.79.4", + "sass-embedded-linux-musl-arm": "1.79.4", + "sass-embedded-linux-musl-arm64": "1.79.4", + "sass-embedded-linux-musl-ia32": "1.79.4", + "sass-embedded-linux-musl-riscv64": "1.79.4", + "sass-embedded-linux-musl-x64": "1.79.4", + "sass-embedded-linux-riscv64": "1.79.4", + "sass-embedded-linux-x64": "1.79.4", + "sass-embedded-win32-arm64": "1.79.4", + "sass-embedded-win32-ia32": "1.79.4", + "sass-embedded-win32-x64": "1.79.4" + } + }, + "node_modules/sass-embedded-android-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.79.4.tgz", + "integrity": "sha512-YOVpDGDcwWUQvktpJhYo4zOkknDpdX6ALpaeHDTX6GBUvnZfx+Widh76v+QFUhiJQ/I/hndXg1jv/PKilOHRrw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.79.4.tgz", + "integrity": "sha512-0JAZ8TtXYv9yI3Yasaq03xvo7DLJOmD+Exb30oJKxXcWTAV9TB0ZWKoIRsFxbCyPxyn7ouxkaCEXQtaTRKrmfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.79.4.tgz", + "integrity": "sha512-IjO3RoyvNN84ZyfAR5s/a8TIdNPfClb7CLGrswB3BN/NElYIJUJMVHD6+Y8W9QwBIZ8DrK1IdLFSTV8nn82xMA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.79.4.tgz", + "integrity": "sha512-uOT8nXmKxSwuIdcqvElVWBFcm/+YcIvmwfoKbpuuSOSxUe9eqFzxo+fk7ILhynzf6FBlvRUH5DcjGj+sXtCc3w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-android-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.79.4.tgz", + "integrity": "sha512-W2FQoj3Z2J2DirNs3xSBVvrhMuqLnsqvOPulxOkhL/074+faKOZZnPx2tZ5zsHbY97SonciiU0SV0mm98xI42w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.79.4.tgz", + "integrity": "sha512-pcYtbN1VUAAcfgyHeX8ySndDWGjIvcq6rldduktPbGGuAlEWFDfnwjTbv0hS945ggdzZ6TFnaFlLEDr0SjKzBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-darwin-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.79.4.tgz", + "integrity": "sha512-ir8CFTfc4JLx/qCP8LK1/3pWv35nRyAQkUK7lBIKM6hWzztt64gcno9rZIk4SpHr7Z/Bp1IYWWRS4ZT+4HmsbA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.79.4.tgz", + "integrity": "sha512-H/XEE3rY7c+tY0qDaELjPjC6VheAhBo1tPJQ6UHoBEf8xrbT/RT3dWiIS8grp9Vk54RCn05BEB/+POaljvvKGA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.79.4.tgz", + "integrity": "sha512-XIVn2mCuA422SR2kmKjF6jhjMs1Vrt1DbZ/ktSp+eR0sU4ugu2htg45GajiUFSKKRj7Sc+cBdThq1zPPsDLf1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.79.4.tgz", + "integrity": "sha512-3nqZxV4nuUTb1ahLexVl4hsnx1KKwiGdHEf1xHWTZai6fYFMcwyNPrHySCQzFHqb5xiqSpPzzrKjuDhF6+guuQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.79.4.tgz", + "integrity": "sha512-HnbU1DEiQdUayioNzxh2WlbTEgQRBPTgIIvof8J63QLmVItUqE7EkWYkSUy4RhO+8NsuN9wzGmGTzFBvTImU7g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.79.4.tgz", + "integrity": "sha512-C6qX06waPEfDgOHR8jXoYxl0EtIXOyBDyyonrLO3StRjWjGx7XMQj2hA/KXSsV+Hr71fBOsaViosqWXPzTbEiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.79.4.tgz", + "integrity": "sha512-y5b0fdOPWyhj4c+mc88GvQiC5onRH1V0iNaWNjsiZ+L4hHje6T98nDLrCJn0fz5GQnXjyLCLZduMWbfV0QjHGg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.79.4.tgz", + "integrity": "sha512-G2M5ADMV9SqnkwpM0S+UzDz7xR2njCOhofku/sDMZABzAjQQWTsAykKoGmzlT98fTw2HbNhb6u74umf2WLhCfw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-musl-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.79.4.tgz", + "integrity": "sha512-kQm8dCU3DXf7DtUGWYPiPs03KJYKvFeiZJHhSx993DCM8D2b0wCXWky0S0Z46gf1sEur0SN4Lvnt1WczTqxIBw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-riscv64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.79.4.tgz", + "integrity": "sha512-GaTI/mXYWYSzG5wxtM4H2cozLpATyh+4l+rO9FFKOL8e1sUOLAzTeRdU2nSBYCuRqsxRuTZIwCXhSz9Q3NRuNA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-linux-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.79.4.tgz", + "integrity": "sha512-f9laGkqHgC01h99Qt4LsOV+OLMffjvUcTu14hYWqMS9QVX5a4ihMwpf1NoAtTUytb7cVF3rYY/NVGuXt6G3ppQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-arm64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.79.4.tgz", + "integrity": "sha512-cidBvtaA2cJ6dNlwQEa8qak+ezypurzKs0h0QAHLH324+j/6Jum7LCnQhZRPYJBFjHl+WYd7KwzPnJ2X5USWnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-ia32": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.79.4.tgz", + "integrity": "sha512-hexdmNTIZGTKNTzlMcdvEXzYuxOJcY89zqgsf45aQ2YMy4y2M8dTOxRI/Vz7p4iRxVp1Jow6LCtaLHrNI2Ordg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded-win32-x64": { + "version": "1.79.4", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.79.4.tgz", + "integrity": "sha512-73yrpiWIbti6DkxhWURklkgSLYKfU9itDmvHxB+oYSb4vQveIApqTwSyTOuIUb/6Da/EsgEpdJ4Lbj4sLaMZWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-embedded/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } }, "node_modules/saxes": { "version": "6.0.0", @@ -6769,15 +6521,22 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", + "dev": true + }, "node_modules/vite": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", - "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.40", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -7065,6 +6824,20 @@ "eslint": ">=6.0.0" } }, + "node_modules/vue-router": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", + "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/vue-tsc": { "version": "2.0.29", "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.29.tgz", diff --git a/packages/cmk-frontend-vue/package.json b/packages/cmk-frontend-vue/package.json index bd183093f3c..2c61ab36147 100644 --- a/packages/cmk-frontend-vue/package.json +++ b/packages/cmk-frontend-vue/package.json @@ -18,21 +18,18 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "core-js": "^3.38.0", - "crossfilter2": "^1.5.4", - "d3": "^7.9.0", - "jquery": "^3.7.1", "lucide-vue-next": "^0.427.0", - "radix-vue": "^1.9.4", + "radix-vue": "^1.9.7", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", - "vue": "^3.5.5" + "vue": "^3.5.5", + "vue-router": "^4.4.5" }, "devDependencies": { "@rushstack/eslint-patch": "^1.10.4", "@testing-library/jest-dom": "^6.5.0", "@testing-library/vue": "^8.1.0", "@tsconfig/node20": "^20.1.4", - "@types/d3": "^7.4.3", "@types/node": "^20.14.2", "@vitejs/plugin-vue": "^5.1.2", "@vue/eslint-config-prettier": "^9.0.0", @@ -44,6 +41,7 @@ "jsdom": "^24.1.1", "npm-run-all2": "^6.2.2", "prettier": "^3.3.3", + "sass-embedded": "^1.79.4", "typescript": "~5.5.4", "vite": "^5.4.0", "vitest": "^1.6.0", diff --git a/packages/cmk-frontend-vue/scripts/test_license_headers.py b/packages/cmk-frontend-vue/scripts/test_license_headers.py index a3c5dfae686..bfd233db6bb 100644 --- a/packages/cmk-frontend-vue/scripts/test_license_headers.py +++ b/packages/cmk-frontend-vue/scripts/test_license_headers.py @@ -28,8 +28,8 @@ Path(".prettierrc.json"), Path("README.md"), Path("index.html"), + Path("src/components/_demo/index.html"), Path("env.d.ts"), - Path("src/form/components/vue_formspec_components.ts"), # auto generated ] ) diff --git a/packages/cmk-frontend-vue/src/assets/variables.css b/packages/cmk-frontend-vue/src/assets/variables.css index 89a124acb88..93e5b1e03d5 100644 --- a/packages/cmk-frontend-vue/src/assets/variables.css +++ b/packages/cmk-frontend-vue/src/assets/variables.css @@ -34,7 +34,14 @@ --icon-save-to-services: url('~cmk-frontend/src/themes/facelift/images/icon_save_to_services.svg'); --icon-insertdate: url('~cmk-frontend/src/themes/facelift/images/icon_insertdate.png'); --icon-alert-crit: url('~cmk-frontend/src/themes/facelift/images/icon_alert_crit.svg'); + --icon-alert-warn: url('~cmk-frontend/src/themes/facelift/images/icon_alert_warn.png'); + --icon-alert-up: url('~cmk-frontend/src/themes/facelift/images/icon_alert_up.png'); + --icon-about-checkmk: url('~cmk-frontend/src/themes/facelift/images/icon_about_checkmk.svg'); --icon-check: url('~cmk-frontend/src/themes/facelift/images/icon_check.svg'); + --icon-save: url('~cmk-frontend/src/themes/facelift/images/icon_save.svg'); + --icon-cancel: url('~cmk-frontend/src/themes/facelift/images/icon_cancel.svg'); + --icon-search: url('~cmk-frontend/src/themes/facelift/images/icon_search_action_light.svg'); + --icon-load-graph: url('~cmk-frontend/src/themes/facelift/images/load_graph.png'); } @layer theme { @@ -42,25 +49,35 @@ /* Icons */ --icon-main-help: url('~cmk-frontend/src/themes/facelift/images/icon_main_help.svg'); --icon-select-arrow: url('~cmk-frontend/src/themes/facelift/images/select_arrow.png'); + --icon-close: url('~cmk-frontend/src/themes/facelift/images/icon_close.svg'); /* Colors */ --default-submit-button-border-color: var(--success-dimmed); --default-border-color: rgb(234 234 234); + --default-background-color: rgb(249, 249, 255); --default-table-th-color: rgb(232 232 238); --default-select-background-color: rgb(224, 224, 228); --default-select-hover-color: var(--success); + --default-border-color-green: rgb(21, 209, 160); + --default-text-color: rgb(39, 39, 39); + --default-component-background-color: rgb(240, 240, 240); } body[data-theme='modern-dark'] { /* Icons */ --icon-main-help: url('~cmk-frontend/src/themes/modern-dark/images/icon_main_help.svg'); --icon-select-arrow: url('~cmk-frontend/src/themes/modern-dark/images/select_arrow.png'); + --icon-close: url('~cmk-frontend/src/themes/modern-dark/images/icon_close.svg'); /* Colors */ --default-submit-button-border-color: rgb(8 94 61); --default-border-color: rgb(38 45 52); + --default-background-color: rgb(28, 34, 40); --default-table-th-color: rgb(32, 39, 46); --default-select-background-color: rgb(48, 57, 70); --default-select-hover-color: var(--success); + --default-border-color-green: rgb(21, 209, 160); + --default-text-color: rgb(255, 255, 255); + --default-component-background-color: rgb(46, 44, 44); } } diff --git a/packages/cmk-frontend-vue/src/quick-setup/components/AlertBox.vue b/packages/cmk-frontend-vue/src/components/AlertBox.vue similarity index 81% rename from packages/cmk-frontend-vue/src/quick-setup/components/AlertBox.vue rename to packages/cmk-frontend-vue/src/components/AlertBox.vue index fed1a7044f0..bbde53f45b1 100644 --- a/packages/cmk-frontend-vue/src/quick-setup/components/AlertBox.vue +++ b/packages/cmk-frontend-vue/src/components/AlertBox.vue @@ -5,6 +5,7 @@ conditions defined in the file COPYING, which is part of this source code packag --> + + + + diff --git a/packages/cmk-frontend-vue/src/components/FormEditAsync.vue b/packages/cmk-frontend-vue/src/components/FormEditAsync.vue new file mode 100644 index 00000000000..baed925fb8e --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/FormEditAsync.vue @@ -0,0 +1,124 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/quick-setup/components/IconButton.vue b/packages/cmk-frontend-vue/src/components/IconButton.vue similarity index 62% rename from packages/cmk-frontend-vue/src/quick-setup/components/IconButton.vue rename to packages/cmk-frontend-vue/src/components/IconButton.vue index c70f956b7d6..2be8c421fda 100644 --- a/packages/cmk-frontend-vue/src/quick-setup/components/IconButton.vue +++ b/packages/cmk-frontend-vue/src/components/IconButton.vue @@ -5,9 +5,7 @@ conditions defined in the file COPYING, which is part of this source code packag --> diff --git a/packages/cmk-frontend-vue/src/components/IconElement.vue b/packages/cmk-frontend-vue/src/components/IconElement.vue new file mode 100644 index 00000000000..378c0e3076d --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/IconElement.vue @@ -0,0 +1,98 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/SimpleButton.vue b/packages/cmk-frontend-vue/src/components/SimpleButton.vue new file mode 100644 index 00000000000..6daacb9e7b3 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/SimpleButton.vue @@ -0,0 +1,25 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/ToggleButtonGroup.vue b/packages/cmk-frontend-vue/src/components/ToggleButtonGroup.vue new file mode 100644 index 00000000000..6473f4aff59 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/ToggleButtonGroup.vue @@ -0,0 +1,61 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoAlertBox.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoAlertBox.vue new file mode 100644 index 00000000000..d94078ab1e1 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoAlertBox.vue @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoApp.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoApp.vue new file mode 100644 index 00000000000..06148ba7327 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoApp.vue @@ -0,0 +1,80 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoEmpty.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoEmpty.vue new file mode 100644 index 00000000000..4fcd7f784ef --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoEmpty.vue @@ -0,0 +1,13 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoFormEditAsync.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoFormEditAsync.vue new file mode 100644 index 00000000000..1672055211a --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoFormEditAsync.vue @@ -0,0 +1,155 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoIconButton.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoIconButton.vue new file mode 100644 index 00000000000..4ba68d96120 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoIconButton.vue @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoIconElement.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoIconElement.vue new file mode 100644 index 00000000000..8d9f989d413 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoIconElement.vue @@ -0,0 +1,67 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/DemoSlideIn.vue b/packages/cmk-frontend-vue/src/components/_demo/DemoSlideIn.vue new file mode 100644 index 00000000000..6cf9aa6e5a5 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/DemoSlideIn.vue @@ -0,0 +1,85 @@ + + + + + + + diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/button/index.ts b/packages/cmk-frontend-vue/src/components/_demo/assets/main.css similarity index 83% rename from packages/cmk-frontend-vue/src/quick-setup/ui/button/index.ts rename to packages/cmk-frontend-vue/src/components/_demo/assets/main.css index dd558631ecb..8ef489591fd 100644 --- a/packages/cmk-frontend-vue/src/quick-setup/ui/button/index.ts +++ b/packages/cmk-frontend-vue/src/components/_demo/assets/main.css @@ -3,4 +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. */ -export { default as Button } from './UiButton.vue' + +html { + font-family: sans-serif; +} diff --git a/packages/cmk-frontend-vue/src/components/_demo/index.html b/packages/cmk-frontend-vue/src/components/_demo/index.html new file mode 100644 index 00000000000..07b22490797 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/index.html @@ -0,0 +1,16 @@ + + + + + + + cmk-frontend-vue + + +
    + + + diff --git a/packages/cmk-frontend-vue/src/components/_demo/index.ts b/packages/cmk-frontend-vue/src/components/_demo/index.ts new file mode 100644 index 00000000000..1157cfe9604 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/index.ts @@ -0,0 +1,17 @@ +/** + * 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. + */ + +import './assets/main.css' +import '@/assets/variables.css' +import '~cmk-frontend/src/themes/facelift/theme.scss' + +import { createApp } from 'vue' +import DemoApp from './DemoApp.vue' +import router from './router' + +const app = createApp(DemoApp) +app.use(router) +app.mount('#app') diff --git a/packages/cmk-frontend-vue/src/components/_demo/router.ts b/packages/cmk-frontend-vue/src/components/_demo/router.ts new file mode 100644 index 00000000000..baaafe713b7 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/_demo/router.ts @@ -0,0 +1,52 @@ +/** + * 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. + */ + +import { createRouter, createWebHistory } from 'vue-router' + +import DemoEmpty from './DemoEmpty.vue' +import DemoAlertBox from './DemoAlertBox.vue' +import DemoIconButton from './DemoIconButton.vue' +import DemoSlideIn from './DemoSlideIn.vue' +import DemoFormEditAsync from './DemoFormEditAsync.vue' +import DemoIconElement from './DemoIconElement.vue' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'home', + component: DemoEmpty + }, + { + path: '/alertbox', + name: 'AlertBox', + component: DemoAlertBox + }, + { + path: '/iconbutton', + name: 'IconButton', + component: DemoIconButton + }, + { + path: '/slidein', + name: 'SlideIn', + component: DemoSlideIn + }, + { + path: '/formeditasync', + name: 'FormEditAsync', + component: DemoFormEditAsync + }, + { + path: '/iconelement', + name: 'IconElement', + component: DemoIconElement + } + ] +}) + +export default router diff --git a/packages/cmk-frontend-vue/src/components/slidein/SlideIn.vue b/packages/cmk-frontend-vue/src/components/slidein/SlideIn.vue new file mode 100644 index 00000000000..b1efa456987 --- /dev/null +++ b/packages/cmk-frontend-vue/src/components/slidein/SlideIn.vue @@ -0,0 +1,130 @@ + + + + + + diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/CollapsibleContent.vue b/packages/cmk-frontend-vue/src/components/ui/collapsible/CollapsibleContent.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/CollapsibleContent.vue rename to packages/cmk-frontend-vue/src/components/ui/collapsible/CollapsibleContent.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/CollapsibleTrigger.vue b/packages/cmk-frontend-vue/src/components/ui/collapsible/CollapsibleTrigger.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/CollapsibleTrigger.vue rename to packages/cmk-frontend-vue/src/components/ui/collapsible/CollapsibleTrigger.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/UiCollapsible.vue b/packages/cmk-frontend-vue/src/components/ui/collapsible/UiCollapsible.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/UiCollapsible.vue rename to packages/cmk-frontend-vue/src/components/ui/collapsible/UiCollapsible.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/index.ts b/packages/cmk-frontend-vue/src/components/ui/collapsible/index.ts similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/collapsible/index.ts rename to packages/cmk-frontend-vue/src/components/ui/collapsible/index.ts diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/label/UiLabel.vue b/packages/cmk-frontend-vue/src/components/ui/label/UiLabel.vue similarity index 84% rename from packages/cmk-frontend-vue/src/quick-setup/ui/label/UiLabel.vue rename to packages/cmk-frontend-vue/src/components/ui/label/UiLabel.vue index d2e499aa3bb..b4d364f9360 100644 --- a/packages/cmk-frontend-vue/src/quick-setup/ui/label/UiLabel.vue +++ b/packages/cmk-frontend-vue/src/components/ui/label/UiLabel.vue @@ -25,6 +25,7 @@ type LabelVariants = VariantProps const props = defineProps< LabelProps & { variant?: LabelVariants['variant'] + onClick?: (() => void) | null } >() @@ -38,7 +39,11 @@ const delegatedProps = computed(() => { @@ -58,5 +63,10 @@ label { font-size: var(--font-size-normal); margin-bottom: var(--spacing); } + + &.qs-ui-label--clickable { + cursor: pointer; + pointer-events: all; + } } diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/label/index.ts b/packages/cmk-frontend-vue/src/components/ui/label/index.ts similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/label/index.ts rename to packages/cmk-frontend-vue/src/components/ui/label/index.ts diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipContent.vue b/packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipContent.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipContent.vue rename to packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipContent.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipProvider.vue b/packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipProvider.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipProvider.vue rename to packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipProvider.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipTrigger.vue b/packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipTrigger.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/TooltipTrigger.vue rename to packages/cmk-frontend-vue/src/components/ui/tooltip/TooltipTrigger.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/UiTooltip.vue b/packages/cmk-frontend-vue/src/components/ui/tooltip/UiTooltip.vue similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/UiTooltip.vue rename to packages/cmk-frontend-vue/src/components/ui/tooltip/UiTooltip.vue diff --git a/packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/index.ts b/packages/cmk-frontend-vue/src/components/ui/tooltip/index.ts similarity index 100% rename from packages/cmk-frontend-vue/src/quick-setup/ui/tooltip/index.ts rename to packages/cmk-frontend-vue/src/components/ui/tooltip/index.ts diff --git a/packages/cmk-frontend-vue/src/form/FormApp.vue b/packages/cmk-frontend-vue/src/form/FormApp.vue index f9f2fdd5680..60a00e66167 100644 --- a/packages/cmk-frontend-vue/src/form/FormApp.vue +++ b/packages/cmk-frontend-vue/src/form/FormApp.vue @@ -54,33 +54,36 @@ function toggleActiveMode() { diff --git a/packages/cmk-frontend-vue/src/form/components/FormEdit.vue b/packages/cmk-frontend-vue/src/form/components/FormEdit.vue index 8b63797f70b..5630a76e0ac 100644 --- a/packages/cmk-frontend-vue/src/form/components/FormEdit.vue +++ b/packages/cmk-frontend-vue/src/form/components/FormEdit.vue @@ -22,13 +22,14 @@ import FormDataSize from '@/form/components/forms/FormDataSize.vue' import FormCatalog from '@/form/components/forms/FormCatalog.vue' import FormTimeSpan from '@/form/components/forms/FormTimeSpan.vue' import type { ValidationMessages } from '@/form/components/utils/validation' -import FormMultipleChoice from '@/form/components/forms/FormMultipleChoice.vue' +import FormDualListChoice from '@/form/components/forms/FormDualListChoice.vue' import FormPassword from './forms/FormPassword.vue' import FormTuple from '@/form/components/forms/FormTuple.vue' import FormOptionalChoice from '@/form/components/forms/FormOptionalChoice.vue' import FormSimplePassword from '@/form/components/forms/FormSimplePassword.vue' import FormCommentTextArea from './forms/FormCommentTextArea.vue' import FormListOfStrings from '@/form/components/forms/FormListOfStrings.vue' +import FormCheckboxListChoice from './forms/FormCheckboxListChoice.vue' const props = defineProps<{ spec: FormSpec @@ -52,7 +53,8 @@ const components: Record = { boolean_choice: FormBooleanChoice, multiline_text: FormMultilineText, comment_text_area: FormCommentTextArea, - multiple_choice: FormMultipleChoice, + dual_list_choice: FormDualListChoice, + checkbox_list_choice: FormCheckboxListChoice, password: FormPassword, data_size: FormDataSize, catalog: FormCatalog, diff --git a/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue b/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue index 50ff2f1356d..918c89f2617 100644 --- a/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue +++ b/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue @@ -17,11 +17,12 @@ import type { FixedValue, BooleanChoice, MultilineText, - MultipleChoice, Password, Tuple, OptionalChoice, - ListOfStrings + ListOfStrings, + DualListChoice, + CheckboxListChoice } from '@/form/components/vue_formspec_components' import { groupDictionaryValidations, @@ -71,8 +72,10 @@ function renderForm( return renderDataSize(value as [string, string]) case 'catalog': return h('div', 'Catalog does not support readonly') - case 'multiple_choice': - return renderMultipleChoice(formSpec as MultipleChoice, value as string[]) + case 'dual_list_choice': + return renderMultipleChoice(formSpec as DualListChoice, value as string[]) + case 'checkbox_list_choice': + return renderMultipleChoice(formSpec as CheckboxListChoice, value as string[]) case 'password': return renderPassword(formSpec as Password, value as (string | boolean)[]) case 'tuple': @@ -148,27 +151,35 @@ function renderTuple( return h('span', tupleResults) } -function renderMultipleChoice(formSpec: MultipleChoice, value: string[]): VNode { +function renderMultipleChoice( + formSpec: DualListChoice | CheckboxListChoice, + value: string[] +): VNode { let nameToTitle: Record = {} for (const element of formSpec.elements) { nameToTitle[element.name] = element.title } - const maxEntries = 10 - const textTokens: string[] = [] + const maxEntries = 5 + const textSpans: VNode[] = [] // WIP: no i18n... for (let [index, entry] of value.entries()) { if (index >= maxEntries) { break } - textTokens.push(nameToTitle[entry]!) + textSpans.push(h('span', nameToTitle[entry]!)) } - let infoText = textTokens.join(', ') if (value.length > maxEntries) { - infoText += ` and ${value.length - maxEntries} more` + textSpans.push( + h( + 'span', + { class: 'form-readonly__multiple-choice__max-entries' }, + ` and ${value.length - maxEntries} more` + ) + ) } - return h('div', infoText) + return h('div', { class: 'form-readonly__multiple-choice' }, textSpans) } function renderDataSize(value: [string, string]): VNode { @@ -192,7 +203,7 @@ function renderBooleanChoice(formSpec: BooleanChoice, value: boolean): VNode { function renderFixedValue(formSpec: FixedValue): VNode { let shownValue = formSpec.value - if (formSpec.label != null) { + if (formSpec.label !== null) { shownValue = formSpec.label } return h('div', shownValue as string) @@ -207,7 +218,7 @@ function renderDict( // Note: Dictionary validations are not shown const [, elementValidations] = groupDictionaryValidations(formSpec.elements, backendValidation) formSpec.elements.map((element) => { - if (value[element.ident] == undefined) { + if (value[element.ident] === undefined) { return } @@ -416,9 +427,31 @@ export default defineComponent({ diff --git a/packages/cmk-frontend-vue/src/form/components/FormValidation.vue b/packages/cmk-frontend-vue/src/form/components/FormValidation.vue index 72f826b7ff2..8710854f095 100644 --- a/packages/cmk-frontend-vue/src/form/components/FormValidation.vue +++ b/packages/cmk-frontend-vue/src/form/components/FormValidation.vue @@ -4,6 +4,8 @@ This file is part of Checkmk (https://checkmk.com). It is subject to the terms a conditions defined in the file COPYING, which is part of this source code package. -->