Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTikhon Uskov <tikhon.uskov@zabbix.com>2021-04-15 11:53:27 +0300
committerTikhon Uskov <tikhon.uskov@zabbix.com>2021-04-15 11:53:27 +0300
commit0f46808033994d2a2587d573423499f15d41658a (patch)
tree683bc3d59ae9dc4e0ab61992075bffaefce7a581 /templates
parent78f46e063d6783943829c700d5ca8f726c1b2099 (diff)
.........T [ZBXNEXT-6592] fixed after review
Diffstat (limited to 'templates')
-rw-r--r--templates/media/manageengine_servicedesk/README.md31
-rw-r--r--templates/media/manageengine_servicedesk/media_manageengine_servicedesk.yaml142
2 files changed, 93 insertions, 80 deletions
diff --git a/templates/media/manageengine_servicedesk/README.md b/templates/media/manageengine_servicedesk/README.md
index 4403eca67c8..ff8e6a9a7e6 100644
--- a/templates/media/manageengine_servicedesk/README.md
+++ b/templates/media/manageengine_servicedesk/README.md
@@ -3,16 +3,16 @@
This guide describes how to integrate Zabbix 5.4 installation with ManageEngine ServiceDesk (both on-premise and on-demand) using the Zabbix webhook feature. This guide provides instructions on setting up a media type, a user and an action in Zabbix.<br>
Please note that recovery and update operations are supported only for trigger-based events.
-### Setting up ManageEngine ServiceDesk
+## Setting up ManageEngine ServiceDesk
At first, create a user for API or use an existing one.
-## Setting up the on-premise installation
+### Setting up the on-premise installation
1\. Go to *Admin -> Technicians*.<br>
2\. Click the *Add New Technician* link, enter the Technician details and provide login permission.<br>
3\. Click *Generate link* under the API key details block. Select a time frame for the key to expire using the Calendar icon, or simply retain the same key perpetually.<br>
4\. Save TEHNICAN_KEY for use in Zabbix later.<br>
-## Setting up the on-demand installation
+### Setting up the on-demand installation
1\. Go to [Zoho Developer Console](https://api-console.zoho.com/).<br>
2\. Choose *Self Client* from the list of client types, and click *Create Now*.<br>
3\. Click OK in the pop up to enable a self client for your account.<br>
@@ -21,18 +21,27 @@ At first, create a user for API or use an existing one.
6\. Select the *Time Duration* for which the grant token is valid. Please note that after this time, the grant token expires.<br>
7\. Enter a description and click *Generate*.<br>
8\. The generated code for the specified scope is displayed. Copy the grant code.<br>
-9\. Make a POST request with the following URL.<br>
-```https://accounts.zoho.com/oauth/v2/token?code=1000.f74e7b6fc16c95bbc1fa2f067962f84b.9768e796b6273774817032613ba6892a&grant_type=authorization_code&client_id=1000.15S25B602CISR5WO9RUZ8UT39O3RIH&client_secret=9ea302935eb150d9d6cbefd35b1eb8891332d815b8&redirect_uri=https://www.zoho.com```<br>
+9\. Make a POST request with the URL params following parameters:<br>
+- **code**: enter the Grant Token / Authorization Code generated from previous step.
+- **grant_type**: enter the value as "authorization_code".
+- **client_id**: specify client_id obtained in step 4.
+- **client_secret**: specify client_secret obtained in step 4.
+- **redirect_uri**: specify the Callback URL that you registered during the app registration. You can use any ULR for Self client mode, *https://www.zoho.com* for example.
+
+Example:
+```curl -X POST https://accounts.zoho.com/oauth/v2/token?code=1000.f74e7b6fc16c95bbc1fa2f067962f84b.9768e796b6273774817032613ba6892a&grant_type=authorization_code&client_id=1000.15S25B602CISR5WO9RUZ8UT39O3RIH&client_secret=9ea302935eb150d9d6cbefd35b1eb8891332d815b8&redirect_uri=https://www.zoho.com```<br>
Use your domain-specific Zoho accounts URL when you make the request.<br>
+- For US: https://accounts.zoho.com
+- For AU: https://accounts.zoho.com.au
- For EU: https://accounts.zoho.eu
-- For CN: https://accounts.zoho.com.cn
- For IN: https://accounts.zoho.in
+- For CN: https://accounts.zoho.com.cn
10\. If the request is successful, you will receive the following output:<br>
```{ “access_token”: “1000.2370ff1fd75e968ae780cd8d14841e82.03518d2d1dab9c6c4cf74ae82b89defa”, “refresh_token”: “1000.2afabf2f5a396325e88f715c6de34d12.edce6130ca3832a14e5f80d005a5324d”, “token_type”: “Bearer”, “expires_in”: 3600 }```<br>
Save the *refresh_token* for using in Zabbix later.
-### Setting up the webhook in Zabbix
+## Setting up the webhook in Zabbix
1\. In the *Administration > Media types* section, import [media_manageengine_servicedesk.yaml](media_manageengine_servicedesk.yaml).
2\. Open the newly added **ManageEngine ServiceDesk** media type and replace all *&lt;PLACEHOLDERS&gt;* with your values.<br>
@@ -40,11 +49,11 @@ The following parameters are required:<br>
**sd_on_premise** - true or false. Pass *true* if you are using on-premise installation and *false* if not.<br>
**sd_url** - the URL of your instance.<br>
-The following parameters are required for on-premise servicedesk:<br>
+The following parameters are required for on-premise ServiceDesk:<br>
**sd_on_premise_auth_token** - the TEHNICAN_KEY generated earlier.<br>
**field_ref:requester** - login of the account used for request creation.<br>
-The following parameters are required for on-demand servicedesk:<br>
+The following parameters are required for on-demand ServiceDesk:<br>
**sd_url_auth** - your domain-specific Zoho accounts URL for refreshing access token.<br>
**sd_on_demand_client_id**, **sd_on_demand_client_secret**, **sd_on_demand_refresh_token** - created earlier authentication details.<br>
**field_ref:requester** - requester's displaying name. You can remove this parameter or use any name. *"Zabbix"*, for example. <br>
@@ -55,10 +64,10 @@ Make sure this user has access to all hosts, for which you would like problem no
## Customize your requests
You can add any data to ServiceDesk or user-defined fields.<br>
-Please see the [Om-demand](https://www.manageengine.com/products/service-desk/sdpod-v3-api/SDPOD-V3-API.html#add-request) and [On-premise](
+Please see the [On-demand](https://www.manageengine.com/products/service-desk/sdpod-v3-api/SDPOD-V3-API.html#add-request) and [On-premise](
https://ui.servicedeskplus.com/APIDocs3/index.html#add-request) API specification for details about fields.<br>
Most of fields should be filled as single-line string, other should be an object with *name* property. Zabbix can fill both, but not *"date"* fields.<br>
-Fields shoud be in format **field_string:fieldname**, where:<br>
+Fields should be in format **field_string:fieldname**, where:<br>
**field** - can be *field* or *udf_field*. The prefix for payload generator.<br>
**string** - should be *string* for single-line strings or any other for objects.<br>
**:** - separator between prefix and field name.<br>
diff --git a/templates/media/manageengine_servicedesk/media_manageengine_servicedesk.yaml b/templates/media/manageengine_servicedesk/media_manageengine_servicedesk.yaml
index 6ce6b9528ef..4da48d6dc03 100644
--- a/templates/media/manageengine_servicedesk/media_manageengine_servicedesk.yaml
+++ b/templates/media/manageengine_servicedesk/media_manageengine_servicedesk.yaml
@@ -1,6 +1,6 @@
zabbix_export:
version: '5.4'
- date: '2021-04-12T06:46:03Z'
+ date: '2021-04-15T08:50:14Z'
media_types:
-
name: 'ManageEngine ServiceDesk'
@@ -110,15 +110,14 @@ zabbix_export:
},
createLink: function (id, url) {
- if (MEngine.params.on_premise.toLowerCase() === 'true') {
- return url + (url.endsWith('/') ? '' : '/') + 'WorkOrder.do?woMode=viewWO&woID=' + id;
- }
- else {
- return url + (url.endsWith('/') ? '' : '/') + 'app/itdesk/ui/requests/' + id + '/details';
- }
+ return url + (url.endsWith('/') ? '' : '/') +
+ ((MEngine.params.on_premise.toLowerCase() === 'true')
+ ? ('WorkOrder.do?woMode=viewWO&woID=' + id)
+ : ('app/itdesk/ui/requests/' + id + '/details')
+ );
},
- setToken: function () {
+ refreshAccessToken: function () {
[
'url_auth',
'on_demand_refresh_token',
@@ -134,9 +133,9 @@ zabbix_export:
var response,
request = new HttpRequest(),
url = MEngine.params.url_auth +
- 'refresh_token=' + MEngine.params.on_demand_refresh_token +
- '&grant_type=refresh_token&client_id=' + MEngine.params.on_demand_client_id +
- '&client_secret=' + MEngine.params.on_demand_client_secret +
+ 'refresh_token=' + encodeURIComponent(MEngine.params.on_demand_refresh_token) +
+ '&grant_type=refresh_token&client_id=' + encodeURIComponent(MEngine.params.on_demand_client_id) +
+ '&client_secret=' + encodeURIComponent(MEngine.params.on_demand_client_secret) +
'&redirect_uri=https://www.zoho.com&scope=SDPOnDemand.requests.ALL';
if (MEngine.HTTPProxy) {
@@ -150,18 +149,26 @@ zabbix_export:
Zabbix.log(4, '[ ManageEngine Webhook ] Received response with status code ' +
request.getStatus() + '\n' + response);
- if (request.getStatus() < 200 || request.getStatus() >= 300) {
- throw 'Access token resresh failed with status code ' + request.getStatus() +
+ try {
+ response = JSON.parse(response);
+ }
+ catch (error) {
+ Zabbix.log(4, '[ ManageEngine Webhook ] Failed to parse response received from Zoho Accounts');
+ }
+
+ if ((request.getStatus() < 200 || request.getStatus() >= 300) && !response.access_token) {
+ throw 'Access token refresh failed with HTTP status code ' + request.getStatus() +
'. Check debug log for more information.';
}
else {
- MEngine.params.on_demand_auth_token = JSON.parse(response).access_token;
+ MEngine.params.on_demand_auth_token = response.access_token;
}
},
request: function (method, query, data) {
var response,
url = MEngine.params.url + query,
+ input,
request = new HttpRequest(),
message;
@@ -181,15 +188,16 @@ zabbix_export:
data = JSON.stringify(data);
}
- Zabbix.log(4, '[ ManageEngine Webhook ] Sending request: ' + url + '?input_data=' + encodeURIComponent(data));
+ input = 'input_data=' + encodeURIComponent(data);
+ Zabbix.log(4, '[ ManageEngine Webhook ] Sending request: ' + url + '?' + input);
switch (method) {
case 'post':
- response = request.post(url + '?input_data=' + encodeURIComponent(data));
+ response = request.post(url, input);
break;
case 'put':
- response = request.put(url + '?input_data=' + encodeURIComponent(data));
+ response = request.put(url, input);
break;
default:
@@ -204,8 +212,6 @@ zabbix_export:
}
catch (error) {
Zabbix.log(4, '[ ManageEngine Webhook ] Failed to parse response received from ManageEngine');
- throw 'Failed to parse response received from ManageEngine.\nRequest status code ' +
- request.getStatus() + '. Check debug log for more information.';
}
if ((request.getStatus() < 200 || request.getStatus() >= 300)
@@ -216,7 +222,9 @@ zabbix_export:
else if (typeof response.response_status === 'object' && response.response_status.status === 'failed') {
message = 'Request failed with status_code ';
- if (typeof response.response_status.messages === 'object' && response.response_status.messages[0].message) {
+ if (typeof response.response_status.messages === 'object'
+ && response.response_status.messages[0]
+ && response.response_status.messages[0].message) {
message += response.response_status.messages[0].status_code +
'. Message: ' + response.response_status.messages[0].message;
}
@@ -236,51 +244,49 @@ zabbix_export:
var data = {},
result;
- if (typeof fields === 'object' && Object.keys(fields).length) {
- if (isNote) {
- data.description = fields['field_string:description'];
- result = {request_note: data};
- }
- else {
- Object.keys(fields)
- .forEach(function(field) {
- if (fields[field].trim() === '') {
- Zabbix.log(4, '[ ManageEngine Webhook ] Field "' + field +
- '" can\'t be empty. The field ignored.');
- }
- else {
- try {
- var prefix = field.split(':')[0],
- root;
-
- if (prefix.startsWith('udf_') && !data.udf_fields) {
- data.udf_fields = {};
- root = data.udf_fields;
- }
- else if (prefix.startsWith('udf_')) {
- root = data.udf_fields;
- }
- else {
- root = data;
- }
-
- if (prefix.endsWith('string')) {
- root[field.substring(field.indexOf(':') + 1)] = fields[field];
- }
- else {
- root[field.substring(field.indexOf(':') + 1)] = {
- name: fields[field]
- };
- }
+ if (isNote) {
+ data.description = fields['field_string:description'];
+ result = {request_note: data};
+ }
+ else {
+ Object.keys(fields)
+ .forEach(function(field) {
+ if (fields[field].trim() === '') {
+ Zabbix.log(4, '[ ManageEngine Webhook ] Field "' + field +
+ '" can\'t be empty. The field ignored.');
+ }
+ else {
+ try {
+ var prefix = field.split(':')[0],
+ root;
+
+ if (prefix.startsWith('udf_') && !data.udf_fields) {
+ data.udf_fields = {};
+ root = data.udf_fields;
}
- catch (error) {
- Zabbix.log(4, '[ ManageEngine Webhook ] Can\'t parse field "' + field +
- '". The field ignored.');
+ else if (prefix.startsWith('udf_')) {
+ root = data.udf_fields;
+ }
+ else {
+ root = data;
+ }
+
+ if (prefix.endsWith('string')) {
+ root[field.substring(field.indexOf(':') + 1)] = fields[field];
+ }
+ else {
+ root[field.substring(field.indexOf(':') + 1)] = {
+ name: fields[field]
+ };
}
}
- });
- result = {request: data};
- }
+ catch (error) {
+ Zabbix.log(4, '[ ManageEngine Webhook ] Can\'t parse field "' + field +
+ '". The field ignored.');
+ }
+ }
+ });
+ result = {request: data};
}
return result;
@@ -315,8 +321,7 @@ zabbix_export:
fields[key] = params[key];
}
- if (required_params.indexOf(key) !== -1
- && (typeof params[key] === 'undefined' || params[key].trim() === '')) {
+ if (required_params.indexOf(key) !== -1 && params[key].trim() === '') {
throw 'Parameter "' + key + '" can\'t be empty.';
}
});
@@ -347,7 +352,6 @@ zabbix_export:
fields['field_object:priority'] = params['priority_' + severities[params.event_nseverity].name]
|| 'Normal';
-
if (params.event_update_status === '1' && (typeof params.sd_request_id === 'undefined'
|| params.sd_request_id.trim() === ''
|| params.sd_request_id === '{EVENT.TAGS.__zbx_sd_request_id}')) {
@@ -358,10 +362,9 @@ zabbix_export:
MEngine.setProxy(params.HTTPProxy);
if (MEngine.params.on_premise.toLowerCase() !== 'true') {
- MEngine.setToken();
+ MEngine.refreshAccessToken();
}
-
// Create issue for non trigger-based events.
if (params.event_source !== '0' && params.event_recovery_value !== '0') {
MEngine.request('post', 'requests', MEngine.createPaylaod(fields));
@@ -379,13 +382,14 @@ zabbix_export:
}
else {
MEngine.request('post', 'requests/' + params.sd_request_id + '/notes',
- MEngine.createPaylaod(fields, params.event_update_status === '1'));
+ MEngine.createPaylaod(fields, params.event_update_status === '1')
+ );
}
return JSON.stringify(result);
}
catch (error) {
- Zabbix.log(3, '[ MEngine Webhook ] ERROR: ' + error);
+ Zabbix.log(3, '[ ManageEngine Webhook ] ERROR: ' + error);
throw 'Sending failed: ' + error;
}
process_tags: 'YES'