Skip to content

Commit bcf908a

Browse files
committed
17280 FIX Grouping of services in table views
Grouping services in table views did not previously work as expected. With [Werk 15494](https://checkmk.com/werk/15494), a new service grouping feature was introduced that did not work as expected in certain situations after [Werk 15550](https://checkmk.com/werk/15550) fixed a crash related to service grouping. Another issue fixed with [Werk 17278](https://checkmk.com/werk/15494) partially broke the feature even more. The original feature also had a bug where when using non-matching groups, the group title would be displayed incorrectly, in specific situations. All of the above are now fixed and the original feature is restored and working again. SUP-19435 Change-Id: I86ffd5845957dc4b4a51733cac19499d50a897f0
1 parent bb05f5f commit bcf908a

3 files changed

Lines changed: 161 additions & 13 deletions

File tree

.werks/17280.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[//]: # (werk v2)
2+
# Grouping of services in table views
3+
4+
key | value
5+
---------- | ---
6+
date | 2025-02-07T06:32:29+00:00
7+
version | 2.4.0b1
8+
class | fix
9+
edition | cre
10+
component | multisite
11+
level | 1
12+
compatible | yes
13+
14+
Grouping services in table views did not previously work as expected.
15+
16+
With [Werk 15494](https://checkmk.com/werk/15494), a new service grouping
17+
feature was introduced that did not work as expected in certain situations after
18+
[Werk 15550](https://checkmk.com/werk/15550) fixed a crash related to
19+
service grouping.
20+
21+
Another issue fixed with [Werk 17278](https://checkmk.com/werk/15494) partially
22+
broke the feature even more.
23+
24+
The original feature also had a bug where when using non-matching
25+
groups, the group title would be displayed incorrectly, in specific situations.
26+
27+
All of the above are now fixed and the original feature is restored and
28+
working again.

cmk/gui/views/layout/layouts.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
from cmk.ccc.exceptions import MKGeneralException
1313

14-
from cmk.utils.regex import escape_regex_chars
15-
1614
from cmk.gui import utils
1715
from cmk.gui.config import active_config
1816
from cmk.gui.data_source import row_id
@@ -404,22 +402,26 @@ def calculate_view_grouping_of_services(
404402
return groupings, rows_with_ids
405403

406404

405+
def get_group_spec(group_spec: GroupSpec, service_name: str) -> GroupSpec:
406+
if re.findall(r"\\\d", group_spec["title"]):
407+
return GroupSpec(
408+
title=re.sub(
409+
pattern=group_spec["pattern"],
410+
repl=group_spec["title"],
411+
string=service_name,
412+
),
413+
pattern=group_spec["pattern"],
414+
min_items=group_spec["min_items"],
415+
)
416+
return group_spec
417+
418+
407419
def try_to_match_group(row: Row) -> GroupSpec | None:
408420
for group_spec in active_config.service_view_grouping:
409421
if row.get("service_description") and re.match(
410422
group_spec["pattern"], row["service_description"]
411423
):
412-
if re.findall(r"(\([^)]*\))", group_spec["pattern"]):
413-
return GroupSpec(
414-
title=re.sub(
415-
group_spec["pattern"],
416-
escape_regex_chars(group_spec["title"]),
417-
row["service_description"],
418-
),
419-
pattern=group_spec["pattern"],
420-
min_items=group_spec["min_items"],
421-
)
422-
return group_spec
424+
return get_group_spec(group_spec, row["service_description"])
423425

424426
return None
425427

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env python3
2+
# Copyright (C) 2025 Checkmk GmbH - License: GNU General Public License v2
3+
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
4+
# conditions defined in the file COPYING, which is part of this source code package.
5+
6+
import pytest
7+
8+
from cmk.gui.type_defs import GroupSpec
9+
from cmk.gui.views.layout.layouts import get_group_spec
10+
11+
12+
@pytest.mark.parametrize(
13+
"group_spec, expected_group_spec, service_name",
14+
[
15+
pytest.param(
16+
GroupSpec(
17+
title="Hardware",
18+
pattern="(?i:cpu)|(?i:interface).*",
19+
min_items=2,
20+
),
21+
GroupSpec(
22+
title="Hardware",
23+
pattern="(?i:cpu)|(?i:interface).*",
24+
min_items=2,
25+
),
26+
"Interface 1",
27+
id="non-capturing groups case 1 (SUP-19435)",
28+
),
29+
pytest.param(
30+
GroupSpec(
31+
title="Hardware",
32+
pattern="(?i:cpu)|(?i:interface).*",
33+
min_items=2,
34+
),
35+
GroupSpec(
36+
title="Hardware",
37+
pattern="(?i:cpu)|(?i:interface).*",
38+
min_items=2,
39+
),
40+
"CPU load",
41+
id="non-capturing groups case 2 (SUP-19435)",
42+
),
43+
pytest.param(
44+
GroupSpec(
45+
title="CPU",
46+
pattern="(?!.*(CPU)).*",
47+
min_items=2,
48+
),
49+
GroupSpec(
50+
title="CPU",
51+
pattern="(?!.*(CPU)).*",
52+
min_items=2,
53+
),
54+
"CPU load",
55+
id="non-capturing groups case 3 (SUP-21609)",
56+
),
57+
pytest.param(
58+
GroupSpec(
59+
title=r"Oracle instance \1",
60+
pattern="ORA ([A-Za-z0-9]+).*",
61+
min_items=2,
62+
),
63+
GroupSpec(
64+
title="Oracle instance 1337",
65+
pattern="ORA ([A-Za-z0-9]+).*",
66+
min_items=2,
67+
),
68+
"ORA 1337",
69+
id="match group replacement (SUP-13124)",
70+
),
71+
pytest.param(
72+
GroupSpec(
73+
title="LocalChecks",
74+
pattern="local_",
75+
min_items=2,
76+
),
77+
GroupSpec(
78+
title="LocalChecks",
79+
pattern="local_",
80+
min_items=2,
81+
),
82+
r"local_\PTest",
83+
id=r"Bad escape \P (SUP-14585)",
84+
),
85+
pytest.param(
86+
GroupSpec(
87+
title=r"LocalChecks \1",
88+
pattern="local_(.*)",
89+
min_items=2,
90+
),
91+
GroupSpec(
92+
title=r"LocalChecks \PTest",
93+
pattern="local_(.*)",
94+
min_items=2,
95+
),
96+
r"local_\PTest",
97+
id=r"Bad escape \P (SUP-14585)",
98+
),
99+
pytest.param(
100+
GroupSpec(
101+
title=r"Foo \1 Bar \2",
102+
pattern=r"my_(\d+)_services_(\d+)",
103+
min_items=2,
104+
),
105+
GroupSpec(
106+
title=r"Foo 10 Bar 20",
107+
pattern=r"my_(\d+)_services_(\d+)",
108+
min_items=2,
109+
),
110+
"my_10_services_20",
111+
id="two match groups replacement",
112+
),
113+
],
114+
)
115+
def test_get_group_spec(
116+
group_spec: GroupSpec, expected_group_spec: GroupSpec, service_name: str
117+
) -> None:
118+
assert get_group_spec(group_spec, service_name) == expected_group_spec

0 commit comments

Comments
 (0)