Skip to content

Commit ff0e038

Browse files
kbuettnerDavidGerva
authored andcommitted
18264 netapp_ontap_status: respect alert's suppression and acknowledgement
CMK-23741 Closes: #820 Change-Id: I3d00eef0f649b25edf502e2dee960bb4309c8581
1 parent 15e0eb5 commit ff0e038

4 files changed

Lines changed: 104 additions & 10 deletions

File tree

.werks/18264.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[//]: # (werk v2)
2+
# netapp_ontap_status: respect alert's suppression and acknowledgement
3+
4+
key | value
5+
---------- | ---
6+
date | 2025-07-30T19:48:26+00:00
7+
version | 2.4.0p36
8+
class | feature
9+
edition | cre
10+
component | checks
11+
level | 1
12+
compatible | yes
13+
14+
This werk impacts those who monitor NetApp ONTAP systems.
15+
16+
The Diagnosis Status service (netapp_ontap_status)
17+
was critical if at least one alert was present, regardless of its suppress or acknowledge status.
18+
19+
This change modifies the mentioned service
20+
to consider alerts that are either acknowledged or suppressed on the NetApp side as OK.
21+
The service details will now also include the status of each alert
22+
(suppressed or acknowledged, if applicable) and the name of the suppressor or acknowledger.
23+
24+
Credits for this change go to GitHub user @kbuettner.

cmk/plugins/netapp/agent_based/netapp_ontap_status.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929
# }
3030

3131

32+
def format_alert(alert):
33+
s = alert.name
34+
if alert.acknowledge:
35+
s += f", acknowledged by {alert.acknowledger}"
36+
if alert.suppress:
37+
s += f", suppressed by {alert.suppressor}"
38+
return s
39+
40+
3241
def parse_netapp_api_status(string_table: StringTable) -> Section:
3342
return [
3443
alert for line in string_table for alert in [models.AlertModel.model_validate_json(line[0])]
@@ -46,14 +55,25 @@ def discovery_netapp_ontap_status(section: Section) -> DiscoveryResult:
4655

4756

4857
def check_netapp_ontap_status(section: Section) -> CheckResult:
49-
"""
50-
Status is considered OK if there are no alerts
51-
"""
52-
5358
if not section:
54-
yield Result(state=State.OK, summary="Status: OK")
59+
yield Result(state=State.OK, summary="No alerts present")
60+
return
61+
62+
handled_alerts = [alert for alert in section if alert.acknowledge or alert.suppress]
63+
unhandled_alerts = [alert for alert in section if alert not in handled_alerts]
64+
# show the unhandled alerts first
65+
details = "\n".join(format_alert(alert) for alert in unhandled_alerts + handled_alerts)
66+
67+
if unhandled_alerts:
68+
yield Result(
69+
state=State.CRIT, summary="Unhandled alerts present, see details", details=details
70+
)
5571
else:
56-
yield Result(state=State.CRIT, summary="Status: Alerts present")
72+
yield Result(
73+
state=State.OK,
74+
summary="Alerts present, but all acknowledged or suppressed, see details",
75+
details=details,
76+
)
5777

5878

5979
check_plugin_netapp_ontap_status = CheckPlugin(

cmk/plugins/netapp/models.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,15 @@ class ShelfPsuModel(ShelfObjectModel):
581581

582582
class AlertModel(BaseModel):
583583
"""
584-
cfr: https://docs.netapp.com/us-en/ontap-restmap-9141//diagnosis.html#diagnosis-alert-get
584+
https://docs.netapp.com/us-en/ontap-restmap-9141//diagnosis.html#diagnosis-alert-get
585585
"""
586586

587587
name: str
588+
# this fields should always be present since ONTAP v 9.8 but better be safe than sorry...
589+
acknowledge: bool = False
590+
acknowledger: str = ""
591+
suppress: bool = False
592+
suppressor: str = ""
588593

589594

590595
class NtpPeerStatusModel(BaseModel):

tests/unit/cmk/plugins/netapp/test_netapp_ontap_status.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,60 @@ class AlertModelFactory(ModelFactory):
2121
"alerts_models, expected_result",
2222
[
2323
pytest.param(
24-
[AlertModelFactory.build(name="alert1"), AlertModelFactory.build(name="alert2")],
25-
[Result(state=State.CRIT, summary="Status: Alerts present")],
24+
[
25+
AlertModelFactory.build(name="alert1", acknowledge=False, suppress=False),
26+
AlertModelFactory.build(name="alert2", acknowledge=False, suppress=False),
27+
],
28+
[
29+
Result(
30+
state=State.CRIT,
31+
summary="Unhandled alerts present, see details",
32+
details="alert1\nalert2",
33+
)
34+
],
2635
id="alerts present",
2736
),
2837
pytest.param(
2938
[],
30-
[Result(state=State.OK, summary="Status: OK")],
39+
[Result(state=State.OK, summary="No alerts present")],
3140
id="no alerts present",
3241
),
42+
pytest.param(
43+
[
44+
AlertModelFactory.build(
45+
name="alert1", acknowledge=True, acknowledger="hhirsch", suppress=False
46+
),
47+
AlertModelFactory.build(
48+
name="alert2", acknowledge=False, suppress=True, suppressor="hhirsch"
49+
),
50+
],
51+
[
52+
Result(
53+
state=State.OK,
54+
summary="Alerts present, but all acknowledged or suppressed, see details",
55+
details="alert1, acknowledged by hhirsch\nalert2, suppressed by hhirsch",
56+
)
57+
],
58+
id="alerts suppressed",
59+
),
60+
pytest.param(
61+
[
62+
AlertModelFactory.build(
63+
name="alert2", acknowledge=False, suppress=True, suppressor="hhirsch"
64+
),
65+
AlertModelFactory.build(
66+
name="alert1", acknowledge=False, acknowledger="hhirsch", suppress=False
67+
),
68+
],
69+
[
70+
Result(
71+
state=State.CRIT,
72+
summary="Unhandled alerts present, see details",
73+
details="alert1\nalert2, suppressed by hhirsch",
74+
)
75+
],
76+
id="one alert not suppressed (show it first)",
77+
),
3378
],
3479
)
3580
def test_check_netapp_ontap_status(

0 commit comments

Comments
 (0)