Skip to content

Commit bf65e6e

Browse files
committed
Properly parse translation options
... and fix the lying type annotations. Change-Id: I64d4f185e4e5959fba1a9aabf11a0ab4f02155c5
1 parent 304e105 commit bf65e6e

4 files changed

Lines changed: 38 additions & 26 deletions

File tree

cmk/base/config.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,7 @@ class LoadedConfigFragment:
568568
checkgroup_parameters: Mapping[str, Sequence[RuleSpec[Mapping[str, object]]]]
569569
service_rule_groups: set[str]
570570
service_descriptions: Mapping[str, str]
571-
service_description_translation: Sequence[
572-
RuleSpec[cmk.utils.translations.TranslationOptionsSpec]
573-
]
571+
service_description_translation: Sequence[RuleSpec[Mapping[str, object]]]
574572
use_new_descriptions_for: Container[str]
575573
monitoring_core: Literal["nagios", "cmc"]
576574
nagios_illegal_chars: str
@@ -1264,11 +1262,9 @@ def get_piggyback_translations(
12641262
matcher: RulesetMatcher, labels_of_host: Callable[[HostName], Labels], hostname: HostName
12651263
) -> cmk.utils.translations.TranslationOptions:
12661264
"""Get a dict that specifies the actions to be done during the hostname translation"""
1267-
rules = matcher.get_host_values_all(hostname, piggyback_translation, labels_of_host)
1268-
translations: cmk.utils.translations.TranslationOptions = {}
1269-
for rule in rules[::-1]:
1270-
translations.update(rule)
1271-
return translations
1265+
return cmk.utils.translations.parse_translation_options(
1266+
matcher.get_host_values_merged(hostname, piggyback_translation, labels_of_host)
1267+
)
12721268

12731269

12741270
def get_http_proxy(http_proxy: tuple[str, str]) -> HTTPProxyConfig:

cmk/base/configlib/servicename.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
from cmk.utils.rulesets.ruleset_matcher import RulesetMatcher, RuleSpec
1515
from cmk.utils.servicename import Item, ServiceName
1616
from cmk.utils.translations import (
17+
parse_translation_options,
1718
translate_service_description,
1819
TranslationOptions,
19-
TranslationOptionsSpec,
2020
)
2121

2222

@@ -25,7 +25,7 @@ def __init__(
2525
self,
2626
matcher: RulesetMatcher,
2727
illegal_chars: str,
28-
translations: Sequence[RuleSpec[TranslationOptionsSpec]],
28+
translations: Sequence[RuleSpec[Mapping[str, object]]],
2929
) -> None:
3030
self.matcher: Final = matcher
3131
self.illegal_chars: Final = illegal_chars
@@ -66,20 +66,15 @@ def _get_service_translations(
6666
return translations_cache[hostname]
6767

6868
rules = self.matcher.get_host_values_all(hostname, self.translations, labels_of_host)
69-
translations: TranslationOptions = {}
69+
merged = TranslationOptions(case=None, drop_domain=False, regex=[], mapping=[])
7070
for rule in rules[::-1]:
71-
if "case" in rule:
72-
translations["case"] = rule["case"]
73-
if "regex" in rule:
74-
translations["regex"] = list(
75-
set(translations.get("regex", [])) | set(rule["regex"])
76-
)
77-
if "mapping" in rule:
78-
translations["mapping"] = list(
79-
set(translations.get("mapping", [])) | set(rule["mapping"])
80-
)
71+
parsed_rule = parse_translation_options(rule)
72+
if "case" in rule: # inheritence! Don't check for "case" in parsed_rule!
73+
merged["case"] = parsed_rule["case"]
74+
merged["regex"] = list(set(merged["regex"]) | set(parsed_rule["regex"]))
75+
merged["mapping"] = list(set(merged["mapping"]) | set(parsed_rule["mapping"]))
8176

82-
return translations_cache.setdefault(hostname, translations)
77+
return translations_cache.setdefault(hostname, parse_translation_options(merged))
8378

8479

8580
class PassiveServiceNameConfig:

cmk/base/default_config/base.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from cmk.utils.structured_data import RawIntervalFromConfig
2222
from cmk.utils.tags import TagConfigSpec
2323
from cmk.utils.timeperiod import TimeperiodSpecs
24-
from cmk.utils.translations import TranslationOptions, TranslationOptionsSpec
2524

2625
# This file contains the defaults settings for almost all configuration
2726
# variables that can be overridden in main.mk. Some configuration
@@ -58,9 +57,9 @@
5857
cluster_max_cachefile_age = 90 # secs.
5958
piggyback_max_cachefile_age = 3600 # secs
6059
# Ruleset for translating piggyback host names
61-
piggyback_translation: list[RuleSpec[TranslationOptions]] = []
60+
piggyback_translation: Sequence[RuleSpec[Mapping[str, object]]] = []
6261
# Ruleset for translating service names
63-
service_description_translation: list[RuleSpec[TranslationOptionsSpec]] = []
62+
service_description_translation: Sequence[RuleSpec[Mapping[str, object]]] = []
6463
simulation_mode = False
6564
fake_dns: str | None = None
6665
perfdata_format: Literal["pnp", "standard"] = "pnp"

cmk/utils/translations.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# conditions defined in the file COPYING, which is part of this source code package.
55

66
import ipaddress
7-
from collections.abc import Iterable
7+
from collections.abc import Iterable, Mapping
88
from typing import cast, Literal, NotRequired, TypedDict
99

1010
from cmk.ccc.hostaddress import HostName
@@ -21,6 +21,28 @@ class TranslationOptions(TypedDict, total=False):
2121
regex: Iterable[tuple[str, str]]
2222

2323

24+
def _parse_case(raw_case: object) -> Literal["lower", "upper"] | None:
25+
match raw_case:
26+
case "lower" | "upper" | None as case_value:
27+
return case_value
28+
raise (ValueError if isinstance(raw_case, str) else TypeError)(raw_case)
29+
30+
31+
def _parse_list_of_tuples(raw: object) -> Iterable[tuple[str, str]]:
32+
if not isinstance(raw, Iterable):
33+
raise TypeError(raw)
34+
return [(str(a), str(b)) for a, b in raw]
35+
36+
37+
def parse_translation_options(raw: Mapping[str, object]) -> TranslationOptions:
38+
return TranslationOptions(
39+
case=_parse_case(raw.get("case")),
40+
drop_domain=bool(raw.get("drop_domain")),
41+
mapping=_parse_list_of_tuples(raw.get("mapping", [])),
42+
regex=_parse_list_of_tuples(raw.get("regex", [])),
43+
)
44+
45+
2446
# Similar to TranslationOptions, but not the same. This aims to
2547
# cover exactly the structure that is configured with the valuespec.
2648
class TranslationOptionsSpec(TypedDict):

0 commit comments

Comments
 (0)