Skip to content

Commit f65b8ae

Browse files
authored
Merge pull request #86 from atlassian/HEIMDALL-12205-when-zabbix-alert-is-acknowledged-the-jsm-alert-is-not-acknowledged
Added support for new authorization method for Zabbix 7
2 parents 0157603 + e72b71e commit f65b8ae

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import argparse
2+
import json
3+
import logging
4+
import sys
5+
6+
import requests
7+
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument('-payload', '--queuePayload', help='Payload from queue', required=True)
10+
parser.add_argument('-apiKey', '--apiKey', help='The apiKey of the integration', required=True)
11+
parser.add_argument('-jsmUrl', '--jsmUrl', help='The url', required=True)
12+
parser.add_argument('-logLevel', '--logLevel', help='Log level', required=True)
13+
parser.add_argument('-command_url', '--command_url', help='The Command URL', required=False)
14+
parser.add_argument('-user', '--user', help='User', required=False)
15+
parser.add_argument('-password', '--password', help='Password', required=False)
16+
args, unknown = parser.parse_known_args()
17+
args = vars(args)
18+
19+
logging.basicConfig(stream=sys.stdout, level=args['logLevel'])
20+
21+
22+
def parse_field(key, mandatory):
23+
variable = queue_message.get(key)
24+
if not variable:
25+
variable = args.get(key)
26+
if mandatory and not variable:
27+
logging.error(LOG_PREFIX + " Skipping action, Mandatory conf item '" + str(key) +
28+
"' is missing. Check your configuration file.")
29+
raise ValueError(LOG_PREFIX + " Skipping action, Mandatory conf item '" + str(key) +
30+
"' is missing. Check your configuration file.")
31+
return variable
32+
33+
34+
def parse_timeout():
35+
parsed_timeout = args.get('http.timeout')
36+
if not parsed_timeout:
37+
return 30000
38+
return int(parsed_timeout)
39+
40+
41+
def login_to_zabbix(user, password, url):
42+
login_params = {
43+
"jsonrpc": "2.0",
44+
"method": "user.login",
45+
"params": {
46+
"username": user,
47+
"password": password
48+
},
49+
"id": 1
50+
}
51+
logging.debug(LOG_PREFIX + " Logging in to Zabbix. Url: " + str(url) + " user: " + str(user))
52+
content_headers = {
53+
"Content-Type": "application/json"
54+
}
55+
login_result = requests.post(url, data=json.dumps(login_params), headers=content_headers, timeout=timeout)
56+
logging.debug(LOG_PREFIX + " login response: " + str(login_result.status_code) + " " + str(login_result.json()))
57+
if login_result.json() and not login_result.json().get('error'):
58+
return login_result.json()['result']
59+
else:
60+
logging.error(
61+
LOG_PREFIX + " Cannot login to Zabbix: Response " + str(login_result.status_code) + " " + str(login_result.content))
62+
63+
64+
def main():
65+
global LOG_PREFIX
66+
global queue_message
67+
global timeout
68+
69+
queue_message_string = args['queuePayload']
70+
queue_message = json.loads(queue_message_string)
71+
72+
alert_id = queue_message["alert"]["alertId"]
73+
action = queue_message["action"]
74+
source = queue_message["source"]
75+
76+
LOG_PREFIX = "[" + action + "]"
77+
78+
timeout = parse_timeout()
79+
80+
logging.info("Will execute " + str(action) + " for alertId " + str(alert_id))
81+
82+
username = parse_field('user', True)
83+
password = parse_field('password', True)
84+
url = parse_field('command_url', True)
85+
86+
logging.debug("Username: " + str(username))
87+
logging.debug("Command Url: " + str(url))
88+
logging.debug("AlertId: " + str(alert_id))
89+
logging.debug("Source: " + str(source))
90+
logging.debug("Action: " + str(action))
91+
92+
if alert_id:
93+
alert_api_url = args['jsmUrl'] + "/jsm/ops/integration/v2/alerts/" + alert_id
94+
headers = {
95+
"Content-Type": "application/json",
96+
"Accept-Language": "application/json",
97+
"Authorization": "GenieKey " + args['apiKey']
98+
}
99+
alert_response = requests.get(alert_api_url, headers=headers, timeout=timeout)
100+
if alert_response.status_code < 299 and alert_response.json()['data']:
101+
if action == "Acknowledge":
102+
if source and str(source['name']).lower() == "zabbix":
103+
logging.warning("JSM alert is already acknowledged by Zabbix. Discarding!!!")
104+
else:
105+
post_params = {
106+
"jsonrpc": "2.0",
107+
"id": 1,
108+
"method": "event.acknowledge",
109+
"params": {
110+
"eventids": parse_from_details("eventId", alert_response),
111+
"message": "Acknowledged by " + alert_response.json()['data']['report'][
112+
'acknowledgedBy'] + " via JSM",
113+
"action": 6
114+
}
115+
}
116+
auth = login_to_zabbix(username, password, url)
117+
if auth:
118+
logging.debug("Posting to Zabbix. Url: " + str(url) + ", params: " + str(post_params))
119+
headers = {
120+
"Content-Type": "application/json",
121+
"Authorization": "Bearer " + auth,
122+
}
123+
response = requests.post(url, data=json.dumps(post_params), headers=headers, timeout=timeout)
124+
if alert_response.json() and not alert_response.json().get('error'):
125+
logging.info("Successfully executed at Zabbix.")
126+
logging.debug("Zabbix response: " + str(response.json()))
127+
else:
128+
logging.warning(
129+
"Could not execute at Zabbix. Zabbix Response: " + response.content + " Status Code: " + response.status_code)
130+
else:
131+
logging.warning(LOG_PREFIX + "Cannot login to Zabbix!")
132+
else:
133+
logging.warning("Alert with id [" + str(alert_id) + "] does not exist in JSM. It is probably deleted.")
134+
else:
135+
logging.warning("Alert id does not exist ")
136+
137+
def parse_from_details(key,alert_response):
138+
if key in alert_response.json()['data']["details"].keys():
139+
return alert_response.json()['data']["details"][key]
140+
return ""
141+
142+
if __name__ == '__main__':
143+
main()

0 commit comments

Comments
 (0)