Skip to content

Commit 0ce6a94

Browse files
committed
Add webhook mediatype for Zabbix 6.0 or higher
1 parent 5dfbc6f commit 0ce6a94

File tree

9 files changed

+405
-64
lines changed

9 files changed

+405
-64
lines changed

.circleci/config.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ executors:
2222
default: latest
2323
docker:
2424
- image: circleci/ruby:2.7.2-buster
25-
- image: mysql:5.7
25+
- image: mysql:<< parameters.mysql_tag >>
2626
environment:
2727
MYSQL_DATABASE: zabbix
2828
MYSQL_USER: zabbix
@@ -43,6 +43,7 @@ jobs:
4343
integration_test_with_zabbix_32:
4444
executor:
4545
name: zabbix
46+
mysql_tag: 5.7
4647
tag: ubuntu-3.2-latest
4748
working_directory: ~/repo
4849
environment:
@@ -53,13 +54,27 @@ jobs:
5354
integration_test_with_zabbix_40:
5455
executor:
5556
name: zabbix
57+
mysql_tag: 5.7
5658
tag: ubuntu-4.0-latest
5759
working_directory: ~/repo
5860
environment:
5961
ZABBIX_API: http://localhost:8080/
6062
steps:
6163
- integration_test_with_zabbix
6264

65+
integration_test_with_zabbix_60:
66+
executor:
67+
name: zabbix
68+
mysql_tag: 8.2
69+
tag: ubuntu-6.0-latest
70+
working_directory: ~/repo
71+
environment:
72+
ZABBIX_API: http://localhost:8080/
73+
ZABBIX_USER: Admin
74+
ZABBIX_DISPATCHER_MEDIA_TYPE: webhook
75+
steps:
76+
- integration_test_with_zabbix
77+
6378
circleci_is_disabled_job:
6479
docker:
6580
- image: cimg/base:stable
@@ -74,6 +89,7 @@ workflows:
7489
jobs:
7590
- integration_test_with_zabbix_32
7691
- integration_test_with_zabbix_40
92+
- integration_test_with_zabbix_60
7793
circleci_is_disabled:
7894
jobs:
7995
- circleci_is_disabled_job

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
## 1.1.0
4+
5+
- Add webhook media_type for Zabbix 6.0 or higher
6+
37
## 1.0.0
48

59
- Drop python 2.7 support.

README.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ This README explains how this integration works, and how to configure it.
66
![Internal construction of this pack](./images/internal_construction.png)
77

88
# Requirements
9+
## st2 pack
10+
* Zabbix >=3.0. It has been tested with v3.0, v3.2 and v4.0.
911

10-
* Zabbix >3.0. It has been tested with v3.0, v3.2 and v4.0.
12+
## script type distpacher
13+
* Zabbix >=3.0. It has been tested with v3.0, v3.2 and v4.0.
14+
15+
## webhook type dispatcher
16+
* Zabbix >=6.0. It has been tested with v6.0.
1117

1218
# Installation
1319
Install the pack:
@@ -34,6 +40,13 @@ Options:
3440
-s Z_SENDTO, --sendto=Z_SENDTO
3541
Address, user name or other identifier of the
3642
recipient
43+
-s Z_DISPATCHERTYPE, --type=Z_DISPATCHERTYPE
44+
Type of way to dispatch. If you select script,
45+
the Zabbix will use st2_dispatcher. On the
46+
other hand, if you select webhook, this command
47+
will import a webhook dispathcer mediatype which
48+
is defined in media_stackstorm.yml
49+
3750
```
3851
3952
Example execution:
@@ -58,9 +71,12 @@ After executing the `register_st2_config_to_zabbix.py` command, you can notice t
5871
You see following page, and you have to fill out with parameters for your st2 environment (the endpoint URLs of st2-api and st2-auth, and authentication information).
5972
![](./images/configuration_for_mediatype2.png)
6073
74+
If you setup webhook dispatcher, you see following page.
75+
![](./images/configuration_for_mediatype3.png)
76+
6177
You can specify additional parameters and you can handle them from the payload of the StackStorm's Trigger(`zabbix.event_handler`).
6278
63-
### Deploy the AlertScript
79+
### Deploy the AlertScript for script dispatcher
6480
6581
The script `st2_dispatch.py` sends Zabbix events to the StackStorm server. Copy this script to the directory which Zabbix MediaType refers to. The directory is specified by the parameter of `AlertScriptsPath` in the Zabbix configuration file on the node which zabbix was installed.
6682
```shell
@@ -253,6 +269,12 @@ Starting procedure to run the test is also simple, all you have to do is executi
253269
$ bundle exec rspec
254270
```
255271
272+
When you want to run test for webhook type, you have to execute following command.
273+
274+
```
275+
$ ZABBIX_DISPATCHER_MEDIA_TYPE=webhook bundle exec rspec
276+
```
277+
256278
# Advanced Usage
257279
If you would prefer to use an API Key for auth in place of user/pass, you can do so by passing a JSON Dict as the first positional argument in your `Media Type` in place of:
258280
```
@@ -277,6 +299,8 @@ This dict has the following valid keys
277299
`api_key` will cause `st2_userid` and `st2_passwd` to be ignored (API Key prefered)
278300
`trigger` allows you to specify your own trigger on st2 to send messages to. Default is `zabbix.event_handler`
279301
302+
> WARNING: webhook type dispatcher does NOT support user/pass auth, please use API Key.
303+
280304
### JSON Examples
281305
API Key for Auth - `{"api_url":"https://stackstorm.yourdomain.com/api/v1", "api_key":"aaabbbccc111222333"}`
282306
User/Pass for auth - `{"api_url":"https://stackstorm.yourdomain.com/api/v1", "auth_url":"https://stackstorm.yourdomain.com/auth", "st2_userid":"st2admin", "st2_passwd":"st2pass"}`
54.9 KB
Loading

