-
Notifications
You must be signed in to change notification settings - Fork 1
/
checkmk_matrix_notification.py
164 lines (138 loc) · 4.78 KB
/
checkmk_matrix_notification.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/python3
# Matrix
# Matrix notification script from @beposec inspired by:
# Telegram_Notification from Stefan Gehn [email protected]
# check_mk_matrix_notifications from Stanislav N. aka pztrn
# Tested with Checkmk 2.0.0p17 on Debian Bullseye.
import os
import json
import re
import sys
import string
import urllib
import urllib.request
import urllib.parse
import random
import ssl
#################################################################
# Configure Matrix Connection here:
MATRIXHOST = ''
MATRIXTOKEN = ''
#################################################################
# Room id is set by Checkmk notification rule parameter
MATRIXROOM = os.environ["NOTIFY_PARAMETER_1"]
#################################################################
# Setup context for ssl certificate validation
sslverify = ssl.create_default_context(capath="/etc/ssl/certs/")
# Prepare Message Template for Host Notifications
tmpl_host_text = """<b>Check_MK: $HOSTNAME$ - $EVENT_TXT$</b>
<pre><code>Host: $HOSTNAME$
Alias: $HOSTALIAS$
Address: $HOSTADDRESS$
Event: $EVENT_TXT$
Output: $LONGHOSTOUTPUT$
Comment: $NOTIFICATIONCOMMENT$
</code></pre>\n
"""
# Prepare Message Template for Service Notifications
tmpl_service_text = """<b>Check_MK: $HOSTNAME$/$SERVICEDESC$ $EVENT_TXT$</b>
<pre><code>Host: $HOSTNAME$
Alias: $HOSTALIAS$
Address: $HOSTADDRESS$
Service: $SERVICEDESC$
Event: $EVENT_TXT$
Output: $LONGSERVICEOUTPUT$
Comment: $NOTIFICATIONCOMMENT$
</code></pre>\n
"""
def validate_room_id(MATRIXROOM):
# Validation of given room id
room_id_pattern = (r"(![a-zA-Z]+):(([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,})")
if not re.match(room_id_pattern, MATRIXROOM):
sys.exit(
"The given value '%s' is not a proper [matrix] room id."
% MATRIXROOM
)
def substitute_context(template, context):
# Replace all known variables
for varname, value in context.items():
template = template.replace('$'+varname+'$', value)
# Remove unused variables and make them empty
template = re.sub(r"\$[A-Z_][A-Z_0-9]*\$", "", template)
return template
def construct_message_text(context):
notification_type = context["NOTIFICATIONTYPE"]
if notification_type in ["PROBLEM", "RECOVERY"]:
txt_info = "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$"
elif notification_type.startswith("FLAP"):
if "START" in notification_type:
txt_info = "Started Flapping"
else:
txt_info = "Stopped Flapping ($@SHORTSTATE$)"
elif notification_type.startswith("DOWNTIME"):
what = notification_type[8:].title()
txt_info = "Downtime " + what + " ($@SHORTSTATE$)"
elif notification_type == "ACKNOWLEDGEMENT":
txt_info = "Acknowledged ($@SHORTSTATE$)"
elif notification_type == "CUSTOM":
txt_info = "Custom Notification ($@SHORTSTATE$)"
else:
txt_info = notification_type # Should neven happen
txt_info = substitute_context(
txt_info.replace("@", context["WHAT"]),
context
)
context["EVENT_TXT"] = txt_info
if context['WHAT'] == 'HOST':
tmpl_text = tmpl_host_text
else:
tmpl_text = tmpl_service_text
return substitute_context(tmpl_text, context)
def fetch_notification_context():
context = {}
for (var, value) in os.environ.items():
if var.startswith("NOTIFY_"):
context[var[7:]] = value
return context
def send_matrix_message(text):
# Build Matrix Message
matrixDataDict = {
"msgtype": "m.text",
"body": text,
"format": "org.matrix.custom.html",
"formatted_body": text,
}
matrixData = json.dumps(matrixDataDict)
matrixData = matrixData.encode("utf-8")
# Create random transaction ID for Matrix Homeserver
txnId = ''.join(random.SystemRandom().choice(
string.ascii_uppercase + string.digits) for _ in range(16))
# Authorization headers and etc.
matrixHeaders = {"Authorization": "Bearer " + MATRIXTOKEN,
"Content-Type": "application/json",
"Content-Length": str(len(matrixData))}
# Request
url = MATRIXHOST \
+ "/_matrix/client/r0/rooms/" \
+ MATRIXROOM \
+ "/send/m.room.message/" \
+ txnId
req = urllib.request.Request(
url,
data=matrixData,
headers=matrixHeaders,
method='PUT'
)
try:
response = urllib.request.urlopen(req, context=sslverify)
except urllib.error.URLError as e:
sys.stdout.write(
'Cannot send to matrix room: HTTP-Error %s %s\n' % (e.reason, e)
)
def main():
validate_room_id(MATRIXROOM)
context = fetch_notification_context()
text = construct_message_text(context)
send_matrix_message(text)
if __name__ == '__main__':
main()