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:
authorAndrew Biba <andrew.biba@zabbix.com>2022-04-06 15:35:34 +0300
committerAndrew Biba <andrew.biba@zabbix.com>2022-04-06 15:35:34 +0300
commit393d1d39b9bdf44ce4cdf64cb374b783bda2ccf2 (patch)
tree419830a9989f35e0ba65fd13d6f623e923b66162 /templates
parentccfbdc1a9137fe6208c1d3e445afdf11335f1a52 (diff)
.........T [ZBXNEXT-7505] added new GLPi media type
Diffstat (limited to 'templates')
-rw-r--r--templates/media/glpi/README.md67
-rw-r--r--templates/media/glpi/images/1.pngbin0 -> 11449 bytes
-rw-r--r--templates/media/glpi/images/1.thumb.pngbin0 -> 22093 bytes
-rw-r--r--templates/media/glpi/images/2.pngbin0 -> 5910 bytes
-rw-r--r--templates/media/glpi/images/2.thumb.pngbin0 -> 12109 bytes
-rw-r--r--templates/media/glpi/images/3.pngbin0 -> 37864 bytes
-rw-r--r--templates/media/glpi/images/3.thumb.pngbin0 -> 51848 bytes
-rw-r--r--templates/media/glpi/media_glpi.yaml375
8 files changed, 442 insertions, 0 deletions
diff --git a/templates/media/glpi/README.md b/templates/media/glpi/README.md
new file mode 100644
index 00000000000..43a061cb42d
--- /dev/null
+++ b/templates/media/glpi/README.md
@@ -0,0 +1,67 @@
+
+# GLPi webhook
+
+## About webhook
+
+This webhook creates problems in GLPi Assistance section. Created problems have the next severity mapping:
+
+|Severity In zabbix|Urgency in GLPi|
+|-|-|
+0 - Not classified| Medium (default)|
+1 - Information| Very low|
+2 - Warning| Low|
+3 - Average| Medium|
+4 - High| High|
+5 - Disaster| Very High|
+
+On Update action in zabbix, webhook updates created problem's title, severity and creates followup with update comment.
+
+On resolve action, webhook updates created problem title and creates followup with resolve information.
+
+Created problems have "New" status, and resolved - "Solved" status.
+
+Due to the specifics of the webhook, the number of retries is set to 1 by default. We recommend that you do not change this setting, because in case of a transaction error, additional duplicate objects (problems, followups) may be created during the retry.
+
+## Installation guide
+
+This guide describes how to integrate your Zabbix installation with GLPi problems using the Zabbix webhook feature. This guide provides instructions on setting up a media type, a user and an action in Zabbix.
+<br/><br/>
+## In GLPi
+
+1\. Create or use existing user in GLPi with permission to create problems and followups.
+[![](images/1.thumb.png?raw=true)](images/1.png)
+[![](images/2.thumb.png?raw=true)](images/2.png)
+
+2\. Please create an **API token**. For that you should go into user profile and set tick in "Regenerate" field against "API token" and hit save.
+[![](images/3.thumb.png?raw=true)](images/3.png)
+
+
+3\. Copy the **API token** of your new integration to use it in Zabbix.
+<br/><br/>
+## In Zabbix
+
+The configuration consists of a _media type_ in Zabbix, which will invoke the webhook to send alerts to GLPi problems through the GLPi Rest API.
+
+
+1\. [Import](https://www.zabbix.com/documentation/6.2/manual/web_interface/frontend_sections/administration/mediatypes) the GLPi media type from file [media_glpi.yaml](media_glpi.yaml).
+
+2\. Change in the imported media the values of the variable *glpi_token* and *glpi_url*.
+
+
+For more information about the Zabbix Webhook configuration, please see the [documentation](https://www.zabbix.com/documentation/6.2/manual/config/notifications/media/webhook).
+
+3\. Create a **Zabbix user** and add **Media** with the **GLPi** media type.
+Though a "Send to" field is not used in GLPi webhook, it cannot be empty. To comply with frontend requirements, you can put any symbol there.
+Make sure this user has access to all hosts for which you would like problem notifications to be converted into GLPi problems.
+
+4\. Set up a global macro {$ZABBIX.URL} with URL of current zabbix. Please notice that HTTPS will be used by default if HTTP/HTTPS schema is not present in the URL.
+
+For more information, please see [Zabbix](https://www.zabbix.com/documentation/6.2/manual/config/notifications) and [GLPi](https://glpi-project.org/DOC/EN/) documentation.
+<br/><br/>
+
+## Tested on
+GLPI 9.5.7
+<br/><br/>
+## Supported Versions
+
+Zabbix 6.2
diff --git a/templates/media/glpi/images/1.png b/templates/media/glpi/images/1.png
new file mode 100644
index 00000000000..608a8295e3b
--- /dev/null
+++ b/templates/media/glpi/images/1.png
Binary files differ
diff --git a/templates/media/glpi/images/1.thumb.png b/templates/media/glpi/images/1.thumb.png
new file mode 100644
index 00000000000..886b48a7a8c
--- /dev/null
+++ b/templates/media/glpi/images/1.thumb.png
Binary files differ
diff --git a/templates/media/glpi/images/2.png b/templates/media/glpi/images/2.png
new file mode 100644
index 00000000000..7f0371e40d3
--- /dev/null
+++ b/templates/media/glpi/images/2.png
Binary files differ
diff --git a/templates/media/glpi/images/2.thumb.png b/templates/media/glpi/images/2.thumb.png
new file mode 100644
index 00000000000..b8cf38d3d88
--- /dev/null
+++ b/templates/media/glpi/images/2.thumb.png
Binary files differ
diff --git a/templates/media/glpi/images/3.png b/templates/media/glpi/images/3.png
new file mode 100644
index 00000000000..f0375146973
--- /dev/null
+++ b/templates/media/glpi/images/3.png
Binary files differ
diff --git a/templates/media/glpi/images/3.thumb.png b/templates/media/glpi/images/3.thumb.png
new file mode 100644
index 00000000000..95d96a9838a
--- /dev/null
+++ b/templates/media/glpi/images/3.thumb.png
Binary files differ
diff --git a/templates/media/glpi/media_glpi.yaml b/templates/media/glpi/media_glpi.yaml
new file mode 100644
index 00000000000..b52a435f983
--- /dev/null
+++ b/templates/media/glpi/media_glpi.yaml
@@ -0,0 +1,375 @@
+zabbix_export:
+ version: '6.2'
+ date: '2022-03-24T18:54:55Z'
+ media_types:
+ -
+ name: GLPi
+ type: WEBHOOK
+ parameters:
+ -
+ name: alert_message
+ value: '{ALERT.MESSAGE}'
+ -
+ name: alert_subject
+ value: '{ALERT.SUBJECT}'
+ -
+ name: event_id
+ value: '{EVENT.ID}'
+ -
+ name: event_nseverity
+ value: '{EVENT.NSEVERITY}'
+ -
+ name: event_recovery_value
+ value: '{EVENT.RECOVERY.VALUE}'
+ -
+ name: event_source
+ value: '{EVENT.SOURCE}'
+ -
+ name: event_update_status
+ value: '{EVENT.UPDATE.STATUS}'
+ -
+ name: event_value
+ value: '{EVENT.VALUE}'
+ -
+ name: glpi_problem_id
+ value: '{EVENT.TAGS.__zbx_glpi_problem_id}'
+ -
+ name: glpi_token
+ value: '<PLACE GLPI TOKEN>'
+ -
+ name: glpi_url
+ value: '<PLACE GLPI URL>'
+ -
+ name: trigger_id
+ value: '{TRIGGER.ID}'
+ -
+ name: zabbix_url
+ value: '{$ZABBIX.URL}'
+ attempts: '1'
+ script: |
+ var GLPi = {
+ params: {},
+
+ setParams: function (params) {
+ if (typeof params !== 'object') {
+ return;
+ }
+ GLPi.params = params;
+ },
+
+ setProxy: function (HTTPProxy) {
+ GLPi.HTTPProxy = HTTPProxy;
+ },
+
+ urlCheckFormat: function (url) {
+ if (typeof url === 'string' && !url.endsWith('/')) {
+ url += '/';
+ }
+
+ if (url.indexOf('http://') === -1 && url.indexOf('https://') === -1) {
+ url = 'https://' + url;
+ }
+
+ return url;
+ },
+
+ getAuthToken: function (url, token) {
+ var response,
+ request = new HttpRequest();
+
+ request.addHeader('Content-Type: application/json');
+ request.addHeader('Authorization: user_token ' + token);
+
+ response = request.get(url + "apirest.php/initSession");
+
+ if (response !== null) {
+ try {
+ response = JSON.parse(response);
+ }
+ catch (error) {
+ Zabbix.log(4, '[ GLPi Webhook ] Failed to receive authentication token from GLPi.');
+ response = null;
+ }
+ }
+
+ if (Array.isArray(response)) {
+ if (response[1]) {
+ throw 'Error received from GLPi: ' + response[1];
+ } else {
+ throw 'Failed to receive authentication token from GLPi.';
+ }
+ }
+
+ if (typeof response !== 'object' || !response.session_token) {
+ throw 'Failed to process response received from getting GLPi authentication token. Check debug log for more information.';
+ }
+
+ return response.session_token;
+ },
+
+ getProblemUrl: function (zabbix_url, triggerid, eventid, event_source) {
+ var problem_url = zabbix_url;
+
+ if (event_source === '0') {
+ problem_url += 'tr_events.php?triggerid=' + triggerid + '&eventid=' + eventid;
+ }
+
+ return problem_url;
+ },
+
+ request: function (method, url, data) {
+ if (typeof GLPi.params !== 'object' || typeof GLPi.params.authToken === 'undefined' || GLPi.params.authToken === '') {
+ throw 'Required GLPi param authToken is not set.';
+ }
+
+ var response,
+ request = new HttpRequest();
+
+ request.addHeader('Content-Type: application/json');
+ request.addHeader('Session-Token:' + GLPi.params.authToken);
+
+ if (typeof GLPi.HTTPProxy !== 'undefined' && GLPi.HTTPProxy !== '') {
+ request.setProxy(GLPi.HTTPProxy);
+ }
+
+ if (typeof data !== 'undefined') {
+ data = JSON.stringify(data);
+ }
+
+ Zabbix.log(4, '[ GLPi Webhook ] Sending request: ' + url + ((typeof data === 'string')
+ ? ('\n' + data)
+ : ''));
+
+ switch (method) {
+ case 'post':
+ response = request.post(url, data);
+ break;
+
+ case 'put':
+ response = request.put(url, data);
+ break;
+
+ default:
+ throw 'Unsupported HTTP request method: ' + method;
+ }
+
+ Zabbix.log(4, '[ GLPi Webhook ] Received response with status code ' +
+ request.getStatus() + '\n' + response);
+
+ if (response !== null) {
+ try {
+ response = JSON.parse(response);
+ }
+ catch (error) {
+ Zabbix.log(4, '[ GLPi Webhook ] Failed to parse response received from GLPi');
+ response = null;
+ }
+ }
+
+ if (typeof response !== 'object' || typeof response === 'undefined' || response === null) {
+ throw 'Failed to process response received from GLPi. Check debug log for more information.';
+ }
+
+ if (request.getStatus() < 200 || request.getStatus() >= 300) {
+ var message = 'Request failed with status code ' + request.getStatus();
+
+ if (response.message) {
+ message += ': ' + response.message;
+ }
+
+ throw message + ' Check debug log for more information.';
+ }
+
+ return response;
+ }
+ };
+
+ try {
+ var params = JSON.parse(value),
+ glpi = {},
+ url = '',
+ data = {},
+ comment_data,
+ result = { tags: {} },
+ required_params = [
+ 'alert_subject', 'alert_message', 'event_source', 'event_value',
+ 'event_update_status', 'event_recovery_value',
+ 'event_id', 'trigger_id', 'zabbix_url',
+ 'glpi_token', 'glpi_url'
+ ],
+ method = 'post',
+ process_tags = true,
+ response;
+
+ Object.keys(params)
+ .forEach(function (key) {
+ if (key.startsWith('glpi_')) {
+ glpi[key.substring(5)] = params[key];
+ }
+ else if (required_params.indexOf(key) !== -1 && params[key] === '') {
+ throw 'Parameter "' + key + '" can\'t be empty.';
+ }
+ });
+
+ if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
+ throw 'Incorrect "event_source" parameter given: ' + params.event_source + '\nMust be 0-3.';
+ }
+
+ // Check {EVENT.VALUE} for trigger-based and internal events.
+ if (params.event_value !== '0' && params.event_value !== '1'
+ && (params.event_source === '0' || params.event_source === '3')) {
+ throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
+ }
+
+ // Check {EVENT.UPDATE.STATUS} only for trigger-based events.
+ if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {
+ throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';
+ }
+
+ if (params.event_source !== '0' && params.event_recovery_value === '0') {
+ throw 'Recovery operations are supported only for trigger-based actions.';
+ }
+
+ if (typeof params.zabbix_url !== 'string' || params.zabbix_url.trim() === '' || params.zabbix_url === '{$ZABBIX.URL}') {
+ throw 'Field "zabbix_url" cannot be empty.';
+ }
+
+ // Check for backslash in the end of url and schema.
+ glpi.url = GLPi.urlCheckFormat(glpi.url);
+ params.zabbix_url = GLPi.urlCheckFormat(params.zabbix_url);
+
+ glpi.authToken = GLPi.getAuthToken(glpi.url, glpi.token);
+ GLPi.setParams(glpi);
+
+ data = {
+ 'input': {
+ 'name': params.alert_subject,
+ 'content': params.alert_message + '\n<a href=' + GLPi.getProblemUrl(params.zabbix_url, params.trigger_id, params.event_id, params.event_source) + '>Link to problem in Zabbix</a>',
+ 'status': 1, // Set status "New"
+ 'urgency': params.event_nseverity
+ }
+ };
+
+ // In case of resolve
+ if (params.event_source === '0' && params.event_value === '0') {
+ process_tags = false;
+ dataFollowup = {
+ 'input': {
+ 'items_id': glpi.problem_id,
+ 'itemtype': 'Problem',
+ 'content': params.alert_message + '\n<a href=' + GLPi.getProblemUrl(params.zabbix_url, params.trigger_id, params.event_id, params.event_source) + '>Link to problem in Zabbix</a>'
+ }
+ };
+ dataProblem = {
+ 'id': glpi.problem_id,
+ 'input': {
+ 'name': params.alert_subject,
+ 'status': 5, // Set status "Solved"
+ 'urgency': params.event_nseverity
+ }
+ };
+
+ GLPi.request('put', glpi.url + 'apirest.php/Problem/' + glpi.problem_id, dataProblem);
+ GLPi.request('post', glpi.url + 'apirest.php/Problem/' + glpi.problem_id + '/ITILFollowup', dataFollowup);
+ }
+
+ // In case of update
+ else if (params.event_source === '0' && params.event_update_status === '1') {
+ process_tags = false;
+ dataFollowup = {
+ 'input': {
+ 'items_id': glpi.problem_id,
+ 'itemtype': 'Problem',
+ 'content': params.alert_message + '\n<a href=' + GLPi.getProblemUrl(params.zabbix_url, params.trigger_id, params.event_id, params.event_source) + '>Link to problem in Zabbix</a>'
+ }
+ };
+ dataProblem = {
+ 'id': glpi.problem_id,
+ 'input': {
+ 'name': params.alert_subject,
+ 'urgency': params.event_nseverity
+ }
+ };
+
+ GLPi.request('put', glpi.url + 'apirest.php/Problem/' + glpi.problem_id, dataProblem);
+ GLPi.request('post', glpi.url + 'apirest.php/Problem/' + glpi.problem_id + '/ITILFollowup', dataFollowup);
+ }
+
+ // In case of problem
+ else {
+ response = GLPi.request('post', glpi.url + 'apirest.php/Problem/', data);
+ }
+
+ if (process_tags) {
+ result.tags.__zbx_glpi_problem_id = response.id;
+ result.tags.__zbx_glpi_link = glpi.url + 'front/problem.form.php?id=' + response.id;
+ }
+
+ Zabbix.log(4, '[ GLPi Webhook ] Result: ' + JSON.stringify(result));
+ return JSON.stringify(result);
+ }
+ catch (error) {
+ Zabbix.log(4, '[ GLPi Webhook ] ERROR: ' + error);
+ throw 'Sending failed: ' + error;
+ }
+ process_tags: 'YES'
+ show_event_menu: 'YES'
+ event_menu_url: '{EVENT.TAGS.__zbx_glpi_link}'
+ event_menu_name: 'GLPi: Problem {EVENT.TAGS.__zbx_glpi_problem_id}'
+ message_templates:
+ -
+ event_source: TRIGGERS
+ operation_mode: PROBLEM
+ subject: '[{EVENT.STATUS}] {EVENT.NAME}'
+ message: |
+ Problem started at {EVENT.TIME} on {EVENT.DATE}
+ Problem name: {EVENT.NAME}
+ Host: {HOST.NAME}
+ Severity: {EVENT.SEVERITY}
+ Operational data: {EVENT.OPDATA}
+ Original problem ID: {EVENT.ID}
+ {TRIGGER.URL}
+ -
+ event_source: TRIGGERS
+ operation_mode: RECOVERY
+ subject: '[{EVENT.STATUS}] {EVENT.NAME}'
+ message: |
+ Problem has been resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE}
+ Problem name: {EVENT.NAME}
+ Host: {HOST.NAME}
+ Severity: {EVENT.SEVERITY}
+ Original problem ID: {EVENT.ID}
+ {TRIGGER.URL}
+ -
+ event_source: TRIGGERS
+ operation_mode: UPDATE
+ subject: '[{EVENT.STATUS}] {EVENT.NAME}'
+ message: |
+ {USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.
+ {EVENT.UPDATE.MESSAGE}
+
+ Current problem status is {EVENT.STATUS}, acknowledged: {EVENT.ACK.STATUS}.
+ -
+ event_source: DISCOVERY
+ operation_mode: PROBLEM
+ subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}'
+ message: |
+ Discovery rule: {DISCOVERY.RULE.NAME}
+
+ Device IP: {DISCOVERY.DEVICE.IPADDRESS}
+ Device DNS: {DISCOVERY.DEVICE.DNS}
+ Device status: {DISCOVERY.DEVICE.STATUS}
+ Device uptime: {DISCOVERY.DEVICE.UPTIME}
+
+ Device service name: {DISCOVERY.SERVICE.NAME}
+ Device service port: {DISCOVERY.SERVICE.PORT}
+ Device service status: {DISCOVERY.SERVICE.STATUS}
+ Device service uptime: {DISCOVERY.SERVICE.UPTIME}
+ -
+ event_source: AUTOREGISTRATION
+ operation_mode: PROBLEM
+ subject: 'Autoregistration: {HOST.HOST}'
+ message: |
+ Host name: {HOST.HOST}
+ Host IP: {HOST.IP}
+ Agent port: {HOST.PORT}