media_stackstorm.yml

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
zabbix_export:
2+
version: '6.0'
3+
media_types:
4+
-
5+
name: StackStorm
6+
type: WEBHOOK
7+
description: StackStorm
8+
parameters:
9+
-
10+
name: alert_message
11+
value: '{ALERT.MESSAGE}'
12+
-
13+
name: alert_subject
14+
value: '{ALERT.SUBJECT}'
15+
-
16+
name: alert_sendto
17+
value: '{ALERT.SENDTO}'
18+
-
19+
name: event_source
20+
value: '{EVENT.SOURCE}'
21+
-
22+
name: st2_api_url
23+
value: '<PLACE ST2 API URL>'
24+
-
25+
name: st2_api_key
26+
value: '<PLACE ST2 API Key>'
27+
-
28+
name: st2_trigger
29+
value: zabbix.event_handler
30+
script: |
31+
var St2 = {
32+
params: {},
33+
34+
setParams: function (params) {
35+
if (typeof params !== 'object') {
36+
return;
37+
}
38+
St2.params = params;
39+
},
40+
41+
setProxy: function (HTTPProxy) {
42+
St2.HTTPProxy = HTTPProxy;
43+
},
44+
45+
urlCheckFormat: function (api_url) {
46+
if (typeof api_url === 'string' && !api_url.endsWith('/')) {
47+
api_url += '/';
48+
}
49+
50+
if (api_url.indexOf('http://') === -1 && api_url.indexOf('https://') === -1) {
51+
api_url = 'https://' + api_url;
52+
}
53+
54+
return api_url;
55+
},
56+
57+
request: function (api_url, data) {
58+
if (typeof St2.params !== 'object' || typeof St2.params['api_key'] === 'undefined' || St2.params['api_key'] === '') {
59+
throw 'Required St2 param is not set: "api_key".';
60+
}
61+
62+
var response,
63+
request = new HttpRequest();
64+
65+
request.addHeader('Content-Type: application/json');
66+
request.addHeader('St2-Api-Key: ' + St2.params.api_key);
67+
68+
const webhook_url = api_url + 'webhooks/st2';
69+
70+
if (typeof St2.HTTPProxy !== 'undefined' && St2.HTTPProxy !== '') {
71+
request.setProxy(St2.HTTPProxy);
72+
}
73+
74+
if (typeof data !== 'undefined') {
75+
data = JSON.stringify(data);
76+
}
77+
78+
Zabbix.log(4, '[ StackStorm Webhook ] Sending request: ' + webhook_url + ((typeof data === 'string')
79+
? ('\n' + data)
80+
: ''));
81+
82+
response = request.post(webhook_url, data);
83+
84+
Zabbix.log(4, '[ StackStorm Webhook ] Received response with status code ' +
85+
request.getStatus() + '\n' + response);
86+
87+
if (response !== null) {
88+
try {
89+
response = JSON.parse(response);
90+
}
91+
catch (error) {
92+
Zabbix.log(4, '[ StackStorm Webhook ] Failed to parse response received from StackStorm');
93+
response = null;
94+
}
95+
}
96+
97+
if (typeof response !== 'object') {
98+
throw 'Failed to process response received from StackStorm. Check debug log for more information.';
99+
}
100+
101+
if (request.getStatus() < 200 || request.getStatus() >= 300) {
102+
var message = 'Request failed with status code ' + request.getStatus();
103+
104+
if (response.message) {
105+
message += ': ' + response.message;
106+
}
107+
108+
throw message + ' Check debug log for more information.';
109+
}
110+
111+
return response;
112+
}
113+
};
114+
115+
try {
116+
var params = JSON.parse(value),
117+
st2 = {},
118+
data = {},
119+
result
120+
required_params = [
121+
'alert_subject', 'alert_message',
122+
'st2_api_url', 'st2_api_key', 'st2_trigger'
123+
];
124+
125+
Object.keys(params)
126+
.forEach(function (key) {
127+
if (key.startsWith('st2_')) {
128+
st2[key.substring(4)] = params[key];
129+
}
130+
else if (required_params.indexOf(key) !== -1 && params[key] === '') {
131+
throw 'Parameter "' + key + '" can\'t be empty.';
132+
}
133+
});
134+
135+
// Check type of event. Possible values: 0 - Trigger
136+
if (params.event_source != 0) {
137+
throw ('Incorrect "event_source" parameter given: ' + params.event_source
138+
+ '\nOnly trigger-based events are supported');
139+
}
140+
141+
// Check for backslash in the end of url and schema.
142+
st2.api_url = St2.urlCheckFormat(st2.api_url);
143+
144+
145+
data.trigger = st2.trigger;
146+
data.payload = {
147+
alert_sendto: params.alert_sendto,
148+
alert_subject: params.alert_subject,
149+
alert_message: params.alert_message
150+
}
151+
152+
St2.setParams(st2);
153+
St2.setProxy(params.HTTPProxy);
154+
155+
var response = St2.request(st2.api_url, data);
156+
157+
Zabbix.log(4, '[ StackStorm Webhook ] Response: ' + JSON.stringify(response));
158+
return JSON.stringify(response);
159+
}
160+
catch (error) {
161+
Zabbix.log(4, '[ StackStorm Webhook ] ERROR: ' + error);
162+
throw 'Sending failed: ' + error;
163+
}
164+
message_templates:
165+
-
166+
event_source: TRIGGERS
167+
operation_mode: PROBLEM
168+
subject: '[{TRIGGER.STATUS}] {TRIGGER.NAME}'
169+
message: |
170+
{
171+
"event": {
172+
"id": "{EVENT.ID}",
173+
"time": "{EVENT.TIME}"
174+
},
175+
"trigger": {
176+
"id": "{TRIGGER.ID}",
177+
"name": "{TRIGGER.NAME}",
178+
"status": "{TRIGGER.STATUS}"
179+
},
180+
"items": [
181+
{
182+
"name": "{ITEM.NAME1}",
183+
"host": "{HOST.NAME1}",
184+
"key": "{ITEM.KEY1}",
185+
"value": "{ITEM.VALUE1}"
186+
},
187+
{
188+
"name": "{ITEM.NAME2}",
189+
"host": "{HOST.NAME2}",
190+
"key": "{ITEM.KEY2}",
191+
"value": "{ITEM.VALUE2}"
192+
},
193+
{
194+
"name": "{ITEM.NAME3}",
195+
"host": "{HOST.NAME3}",
196+
"key": "{ITEM.KEY3}",
197+
"value": "{ITEM.VALUE3}"
198+
},
199+
{
200+
"name": "{ITEM.NAME4}",
201+
"host": "{HOST.NAME4}",
202+
"key": "{ITEM.KEY4}",
203+
"value": "{ITEM.VALUE4}"
204+
},
205+
{
206+
"name": "{ITEM.NAME5}",
207+
"host": "{HOST.NAME5}",
208+
"key": "{ITEM.KEY5}",
209+
"value": "{ITEM.VALUE5}"
210+
},
211+
{
212+
"name": "{ITEM.NAME6}",
213+
"host": "{HOST.NAME6}",
214+
"key": "{ITEM.KEY6}",
215+
"value": "{ITEM.VALUE6}"
216+
},
217+
{
218+
"name": "{ITEM.NAME7}",
219+
"host": "{HOST.NAME7}",
220+
"key": "{ITEM.KEY7}",
221+
"value": "{ITEM.VALUE7}"
222+
},
223+
{
224+
"name": "{ITEM.NAME8}",
225+
"host": "{HOST.NAME8}",
226+
"key": "{ITEM.KEY8}",
227+
"value": "{ITEM.VALUE8}"
228+
},
229+
{
230+
"name": "{ITEM.NAME9}",
231+
"host": "{HOST.NAME9}",
232+
"key": "{ITEM.KEY9}",
233+
"value": "{ITEM.VALUE9}"
234+
}
235+
]
236+
}

pack.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Zabbix Monitoring System
55
keywords:
66
- zabbix
77
- monitoring
8-
version: 1.0.0
8+
version: 1.1.0
99
author: Hiroyasu OHYAMA
1010
1111
python_versions:

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ py-zabbix==1.1.3
22
st2client
33
pytz
44
tzlocal
5+
pyyaml

0 commit comments

Comments
 (0)