Last active
June 1, 2020 22:32
-
-
Save andredeo/54f18c4eca060334e0140864a3cf1fbc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Jira = { | |
params: {}, | |
setParams: function (params) { | |
if (typeof params !== 'object') { | |
return; | |
} | |
Jira.params = params; | |
if (typeof Jira.params.url === 'string') { | |
if (!Jira.params.url.endsWith('/')) { | |
Jira.params.url += '/'; | |
} | |
Jira.params.url += 'rest/api/latest/'; | |
} | |
}, | |
setProxy: function (HTTPProxy) { | |
Jira.HTTPProxy = HTTPProxy; | |
}, | |
setTags: function(event_tags_json) { | |
if (typeof event_tags_json !== 'undefined' && event_tags_json !== '' | |
&& event_tags_json !== '{EVENT.TAGSJSON}') { | |
try { | |
var tags = JSON.parse(event_tags_json), | |
label; | |
Jira.labels = []; | |
tags.forEach(function (tag) { | |
if (typeof tag.tag !== 'undefined' && typeof tag.value !== 'undefined' ) { | |
label = (tag.tag + (tag.value ? (':' + tag.value) : '')).replace(/\s/g, '_'); | |
if (label.length < 256) { | |
Jira.labels.push(label); | |
} | |
} | |
}); | |
} | |
catch (error) { | |
// Code is not missing here. | |
} | |
} | |
}, | |
escapeMarkup: function (str) { | |
var length = str.length, | |
result = '', | |
markup = ['{', '|', '}', '~', '_', '\\', '[', ']', '^', '<', '>', '?', '!', '#', '+', '*', '&']; | |
for (var i = 0; i < length; i++) { | |
var char = str[i]; | |
result += (markup.indexOf(char) !== -1) ? ('&#' + str[i].charCodeAt() + ';') : char; | |
} | |
return result; | |
}, | |
addCustomFields: function (data, fields) { | |
if (typeof fields === 'object' && Object.keys(fields).length) { | |
var schema = Jira.getSchema(), | |
path = ['projects', 0, 'issuetypes', 0, 'fields'], | |
field; | |
while ((field = path.shift()) !== undefined) { | |
schema = schema[field]; | |
if (typeof schema === 'undefined') { | |
schema = null; | |
break; | |
} | |
} | |
if (schema) { | |
Object.keys(fields) | |
.forEach(function(field) { | |
data.fields[field] = fields[field]; | |
if (typeof schema[field] === 'object' && typeof schema[field].schema === 'object' | |
&& (schema[field].schema.type === 'number' || schema[field].schema.type === 'datetime')) { | |
switch (schema[field].schema.type) { | |
case 'number': | |
data.fields[field] = parseInt(fields[field]); | |
break; | |
case 'datetime': | |
if (fields[field].match(/\d+[.-]\d+[.-]\d+T\d+:\d+:\d+/) !== null) { | |
data.fields[field] = fields[field].replace(/\./g, '-'); | |
} | |
else { | |
delete data.fields[field]; | |
} | |
break; | |
} | |
} | |
}); | |
} | |
else { | |
Zabbix.Log(4, '[ Jira Webhook ] Failed to retrieve field schema.'); | |
} | |
} | |
return data; | |
}, | |
request: function (method, query, data) { | |
['url', 'user', 'password', 'project_key', 'issue_type'].forEach(function (field) { | |
if (typeof Jira.params !== 'object' || typeof Jira.params[field] === 'undefined' | |
|| Jira.params[field] === '' ) { | |
throw 'Required Jira param is not set: "' + field + '".'; | |
} | |
}); | |
var response, | |
url = Jira.params.url + query, | |
request = new CurlHttpRequest(); | |
request.AddHeader('Content-Type: application/json'); | |
request.AddHeader('Authorization: Basic ' + btoa(Jira.params.user + ':' + Jira.params.password)); | |
if (typeof Jira.HTTPProxy !== 'undefined' && Jira.HTTPProxy !== '') { | |
request.SetProxy(Jira.HTTPProxy); | |
} | |
if (typeof data !== 'undefined') { | |
data = JSON.stringify(data); | |
} | |
Zabbix.Log(4, '[ Jira Webhook ] Sending request: ' + url + ((typeof data === 'string') ? ('\n' + data) : '')); | |
switch (method) { | |
case 'get': | |
response = request.Get(url, data); | |
break; | |
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, '[ Jira Webhook ] Received response with status code ' + request.Status() + '\n' + response); | |
if (response !== null) { | |
try { | |
response = JSON.parse(response); | |
} | |
catch (error) { | |
Zabbix.Log(4, '[ Jira Webhook ] Failed to parse response received from Jira'); | |
response = null; | |
} | |
} | |
if (request.Status() < 200 || request.Status() >= 300) { | |
var message = 'Request failed with status code ' + request.Status(); | |
if (response !== null && typeof response.errors !== 'undefined' | |
&& Object.keys(response.errors).length > 0) { | |
message += ': ' + JSON.stringify(response.errors); | |
} | |
else if (response !== null && typeof response.errorMessages !== 'undefined' | |
&& Object.keys(response.errorMessages).length > 0) { | |
message += ': ' + JSON.stringify(response.errorMessages); | |
} | |
throw message + ' Check debug log for more information.'; | |
} | |
return { | |
status: request.Status(), | |
response: response | |
}; | |
}, | |
getSchema: function() { | |
var result = Jira.request('get', 'issue/createmeta?expand=projects.issuetypes.fields&projectKeys=' + | |
Jira.params.project_key + '&issuetypeNames=' + Jira.params.issue_type); | |
return result.response; | |
}, | |
createIssue: function(summary, description, fields) { | |
var data = { | |
fields: { | |
project: { | |
key: Jira.params.project_key | |
}, | |
issuetype: { | |
name: Jira.params.issue_type | |
}, | |
summary: summary, | |
description: description | |
} | |
}; | |
if (Jira.labels && Jira.labels.length > 0) { | |
data.fields.labels = Jira.labels; | |
} | |
var result = Jira.request('post', 'issue', Jira.addCustomFields(data, fields)); | |
if (typeof result.response !== 'object' || typeof result.response.key === 'undefined') { | |
throw 'Cannot create Jira issue. Check debug log for more information.'; | |
} | |
return result.response.key; | |
}, | |
updateIssue: function(summary, fields, update) { | |
var data = {fields: {}}; | |
if (summary) { | |
data.fields.summary = summary; | |
} | |
Jira.request('put', 'issue/' + Jira.params.issue_key, Jira.addCustomFields(data, fields)); | |
Jira.commentIssue(update); | |
}, | |
commentIssue: function(update) { | |
var data = {}; | |
if (typeof update === 'string') { | |
data.body = update; | |
Jira.request('post', 'issue/' + Jira.params.issue_key + '/comment', data); | |
} | |
else if (update.status === '1') { | |
data.body = update.user + ' ' + update.action + '.'; | |
if (update.message) { | |
data.body += '\nMessage: {quote}' + Jira.escapeMarkup(update.message) + '{quote}'; | |
} | |
Jira.request('post', 'issue/' + Jira.params.issue_key + '/comment', data); | |
} | |
}, | |
closeIssue: function() { | |
var data = {transition:{id:41}}; | |
Jira.request('post', 'issue/' + Jira.params.issue_key + '/transitions', data); | |
} | |
}; | |
try { | |
var params = JSON.parse(value), | |
fields = {}, | |
jira = {}, | |
update = {}, | |
result = {tags: {}}, | |
required_params = ['alert_subject', 'summary', 'event_recovery_value', 'event_source', 'event_value']; | |
Object.keys(params) | |
.forEach(function (key) { | |
if (key.startsWith('jira_')) { | |
jira[key.substring(5)] = params[key]; | |
} | |
else if (key.startsWith('customfield_')) { | |
fields[key] = params[key]; | |
} | |
else if (key.startsWith('event_update_')) { | |
update[key.substring(13)] = 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.'; | |
} | |
Jira.setParams(jira); | |
Jira.setProxy(params.HTTPProxy); | |
Jira.setTags(params.event_tags_json); | |
// Create issue for non trigger-based events. | |
if (params.event_source !== '0' && params.event_recovery_value !== '0') { | |
Jira.createIssue(params.alert_subject, params.alert_message); | |
} | |
// Create issue for trigger-based events. | |
else if (params.event_value === '1' && update.status === '0' && !jira.issue_key.startsWith(jira.project_key)) { | |
var key = Jira.createIssue(params.alert_subject, | |
(Object.keys(fields).length ? params.trigger_description : params.alert_message), fields); | |
result.tags.__zbx_jira_issuekey = key; | |
result.tags.__zbx_jira_issuelink = params.jira_url + | |
(params.jira_url.endsWith('/') ? '' : '/') + 'browse/' + key; | |
} | |
// Update created issue for trigger-based event. | |
else { | |
if (!jira.issue_key.startsWith(jira.project_key)) { | |
throw 'Incorrect Issue key given: ' + jira.issue_key; | |
} | |
Jira.updateIssue(params.alert_subject, fields, | |
((params.event_value === '0' && !Object.keys(fields).length) | |
? params.alert_message : update)); | |
Jira.closeIssue(); | |
} | |
return JSON.stringify(result); | |
} | |
catch (error) { | |
Zabbix.Log(3, '[ Jira Webhook ] ERROR: ' + error); | |
throw 'Sending failed: ' + error; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment