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
path: root/create
diff options
context:
space:
mode:
authorAleksejs Sestakovs <aleksejs.sestakovs@zabbix.com>2022-09-12 10:20:11 +0300
committerAleksejs Sestakovs <aleksejs.sestakovs@zabbix.com>2022-09-12 10:20:11 +0300
commit88126fce4273f291f6838707a0a88792c931f649 (patch)
tree6464ea6fbe0c214e4472c8a0b03597008cf2e85b /create
parent5db80227fd70e3aedd3d1f1efeb671843095c0c7 (diff)
parentc78c8bd39416db786bfb1b4e8f9579996b8d3ea9 (diff)
.......... [ZBXNEXT-7931] upgraded to master (without conflicts)
Diffstat (limited to 'create')
-rw-r--r--create/src/data.tmpl10
-rw-r--r--create/src/schema.tmpl6
2 files changed, 9 insertions, 7 deletions
diff --git a/create/src/data.tmpl b/create/src/data.tmpl
index 57d338014ca..63c8658a869 100644
--- a/create/src/data.tmpl
+++ b/create/src/data.tmpl
@@ -71,7 +71,7 @@ ROW |7 |4 |PagerDuty | | |
ROW |8 |4 |Pushover | | | | | | | |0 |25 |0 |0 |0 |0 | |0 |3 |10s |1 |try {&eol; var params = JSON.parse(value),&eol; request = new HttpRequest(),&eol; data,&eol; response,&eol; severities = [&eol; {name: 'not_classified', color: '#97AAB3'},&eol; {name: 'information', color: '#7499FF'},&eol; {name: 'warning', color: '#FFC859'},&eol; {name: 'average', color: '#FFA059'},&eol; {name: 'high', color: '#E97659'},&eol; {name: 'disaster', color: '#E45959'},&eol; {name: 'resolved', color: '#009900'},&eol; {name: 'default', color: '#000000'}&eol; ],&eol; priority;&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; request.setProxy(params.HTTPProxy);&eol; }&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';&eol; }&eol;&eol; if (params.event_value !== '0' && params.event_value !== '1'&eol; && (params.event_source === '0' &pipe;&pipe; params.event_source === '3')) {&eol; throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';&eol; }&eol;&eol; if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) {&eol; params.event_nseverity = '7';&eol; }&eol;&eol; if (params.event_value === '0') {&eol; params.event_nseverity = '6';&eol; }&eol;&eol; priority = params['priority_' + severities[params.event_nseverity].name] &pipe;&pipe; params.priority_default;&eol;&eol; if (isNaN(priority) &pipe;&pipe; priority < -2 &pipe;&pipe; priority > 2) {&eol; throw '"priority" should be -2..2';&eol; }&eol;&eol; if (params.event_source === '0' && isNaN(params.triggerid)) {&eol; throw 'field "triggerid" is not a number';&eol; }&eol;&eol; if (isNaN(params.eventid)) {&eol; throw 'field "eventid" is not a number';&eol; }&eol;&eol; if (typeof params.message !== 'string' &pipe;&pipe; params.message.trim() === '') {&eol; throw 'field "message" cannot be empty';&eol; }&eol;&eol; data = {&eol; token: params.token,&eol; user: params.user,&eol; title: params.title,&eol; message: params.message,&eol; url: (params.event_source === '0') &eol; ? params.url + '/tr_events.php?triggerid=' + params.triggerid + '&eventid=' + params.eventid&eol; : params.url,&eol; url_title: params.url_title,&eol; priority: priority&eol; };&eol;&eol; if (priority == 2) {&eol; if (isNaN(params.retry) &pipe;&pipe; params.retry < 30) {&eol; throw 'field "retry" should be a number with value of at least 30 if "priority" is set to 2';&eol; }&eol;&eol; if (isNaN(params.expire) &pipe;&pipe; params.expire > 10800) {&eol; throw 'field "expire" should be a number with value of at most 10800 if "priority" is set to 2';&eol; }&eol;&eol; data.retry = params.retry;&eol; data.expire = params.expire;&eol; }&eol;&eol; data = JSON.stringify(data);&eol; Zabbix.log(4, '[ Pushover Webhook ] Sending request: ' + params.endpoint + '\n' + data);&eol;&eol; request.addHeader('Content-Type: application/json');&eol; response = request.post(params.endpoint, data);&eol;&eol; Zabbix.log(4, '[ Pushover Webhook ] Received response with status code ' + request.getStatus() + '\n' + response);&eol;&eol; if (response !== null) {&eol; try {&eol; response = JSON.parse(response);&eol; }&eol; catch (error) {&eol; Zabbix.log(4, '[ Pushover Webhook ] Failed to parse response received from Pushover');&eol; response = null;&eol; }&eol; }&eol;&eol; if (request.getStatus() != 200 &pipe;&pipe; response === null &pipe;&pipe; typeof response !== 'object' &pipe;&pipe; response.status !== 1) {&eol; if (response !== null && typeof response === 'object' && typeof response.errors === 'object'&eol; && typeof response.errors[0] === 'string') {&eol; throw response.errors[0];&eol; }&eol; else {&eol; throw 'Unknown error. Check debug log for more information.';&eol; }&eol; }&eol;&eol; return 'OK';&eol;}&eol;catch (error) {&eol; Zabbix.log(4, '[ Pushover Webhook ] Pushover notification failed: ' + error);&eol; throw 'Pushover notification failed: ' + error;&eol;}|30s |0 |0 | | |Please refer to setup guide here: https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/pushover&eol;&eol;Set token parameter with to your Pushover application key.&eol;When assigning Pushover media to the Zabbix user - add user key into send to field. |
ROW |9 |4 |Slack | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |var SEVERITY_COLORS = [&eol; '#97AAB3', '#7499FF', '#FFC859',&eol; '#FFA059', '#E97659', '#E45959'&eol;];&eol;&eol;var RESOLVE_COLOR = '#009900';&eol;&eol;var SLACK_MODE_HANDLERS = {&eol; alarm: handlerAlarm,&eol; event: handlerEvent&eol;};&eol;&eol;&eol;if (!String.prototype.format) {&eol; String.prototype.format = function() {&eol; var args = arguments;&eol;&eol; return this.replace(/{(\d+)}/g, function(match, number) {&eol; return number in args&eol; ? args[number]&eol; : match&eol; ;&eol; });&eol; };&eol;}&eol;&eol;function isEventProblem(params) {&eol; return params.event_value == 1&eol; && params.event_update_status == 0&eol; ;&eol;}&eol;&eol;function isEventUpdate(params) {&eol; return params.event_value == 1&eol; && params.event_update_status == 1&eol; ;&eol;}&eol;&eol;function isEventResolve(params) {&eol; return params.event_value == 0;&eol;}&eol;&eol;function getPermalink(channelId, messageTimestamp) {&eol; var req = new HttpRequest();&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; req.setProxy(params.HTTPProxy);&eol; }&eol;&eol; req.addHeader('Content-Type: application/x-www-form-urlencoded; charset=utf-8');&eol; req.addHeader('Authorization: Bearer ' + params.bot_token);&eol;&eol; var query = '{0}?channel={1}&message_ts={2}'.format(&eol; Slack.getPermalink,&eol; encodeURIComponent(channelId),&eol; encodeURIComponent(messageTimestamp)),&eol; resp = JSON.parse(req.get(query));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw 'message was created, but getting message link was failed with reason "' + resp.error + '"';&eol; }&eol;&eol; return resp.permalink;&eol;}&eol;&eol;function createProblemURL(zabbix_url, triggerid, eventid, event_source) {&eol; var problem_url = '';&eol; if (event_source === '0') {&eol; problem_url = '{0}/tr_events.php?triggerid={1}&eventid={2}'&eol; .format(&eol; zabbix_url,&eol; triggerid,&eol; eventid&eol; );&eol; }&eol; else {&eol; problem_url = zabbix_url;&eol; }&eol;&eol; return problem_url;&eol;}&eol;&eol;function handlerAlarm(params) {&eol; var fields = {&eol; channel: params.channel,&eol; as_user: params.slack_as_user,&eol; };&eol;&eol; if (isEventProblem(params)) {&eol; fields.attachments = [&eol; createMessage(&eol; SEVERITY_COLORS[params.event_nseverity] &pipe;&pipe; 0,&eol; params.event_date,&eol; params.event_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)&eol; )&eol; ];&eol;&eol; var resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol;&eol; result.tags = {&eol; ['__message_ts_' + params.channel]: resp.ts,&eol; ['__channel_id_' + params.channel]: resp.channel,&eol; ['__message_link_' + params.channel]: getPermalink(resp.channel, resp.ts),&eol; };&eol;&eol; }&eol; else if (isEventUpdate(params)) {&eol; try {&eol; var channel_event_tags = JSON.parse(params.event_tags);&eol; } catch (error) {&eol; throw 'Cannot process event tags: ' + error;&eol; }&eol;&eol; if (Array.isArray(channel_event_tags)) {&eol; for (i in channel_event_tags) {&eol; if (channel_event_tags[i].tag.includes('__message_ts_' + params.channel)) {&eol; fields.thread_ts = channel_event_tags[i].value;&eol; break;&eol; }&eol; }&eol; }&eol;&eol; fields.attachments = [&eol; createMessage(&eol; SEVERITY_COLORS[params.event_nseverity] &pipe;&pipe; 0,&eol; params.event_update_date,&eol; params.event_update_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),&eol; true&eol; )&eol; ];&eol;&eol; resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol;&eol; }&eol; else if (isEventResolve(params)) {&eol;&eol; fields.text = '';&eol;&eol; try {&eol; var channel_event_tags = JSON.parse(params.event_tags);&eol; } catch (error) {&eol; throw 'Cannot process event tags: ' + error;&eol; }&eol;&eol; if (Array.isArray(channel_event_tags)) {&eol; for (i in channel_event_tags) {&eol; if (channel_event_tags[i].tag.includes('__channel_id_' + params.channel)) {&eol; fields.channel = channel_event_tags[i].value;&eol; continue;&eol; }&eol; if (channel_event_tags[i].tag.includes('__message_ts_' + params.channel)) {&eol; fields.ts = channel_event_tags[i].value;&eol; }&eol; }&eol; }&eol;&eol; fields.attachments = [&eol; createMessage(&eol; RESOLVE_COLOR,&eol; params.event_date,&eol; params.event_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)&eol; )&eol; ];&eol;&eol; resp = JSON.parse(req.post(Slack.chatUpdate, JSON.stringify(fields)));&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol; }&eol;}&eol;&eol;function handlerEvent(params) {&eol; var fields = {&eol; channel: params.channel,&eol; as_user: params.slack_as_user&eol; };&eol;&eol; if (isEventProblem(params)) {&eol; fields.attachments = [&eol; createMessage(&eol; SEVERITY_COLORS[params.event_nseverity] &pipe;&pipe; 0,&eol; params.event_date,&eol; params.event_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)&eol; )&eol; ];&eol;&eol; var resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol;&eol; result.tags = {&eol; ['__message_link_' + params.channel]: getPermalink(resp.channel, resp.ts)&eol; }&eol;&eol; }&eol; else if (isEventUpdate(params)) {&eol; fields.attachments = [&eol; createMessage(&eol; SEVERITY_COLORS[params.event_nseverity] &pipe;&pipe; 0,&eol; params.event_update_date,&eol; params.event_update_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),&eol; false&eol; )&eol; ];&eol;&eol; resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol;&eol; }&eol; else if (isEventResolve(params)) {&eol; fields.attachments = [&eol; createMessage(&eol; RESOLVE_COLOR,&eol; params.event_recovery_date,&eol; params.event_recovery_time,&eol; createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)&eol; )&eol; ];&eol;&eol; resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));&eol;&eol; if (req.getStatus() != 200 &pipe;&pipe; !resp.ok &pipe;&pipe; resp.ok === 'false') {&eol; throw resp.error;&eol; }&eol; }&eol;}&eol;&eol;function createMessage(&eol; event_severity_color,&eol; event_date,&eol; event_time,&eol; problem_url,&eol; isShort,&eol; messageText&eol;) {&eol; var message = {&eol; fallback: params.alert_subject,&eol; title: params.alert_subject,&eol; color: event_severity_color,&eol; title_link: problem_url,&eol; pretext: messageText &pipe;&pipe; '',&eol;&eol; fields: [&eol; {&eol; title: 'Host',&eol; value: '{0} [{1}]'.format(params.host_name, params.host_conn),&eol; short: true&eol; },&eol; {&eol; title: 'Event time',&eol; value: '{0} {1}'.format(event_date, event_time),&eol; short: true&eol; }&eol; ],&eol; };&eol;&eol; if (params.event_source === '0') {&eol; message.fields.push(&eol; {&eol; title: 'Severity',&eol; value: params.event_severity,&eol; short: true&eol; },&eol; {&eol; title: 'Opdata',&eol; value: params.event_opdata,&eol; short: true&eol; }&eol; );&eol; }&eol;&eol; if (!isShort && params.event_source === '0') {&eol; message['actions'] = [&eol; {&eol; type: 'button',&eol; text: 'Open in Zabbix',&eol; url: problem_url&eol; }&eol; ];&eol;&eol; message.fields.push(&eol; {&eol; title: 'Event tags',&eol; value: JSON.parse(params.event_tags).filter(function (e) { return !e.tag.includes('__') }).map(function (e) { return e.tag + ': ' + e.value }).join('\n') &pipe;&pipe; 'None',&eol; short: true&eol; },&eol; {&eol; title: 'Trigger description',&eol; value: params.trigger_description,&eol; short: true&eol; }&eol; );&eol; }&eol;&eol; if (params.event_source !== '0' &pipe;&pipe; params.event_update_status === '1') {&eol; message.fields.push(&eol; {&eol; title: 'Details',&eol; value: params.alert_message,&eol; short: false&eol; }&eol; );&eol; }&eol;&eol; return message;&eol;}&eol;&eol;function validateParams(params) {&eol; if (typeof params.bot_token !== 'string' &pipe;&pipe; params.bot_token.trim() === '') {&eol; throw 'Field "bot_token" cannot be empty';&eol; }&eol;&eol; if (typeof params.channel !== 'string' &pipe;&pipe; params.channel.trim() === '') {&eol; throw 'Field "channel" cannot be empty';&eol; }&eol;&eol; if (isNaN(params.event_id)) {&eol; throw 'Field "event_id" is not a number';&eol; }&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';&eol; }&eol;&eol; if (params.event_source !== '0') {&eol; params.event_nseverity = '0';&eol; params.event_severity = 'Not classified';&eol; params.event_update_status = '0';&eol; params.slack_mode = 'event';&eol; }&eol;&eol; if (params.event_source === '1' &pipe;&pipe; params.event_source === '2') {&eol; params.event_value = '1';&eol; }&eol;&eol; if (params.event_source === '1') {&eol; params.host_name = params.discovery_host_dns;&eol; params.host_ip = params.discovery_host_ip;&eol; }&eol;&eol; if (!~[0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity))) {&eol; throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';&eol; }&eol;&eol; if (typeof params.event_severity !== 'string' &pipe;&pipe; params.event_severity.trim() === '') {&eol; throw 'Field "event_severity" cannot be empty';&eol; }&eol;&eol; if (params.event_update_status !== '0' && params.event_update_status !== '1') {&eol; throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';&eol; }&eol;&eol; if (params.event_value !== '0' && params.event_value !== '1') {&eol; throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';&eol; }&eol;&eol; if (typeof params.host_conn !== 'string' &pipe;&pipe; params.host_conn.trim() === '') {&eol; throw 'Field "host_conn" cannot be empty';&eol; }&eol;&eol; if (typeof params.host_name !== 'string' &pipe;&pipe; params.host_name.trim() === '') {&eol; throw 'Field "host_name" cannot be empty';&eol; }&eol;&eol; if (!~['true', 'false'].indexOf(params.slack_as_user.toLowerCase())) {&eol; throw 'Incorrect "slack_as_user" parameter given: ' + params.slack_as_user + '\nMust be "true" or "false".';&eol; }&eol;&eol; if (!~['alarm', 'event'].indexOf(params.slack_mode)) {&eol; throw 'Incorrect "slack_mode" parameter given: ' + params.slack_mode + '\nMust be "alarm" or "event".';&eol; }&eol;&eol; if (isNaN(params.trigger_id) && params.event_source === '0') {&eol; throw 'field "trigger_id" is not a number';&eol; }&eol;&eol; if (typeof params.zabbix_url !== 'string' &pipe;&pipe; params.zabbix_url.trim() === '') {&eol; throw 'Field "zabbix_url" cannot be empty';&eol; }&eol;&eol; if (!/^(http&pipe;https):\/\/.+/.test(params.zabbix_url)) {&eol; throw 'Field "zabbix_url" must contain a schema';&eol; }&eol;}&eol;&eol;try {&eol; var params = JSON.parse(value);&eol;&eol; validateParams(params);&eol;&eol; var req = new HttpRequest(),&eol; result = {tags: {}};&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; req.setProxy(params.HTTPProxy);&eol; }&eol;&eol; req.addHeader('Content-Type: application/json; charset=utf-8');&eol; req.addHeader('Authorization: Bearer ' + params.bot_token);&eol;&eol; var slack_endpoint = 'https://slack.com/api/';&eol;&eol; var Slack = {&eol; postMessage: slack_endpoint + 'chat.postMessage',&eol; getPermalink: slack_endpoint + 'chat.getPermalink',&eol; chatUpdate: slack_endpoint + 'chat.update'&eol; };&eol;&eol; params.slack_mode = params.slack_mode.toLowerCase();&eol; params.slack_mode = params.slack_mode in SLACK_MODE_HANDLERS&eol; ? params.slack_mode&eol; : 'alarm';&eol;&eol; SLACK_MODE_HANDLERS[params.slack_mode](params);&eol;&eol; if (params.event_source === '0') {&eol; return JSON.stringify(result);&eol; }&eol; else {&eol; return 'OK';&eol; }&eol;}&eol;catch (error) {&eol; Zabbix.log(4, '[ Slack Webhook ] Slack notification failed : ' + error);&eol; throw 'Slack notification failed : ' + error;&eol;}|30s |1 |0 | | | |
ROW |10 |4 |Discord | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |var SEVERITY_COLORS = [&eol; '#97AAB3', // Not classified.&eol; '#7499FF', // Information.&eol; '#FFC859', // Warning.&eol; '#FFA059', // Average.&eol; '#E97659', // High.&eol; '#E45959', // Disaster.&eol; '#009900' // Resolved.&eol;];&eol;&eol;function stringTruncate(str, len) {&eol; return str.length > len ? str.substring(0, len - 3) + '...' : str;&eol;}&eol;&eol;try {&eol; Zabbix.log(4, '[ Discord Webhook ] Executed with params: ' + value);&eol;&eol; var params = JSON.parse(value);&eol;&eol; if (!params.discord_endpoint) {&eol; throw 'Cannot get discord_endpoint';&eol; }&eol; else {&eol; params.discord_endpoint = params.discord_endpoint.replace('/api/', '/api/v7/') + '?wait=True';&eol; }&eol;&eol; params.zabbix_url = (params.zabbix_url.endsWith('/'))&eol; ? params.zabbix_url.slice(0, -1) : params.zabbix_url;&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';&eol; }&eol;&eol; // Set params to true for non trigger-based events.&eol; if (params.event_source !== '0') {&eol; params.use_default_message = 'true';&eol; params.event_nseverity = '0';&eol; }&eol;&eol; // Check {EVENT.VALUE} for trigger-based and internal events.&eol; if (params.event_value !== '0' && params.event_value !== '1'&eol; && (params.event_source === '0' &pipe;&pipe; params.event_source === '3')) {&eol; throw 'Incorrect "event_value" parameter given: "' + params.event_value + '".\nMust be 0 or 1.';&eol; }&eol;&eol; // Check {EVENT.UPDATE.STATUS} only for trigger-based events.&eol; if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {&eol; throw 'Incorrect "event_update_status" parameter given: "' + params.event_update_status + '".\nMust be 0 or 1.';&eol; }&eol;&eol; if (params.event_value == 0) {&eol; params.event_nseverity = '6';&eol; }&eol;&eol; if (!SEVERITY_COLORS[params.event_nseverity]) {&eol; throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';&eol; }&eol;&eol; var color = parseInt(SEVERITY_COLORS[params.event_nseverity].replace('#', ''), 16),&eol; fields = [],&eol; body = {&eol; embeds: [&eol; {&eol; color: color &pipe;&pipe; 0,&eol; url: (params.event_source === '0')&eol; ? params.zabbix_url + '/tr_events.php?triggerid=' + params.trigger_id +&eol; '&eventid=' + params.event_id&eol; : params.zabbix_url&eol; }&eol; ]&eol; };&eol;&eol; // Default message from {ALERT.MESSAGE}.&eol; if (params.use_default_message.toLowerCase() == 'true') {&eol; body.embeds[0].title = stringTruncate(params.alert_subject, 256);&eol; body.embeds[0].description = stringTruncate(params.alert_message, 2048);&eol; }&eol; else {&eol; fields.push(&eol; {&eol; name: 'Host',&eol; value: params.host_name + ' [' + params.host_ip + ']'&eol; }&eol; );&eol;&eol; // Resolved message.&eol; if (params.event_value == 0 && params.event_update_status == 0) {&eol; body.embeds[0].title = stringTruncate('OK: ' + params.event_name, 256);&eol; fields.push(&eol; {&eol; name: 'Recovery time',&eol; value: params.event_recovery_time + ' ' + params.event_recovery_date,&eol; inline: 'True'&eol; }&eol; );&eol; }&eol;&eol; // Problem message.&eol; else if (params.event_value == 1 && params.event_update_status == 0) {&eol; body.embeds[0].title = stringTruncate('PROBLEM: ' + params.event_name, 256);&eol; fields.push(&eol; {&eol; name: 'Event time',&eol; value: params.event_time + ' ' + params.event_date,&eol; inline: 'True'&eol; }&eol; );&eol; }&eol;&eol; // Update message.&eol; else if (params.event_update_status == 1) {&eol; body.embeds[0].title = stringTruncate('UPDATE: ' + params.event_name, 256);&eol; body.embeds[0].description = params.event_update_user + ' ' + params.event_update_action + '.';&eol;&eol; if (params.event_update_message) {&eol; body.embeds[0].description += ' Comment:\n>>> ' + params.event_update_message;&eol; }&eol;&eol; body.embeds[0].description = stringTruncate(body.embeds[0].description, 2048);&eol;&eol; fields.push(&eol; {&eol; name: 'Event update time',&eol; value: params.event_update_time + ' ' + params.event_update_date,&eol; inline: 'True'&eol; }&eol; );&eol; }&eol;&eol; fields.push(&eol; {&eol; name: 'Severity',&eol; value: params.event_severity,&eol; inline: 'True'&eol; }&eol; );&eol;&eol; if (params.event_opdata) {&eol; fields.push(&eol; {&eol; name: 'Operational data',&eol; value: stringTruncate(params.event_opdata, 1024),&eol; inline: 'True'&eol; }&eol; );&eol; }&eol;&eol; if (params.event_value == 1 && params.event_update_status == 0 && params.trigger_description) {&eol; fields.push(&eol; {&eol; name: 'Trigger description',&eol; value: stringTruncate(params.trigger_description, 1024)&eol; }&eol; );&eol; }&eol;&eol; body.embeds[0].footer = {&eol; text: 'Event ID: ' + params.event_id&eol; };&eol;&eol; if (params.event_tags) {&eol; body.embeds[0].footer.text += '\nEvent tags: ' + params.event_tags;&eol; }&eol; body.embeds[0].footer.text = stringTruncate(body.embeds[0].footer.text, 2048);&eol; }&eol;&eol; if (fields.length > 0) {&eol; body.embeds[0].fields = fields;&eol; }&eol;&eol; var req = new HttpRequest();&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; req.setProxy(params.HTTPProxy);&eol; }&eol;&eol; req.addHeader('Content-Type: application/json');&eol;&eol; var resp = req.post(params.discord_endpoint, JSON.stringify(body)),&eol; data = JSON.parse(resp);&eol;&eol; Zabbix.log(4, '[ Discord Webhook ] JSON: ' + JSON.stringify(body));&eol; Zabbix.log(4, '[ Discord Webhook ] Response: ' + resp);&eol;&eol; if (data.id) {&eol; return resp;&eol; }&eol; else {&eol; var message = ((typeof data.message === 'string') ? data.message : 'Unknown error');&eol;&eol; Zabbix.log(3, '[ Discord Webhook ] FAILED with response: ' + resp);&eol; throw message + '. For more details check zabbix server log.';&eol; }&eol;}&eol;catch (error) {&eol; Zabbix.log(3, '[ Discord Webhook ] ERROR: ' + error);&eol; throw 'Sending failed: ' + error;&eol;}|30s |0 |0 | | | |
-ROW |11 |4 |SIGNL4 | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |// SIGNL4 Webhook&eol;try {&eol; var response,&eol; payload,&eol; params = JSON.parse(value),&eol; endpoint = 'https://connect.signl4.com/webhook/',&eol; request = new HttpRequest();&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; request.setProxy(params.HTTPProxy);&eol; }&eol;&eol; if (typeof params.teamsecret === 'string' && params.teamsecret.trim() !== '') {&eol; endpoint += params.teamsecret;&eol; delete params.teamsecret;&eol; }&eol; else {&eol; throw 'The team secret of your SIGNL4 team cannot be empty.';&eol; }&eol;&eol; if (typeof params.Severity === 'string' && params.Severity === '{EVENT.SEVERITY}') {&eol; params.Severity = 'Not classified';&eol; }&eol;&eol; if (typeof params.User === 'string' && params.User === '{USER.FULLNAME}') {&eol; params.User = '';&eol; }&eol;&eol; if (typeof params.Event_Update_Action === 'string' && params.Event_Update_Action === '{EVENT.UPDATE.ACTION}') {&eol; params.Event_Update_Action = '';&eol; }&eol;&eol; // Assemble X-S4-ExternalID for two-way integration&eol; // Format: "ZabbixEventID: 222 ZabbixURL: https://your-zabbix-server/zabbix/"&eol; params['X-S4-ExternalID'] = 'ZabbixEventID: ' + params.Event_ID;&eol; if (typeof params.Zabbix_URL === 'string' && params.Zabbix_URL.indexOf('http') == 0) {&eol; // Make sure the URL ends with '/'&eol; if (params.Zabbix_URL.charAt(params.Zabbix_URL.length - 1) != '/') {&eol; params.Zabbix_URL = params.Zabbix_URL + '/';&eol; }&eol;&eol; params['X-S4-ExternalID'] = params['X-S4-ExternalID'] + ' ZabbixURL: ' + params.Zabbix_URL;&eol;&eol; // Add Link parameter&eol; params['Link'] = params.Zabbix_URL + "tr_events.php?triggerid="+params.Trigger_ID + "&eventid=" + params.Event_ID;&eol; }&eol;&eol; // Check if this is a new problem or a recovery&eol; if (params.Trigger_Status == 'OK') {&eol; params['X-S4-Status'] = 'resolved';&eol; }&eol; else {&eol; params['X-S4-Status'] = 'new';&eol; }&eol;&eol; payload = JSON.stringify(params);&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] Sending request: ' + payload);&eol;&eol; request.addHeader('Content-Type: application/json');&eol; response = request.post(endpoint, 'payload=' + payload);&eol;&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] Received response with status code ' +&eol; request.getStatus() + '\n' + response&eol; );&eol;&eol; if (request.getStatus() !== 201) {&eol; throw 'Request failed with status code ' + request.getStatus() +&eol; '. Check debug log for more information.';&eol; }&eol;&eol; return 'OK';&eol;}&eol;catch (error) {&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] ERROR: ' + error);&eol;&eol; throw 'Sending failed: ' + error;&eol;}|30s |0 |0 | | |SIGNL4 is a mobile alert notification app for powerful alerting, alert management and mobile assignment of work items. It offers alerting via app push, SMS and voice calls including escalations, tracking, and duty scheduling.&eol;&eol;Get the app at https://www.signl4.com.&eol;&eol;Find out more including an integration video here: https://www.signl4.com/blog/portfolio_item/zabbix-mobile-alert-notification-duty-schedule-escalation/ |
+ROW |11 |4 |SIGNL4 | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |// SIGNL4 Webhook&eol;try {&eol; var response,&eol; payload,&eol; params = JSON.parse(value),&eol; endpoint = 'https://connect.signl4.com/webhook/',&eol; request = new HttpRequest();&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {&eol; request.setProxy(params.HTTPProxy);&eol; }&eol;&eol; if (typeof params.teamsecret === 'string' && params.teamsecret.trim() !== '') {&eol; endpoint += params.teamsecret;&eol; delete params.teamsecret;&eol; }&eol; else {&eol; throw 'The team secret of your SIGNL4 team cannot be empty.';&eol; }&eol;&eol; if (typeof params.Severity === 'string' && params.Severity === '{EVENT.SEVERITY}') {&eol; params.Severity = 'Not classified';&eol; }&eol;&eol;if (typeof params.User === 'string' && params.User === '{USER.FULLNAME}') {&eol; params.User = '';&eol; }&eol;&eol;if (typeof params.Event_Update_Action === 'string' && params.Event_Update_Action === '{EVENT.UPDATE.ACTION}') {&eol; params.Event_Update_Action = '';&eol; }&eol;&eol;// Assemble X-S4-ExternalID for two-way integration&eol;// Format: "ZabbixEventID: 222 ZabbixURL: https://your-zabbix-server/zabbix/"&eol;params['X-S4-ExternalID'] = 'ZabbixEventID: ' + params.Event_ID;&eol;if (typeof params.Zabbix_URL === 'string' && params.Zabbix_URL.indexOf('http') == 0) {&eol;// Make sure the URL ends with '/'&eol;if (params.Zabbix_URL.charAt(params.Zabbix_URL.length - 1) != '/') {&eol;params.Zabbix_URL = params.Zabbix_URL + '/';&eol;}&eol;&eol;params['X-S4-ExternalID'] = params['X-S4-ExternalID'] + ' ZabbixURL: ' + params.Zabbix_URL;&eol;&eol;// Add Link parameter&eol;params['Link'] = params.Zabbix_URL + "tr_events.php?triggerid="+params.Trigger_ID + "&eventid=" + params.Event_ID;&eol;}&eol;&eol;// Check if this is a new problem or a recovery&eol;if (params.Trigger_Status == 'OK') {&eol;params['X-S4-Status'] = 'resolved';&eol;}&eol;else {&eol;params['X-S4-Status'] = 'new';&eol;}&eol;&eol; payload = JSON.stringify(params);&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] Sending request: ' + payload);&eol;&eol; request.addHeader('Content-Type: application/json');&eol; response = request.post(endpoint, 'payload=' + payload);&eol;&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] Received response with status code ' +&eol; request.getStatus() + '\n' + response&eol; );&eol;&eol; if (request.getStatus() !== 201) {&eol; throw 'Request failed with status code ' + request.getStatus() +&eol; '. Check debug log for more information.';&eol; }&eol;&eol; return 'OK';&eol;}&eol;catch (error) {&eol; Zabbix.log(4, '[ SIGNL4 Webhook ] ERROR: ' + error);&eol;&eol; throw 'Sending failed: ' + error;&eol;}|30s |0 |0 | | |SIGNL4 is a mobile alert notification app for powerful alerting, alert management and mobile assignment of work items. It offers alerting via app push, SMS and voice calls including escalations, tracking, and duty scheduling.&eol;&eol;Get the app at https://www.signl4.com.&eol;&eol;Find out more including an integration video here: https://www.signl4.com/blog/portfolio_item/zabbix-mobile-alert-notification-duty-schedule-escalation/ |
ROW |12 |4 |Jira | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |var Jira = {&eol; params: {},&eol;&eol; setParams: function (params) {&eol; if (typeof params !== 'object') {&eol; return;&eol; }&eol;&eol; Jira.params = params;&eol; if (typeof Jira.params.url === 'string') {&eol; if (!Jira.params.url.endsWith('/')) {&eol; Jira.params.url += '/';&eol; }&eol;&eol; Jira.params.url += 'rest/api/latest/';&eol; }&eol; },&eol;&eol; setProxy: function (HTTPProxy) {&eol; Jira.HTTPProxy = HTTPProxy;&eol; },&eol;&eol; setTags: function(event_tags_json) {&eol; if (typeof event_tags_json !== 'undefined' && event_tags_json !== ''&eol; && event_tags_json !== '{EVENT.TAGSJSON}') {&eol; try {&eol; var tags = JSON.parse(event_tags_json),&eol; label;&eol;&eol; Jira.labels = [];&eol;&eol; tags.forEach(function (tag) {&eol; if (typeof tag.tag !== 'undefined' && typeof tag.value !== 'undefined'&eol; && !tag.tag.startsWith('__zbx')) {&eol; label = (tag.tag + (tag.value ? (':' + tag.value) : '')).replace(/\s/g, '_');&eol; if (label.length < 256) {&eol; Jira.labels.push(label);&eol; }&eol; }&eol; });&eol; }&eol; catch (error) {&eol; // Code is not missing here.&eol; }&eol; }&eol; },&eol;&eol; escapeMarkup: function (str) {&eol; var length = str.length,&eol; result = '',&eol; markup = ['{', '&pipe;', '}', '~', '_', '\\', '[', ']', '^', '<', '>', '?', '!', '#', '+', '*', '&'];&eol;&eol; for (var i = 0; i < length; i++) {&eol; var char = str[i];&eol;&eol; result += (markup.indexOf(char) !== -1) ? ('&#' + str[i].charCodeAt() + ';') : char;&eol; }&eol;&eol; return result;&eol; },&eol;&eol; addCustomFields: function (data, fields) {&eol; if (typeof fields === 'object' && Object.keys(fields).length) {&eol; var schema = Jira.getSchema(),&eol; path = ['projects', 0, 'issuetypes', 0, 'fields'],&eol; field;&eol;&eol; while ((field = path.shift()) !== undefined) {&eol; schema = schema[field];&eol; if (typeof schema === 'undefined') {&eol; schema = null;&eol; break;&eol; }&eol; }&eol;&eol; if (schema) {&eol; Object.keys(fields)&eol; .forEach(function(field) {&eol; if (typeof schema[field] === 'object' && typeof schema[field].schema === 'object') {&eol; switch (schema[field].schema.type) {&eol; case 'number':&eol; data.fields[field] = parseInt(fields[field]);&eol; break;&eol;&eol; case 'datetime':&eol; if (fields[field].match(/\d+[.-]\d+[.-]\d+T\d+:\d+:\d+/) !== null) {&eol; data.fields[field] = fields[field].replace(/\./g, '-');&eol; }&eol; break;&eol;&eol; case 'option':&eol; data.fields[field] = {value: fields[field]};&eol; break;&eol;&eol; case 'array':&eol; if (schema[field].schema.items === 'option') {&eol; data.fields[field] = [{value: fields[field]}];&eol; }&eol; else {&eol; data.fields[field] = [fields[field]];&eol; }&eol; break;&eol;&eol; default:&eol; data.fields[field] = fields[field];&eol; }&eol; }&eol; });&eol; }&eol; else {&eol; Zabbix.log(4, '[ Jira Webhook ] Failed to retrieve field schema.');&eol; }&eol; }&eol;&eol; return data;&eol; },&eol;&eol; request: function (method, query, data) {&eol; ['url', 'user', 'password', 'project_key', 'issue_type'].forEach(function (field) {&eol; if (typeof Jira.params !== 'object' &pipe;&pipe; typeof Jira.params[field] === 'undefined'&eol; &pipe;&pipe; Jira.params[field] === '' ) {&eol; throw 'Required Jira param is not set: "' + field + '".';&eol; }&eol; });&eol;&eol; var response,&eol; url = Jira.params.url + query,&eol; request = new HttpRequest();&eol;&eol; request.addHeader('Content-Type: application/json');&eol; request.addHeader('Authorization: Basic ' + btoa(Jira.params.user + ':' + Jira.params.password));&eol;&eol; if (typeof Jira.HTTPProxy !== 'undefined' && Jira.HTTPProxy !== '') {&eol; request.setProxy(Jira.HTTPProxy);&eol; }&eol;&eol; if (typeof data !== 'undefined') {&eol; data = JSON.stringify(data);&eol; }&eol;&eol; Zabbix.log(4, '[ Jira Webhook ] Sending request: ' + url + ((typeof data === 'string') ? ('\n' + data) : ''));&eol;&eol; switch (method) {&eol; case 'get':&eol; response = request.get(url, data);&eol; break;&eol;&eol; case 'post':&eol; response = request.post(url, data);&eol; break;&eol;&eol; case 'put':&eol; response = request.put(url, data);&eol; break;&eol;&eol; default:&eol; throw 'Unsupported HTTP request method: ' + method;&eol; }&eol;&eol; Zabbix.log(4, '[ Jira Webhook ] Received response with status code ' + request.getStatus() + '\n' + response);&eol;&eol; if (response !== null) {&eol; try {&eol; response = JSON.parse(response);&eol; }&eol; catch (error) {&eol; Zabbix.log(4, '[ Jira Webhook ] Failed to parse response received from Jira');&eol; response = null;&eol; }&eol; }&eol;&eol; if (request.getStatus() < 200 &pipe;&pipe; request.getStatus() >= 300) {&eol; var message = 'Request failed with status code ' + request.getStatus();&eol;&eol; if (response !== null && typeof response.errors !== 'undefined'&eol; && Object.keys(response.errors).length > 0) {&eol; message += ': ' + JSON.stringify(response.errors);&eol; }&eol; else if (response !== null && typeof response.errorMessages !== 'undefined'&eol; && Object.keys(response.errorMessages).length > 0) {&eol; message += ': ' + JSON.stringify(response.errorMessages);&eol; }&eol;&eol; throw message + ' Check debug log for more information.';&eol; }&eol;&eol; return {&eol; status: request.getStatus(),&eol; response: response&eol; };&eol; },&eol;&eol; getSchema: function() {&eol; var result = Jira.request('get', 'issue/createmeta?expand=projects.issuetypes.fields&projectKeys=' +&eol; encodeURIComponent(Jira.params.project_key) + '&issuetypeNames=' +&eol; encodeURIComponent(Jira.params.issue_type));&eol;&eol; return result.response;&eol; },&eol;&eol; createIssue: function(summary, description, fields) {&eol; var data = {&eol; fields: {&eol; project: {&eol; key: Jira.params.project_key&eol; },&eol; issuetype: {&eol; name: Jira.params.issue_type&eol; },&eol; summary: summary,&eol; description: description&eol; }&eol; };&eol;&eol; if (Jira.labels && Jira.labels.length > 0) {&eol; data.fields.labels = Jira.labels;&eol; }&eol; var result = Jira.request('post', 'issue', Jira.addCustomFields(data, fields));&eol;&eol; if (typeof result.response !== 'object' &pipe;&pipe; typeof result.response.key === 'undefined') {&eol; throw 'Cannot create Jira issue. Check debug log for more information.';&eol; }&eol;&eol; return result.response.key;&eol; },&eol;&eol; updateIssue: function(summary, fields, update) {&eol; var data = {fields: {}};&eol;&eol; if (summary) {&eol; data.fields.summary = summary;&eol; }&eol;&eol; Jira.request('put', 'issue/' + encodeURIComponent(Jira.params.issue_key), Jira.addCustomFields(data, fields));&eol; Jira.commentIssue(update);&eol; },&eol;&eol; commentIssue: function(update) {&eol; var data = {};&eol;&eol; if (typeof update === 'string') {&eol; data.body = update;&eol; Jira.request('post', 'issue/' + encodeURIComponent(Jira.params.issue_key) + '/comment', data);&eol; }&eol; else if (update.status === '1') {&eol; data.body = update.user + ' ' + update.action + '.';&eol;&eol; if (update.message) {&eol; data.body += '\nMessage: {quote}' + Jira.escapeMarkup(update.message) + '{quote}';&eol; }&eol;&eol; Jira.request('post', 'issue/' + encodeURIComponent(Jira.params.issue_key) + '/comment', data);&eol; }&eol; }&eol;};&eol;&eol;try {&eol; var params = JSON.parse(value),&eol; fields = {},&eol; jira = {},&eol; update = {},&eol; result = {tags: {}},&eol; required_params = ['alert_subject', 'summary', 'event_recovery_value', 'event_source', 'event_value'];&eol;&eol; Object.keys(params)&eol; .forEach(function (key) {&eol; if (key.startsWith('jira_')) {&eol; jira[key.substring(5)] = params[key];&eol; }&eol; else if (key.startsWith('customfield_')) {&eol; fields[key] = params[key];&eol; }&eol; else if (key.startsWith('event_update_')) {&eol; update[key.substring(13)] = params[key];&eol; }&eol; else if (required_params.indexOf(key) !== -1 && params[key] === '') {&eol; throw 'Parameter "' + key + '" can\'t be empty.';&eol; }&eol; });&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: ' + params.event_source + '\nMust be 0-3.';&eol; }&eol;&eol; // Check {EVENT.VALUE} for trigger-based and internal events.&eol; if (params.event_value !== '0' && params.event_value !== '1'&eol; && (params.event_source === '0' &pipe;&pipe; params.event_source === '3')) {&eol; throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';&eol; }&eol;&eol; // Check {EVENT.UPDATE.STATUS} only for trigger-based events.&eol; if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {&eol; throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';&eol; }&eol;&eol; if (params.event_source !== '0' && params.event_recovery_value === '0') {&eol; throw 'Recovery operations are supported only for trigger-based actions.';&eol; }&eol;&eol; Jira.setParams(jira);&eol; Jira.setProxy(params.HTTPProxy);&eol; Jira.setTags(params.event_tags_json);&eol;&eol; // Create issue for non trigger-based events.&eol; if (params.event_source !== '0' && params.event_recovery_value !== '0') {&eol; Jira.createIssue(params.alert_subject, params.alert_message);&eol; }&eol; // Create issue for trigger-based events.&eol; else if (params.event_value === '1' && update.status === '0' && !jira.issue_key.startsWith(jira.project_key)) {&eol; var key = Jira.createIssue(params.alert_subject,&eol; (Object.keys(fields).length ? params.trigger_description : params.alert_message), fields);&eol;&eol;&eol; result.tags.__zbx_jira_issuekey = key;&eol; result.tags.__zbx_jira_issuelink = params.jira_url +&eol; (params.jira_url.endsWith('/') ? '' : '/') + 'browse/' + key;&eol; }&eol; // Update created issue for trigger-based event.&eol; else {&eol; if (!jira.issue_key.startsWith(jira.project_key)) {&eol; throw 'Incorrect Issue key given: ' + jira.issue_key;&eol; }&eol; Jira.updateIssue(params.alert_subject, fields,&eol; ((params.event_value === '0' && !Object.keys(fields).length)&eol; ? params.alert_message : update));&eol; }&eol;&eol; return JSON.stringify(result);&eol;}&eol;catch (error) {&eol; Zabbix.log(3, '[ Jira Webhook ] ERROR: ' + error);&eol; throw 'Sending failed: ' + error;&eol;}|30s |1 |1 |{EVENT.TAGS.__zbx_jira_issuelink} |Jira: {EVENT.TAGS.__zbx_jira_issuekey} | |
ROW |13 |4 |Jira with CustomFields | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |var Jira = {&eol; params: {},&eol;&eol; setParams: function (params) {&eol; if (typeof params !== 'object') {&eol; return;&eol; }&eol;&eol; Jira.params = params;&eol; if (typeof Jira.params.url === 'string') {&eol; if (!Jira.params.url.endsWith('/')) {&eol; Jira.params.url += '/';&eol; }&eol;&eol; Jira.params.url += 'rest/api/latest/';&eol; }&eol; },&eol;&eol; setProxy: function (HTTPProxy) {&eol; Jira.HTTPProxy = HTTPProxy;&eol; },&eol;&eol; setTags: function(event_tags_json) {&eol; if (typeof event_tags_json !== 'undefined' && event_tags_json !== ''&eol; && event_tags_json !== '{EVENT.TAGSJSON}') {&eol; try {&eol; var tags = JSON.parse(event_tags_json),&eol; label;&eol;&eol; Jira.labels = [];&eol;&eol; tags.forEach(function (tag) {&eol; if (typeof tag.tag !== 'undefined' && typeof tag.value !== 'undefined' ) {&eol; label = (tag.tag + (tag.value ? (':' + tag.value) : '')).replace(/\s/g, '_');&eol; if (label.length < 256) {&eol; Jira.labels.push(label);&eol; }&eol; }&eol; });&eol; }&eol; catch (error) {&eol; // Code is not missing here.&eol; }&eol; }&eol; },&eol;&eol; escapeMarkup: function (str) {&eol; var length = str.length,&eol; result = '',&eol; markup = ['{', '&pipe;', '}', '~', '_', '\\', '[', ']', '^', '<', '>', '?', '!', '#', '+', '*', '&'];&eol;&eol; for (var i = 0; i < length; i++) {&eol; var char = str[i];&eol;&eol; result += (markup.indexOf(char) !== -1) ? ('&#' + str[i].charCodeAt() + ';') : char;&eol; }&eol;&eol; return result;&eol; },&eol;&eol; addCustomFields: function (data, fields) {&eol; if (typeof fields === 'object' && Object.keys(fields).length) {&eol; var schema = Jira.getSchema(),&eol; path = ['projects', 0, 'issuetypes', 0, 'fields'],&eol; field;&eol;&eol; while ((field = path.shift()) !== undefined) {&eol; schema = schema[field];&eol; if (typeof schema === 'undefined') {&eol; schema = null;&eol; break;&eol; }&eol; }&eol;&eol; if (schema) {&eol; Object.keys(fields)&eol; .forEach(function(field) {&eol; data.fields[field] = fields[field];&eol;&eol; if (typeof schema[field] === 'object' && typeof schema[field].schema === 'object'&eol; && (schema[field].schema.type === 'number' &pipe;&pipe; schema[field].schema.type === 'datetime')) {&eol; switch (schema[field].schema.type) {&eol; case 'number':&eol; data.fields[field] = parseInt(fields[field]);&eol; break;&eol;&eol; case 'datetime':&eol; if (fields[field].match(/\d+[.-]\d+[.-]\d+T\d+:\d+:\d+/) !== null) {&eol; data.fields[field] = fields[field].replace(/\./g, '-');&eol; }&eol; else {&eol; delete data.fields[field];&eol; }&eol; break;&eol; }&eol; }&eol; });&eol; }&eol; else {&eol; Zabbix.log(4, '[ Jira Webhook ] Failed to retrieve field schema.');&eol; }&eol; }&eol;&eol; return data;&eol; },&eol;&eol; request: function (method, query, data) {&eol; ['url', 'user', 'password', 'project_key', 'issue_type'].forEach(function (field) {&eol; if (typeof Jira.params !== 'object' &pipe;&pipe; typeof Jira.params[field] === 'undefined'&eol; &pipe;&pipe; Jira.params[field] === '' ) {&eol; throw 'Required Jira param is not set: "' + field + '".';&eol; }&eol; });&eol;&eol; var response,&eol; url = Jira.params.url + query,&eol; request = new HttpRequest();&eol;&eol; request.addHeader('Content-Type: application/json');&eol; request.addHeader('Authorization: Basic ' + btoa(Jira.params.user + ':' + Jira.params.password));&eol;&eol; if (typeof Jira.HTTPProxy !== 'undefined' && Jira.HTTPProxy !== '') {&eol; request.setProxy(Jira.HTTPProxy);&eol; }&eol;&eol; if (typeof data !== 'undefined') {&eol; data = JSON.stringify(data);&eol; }&eol;&eol; Zabbix.log(4, '[ Jira Webhook ] Sending request: ' + url + ((typeof data === 'string') ? ('\n' + data) : ''));&eol;&eol; switch (method) {&eol; case 'get':&eol; response = request.get(url, data);&eol; break;&eol;&eol; case 'post':&eol; response = request.post(url, data);&eol; break;&eol;&eol; case 'put':&eol; response = request.put(url, data);&eol; break;&eol;&eol; default:&eol; throw 'Unsupported HTTP request method: ' + method;&eol; }&eol;&eol; Zabbix.log(4, '[ Jira Webhook ] Received response with status code ' + request.getStatus() + '\n' + response);&eol;&eol; if (response !== null) {&eol; try {&eol; response = JSON.parse(response);&eol; }&eol; catch (error) {&eol; Zabbix.log(4, '[ Jira Webhook ] Failed to parse response received from Jira');&eol; response = null;&eol; }&eol; }&eol;&eol; if (request.getStatus() < 200 &pipe;&pipe; request.getStatus() >= 300) {&eol; var message = 'Request failed with status code ' + request.getStatus();&eol;&eol; if (response !== null && typeof response.errors !== 'undefined'&eol; && Object.keys(response.errors).length > 0) {&eol; message += ': ' + JSON.stringify(response.errors);&eol; }&eol; else if (response !== null && typeof response.errorMessages !== 'undefined'&eol; && Object.keys(response.errorMessages).length > 0) {&eol; message += ': ' + JSON.stringify(response.errorMessages);&eol; }&eol;&eol; throw message + ' Check debug log for more information.';&eol; }&eol;&eol; return {&eol; status: request.getStatus(),&eol; response: response&eol; };&eol; },&eol;&eol; getSchema: function() {&eol; var result = Jira.request('get', 'issue/createmeta?expand=projects.issuetypes.fields&projectKeys=' +&eol; Jira.params.project_key + '&issuetypeNames=' + Jira.params.issue_type);&eol;&eol; return result.response;&eol; },&eol;&eol; createIssue: function(summary, description, fields) {&eol; var data = {&eol; fields: {&eol; project: {&eol; key: Jira.params.project_key&eol; },&eol; issuetype: {&eol; name: Jira.params.issue_type&eol; },&eol; summary: summary,&eol; description: description&eol; }&eol; };&eol;&eol; if (Jira.labels && Jira.labels.length > 0) {&eol; data.fields.labels = Jira.labels;&eol; }&eol; var result = Jira.request('post', 'issue', Jira.addCustomFields(data, fields));&eol;&eol; if (typeof result.response !== 'object' &pipe;&pipe; typeof result.response.key === 'undefined') {&eol; throw 'Cannot create Jira issue. Check debug log for more information.';&eol; }&eol;&eol; return result.response.key;&eol; },&eol;&eol; updateIssue: function(summary, fields, update) {&eol; var data = {fields: {}};&eol;&eol; if (summary) {&eol; data.fields.summary = summary;&eol; }&eol;&eol; Jira.request('put', 'issue/' + Jira.params.issue_key, Jira.addCustomFields(data, fields));&eol; Jira.commentIssue(update);&eol; },&eol;&eol; commentIssue: function(update) {&eol; var data = {};&eol;&eol; if (typeof update === 'string') {&eol; data.body = update;&eol; Jira.request('post', 'issue/' + Jira.params.issue_key + '/comment', data);&eol; }&eol; else if (update.status === '1') {&eol; data.body = update.user + ' ' + update.action + '.';&eol;&eol; if (update.message) {&eol; data.body += '\nMessage: {quote}' + Jira.escapeMarkup(update.message) + '{quote}';&eol; }&eol;&eol; Jira.request('post', 'issue/' + Jira.params.issue_key + '/comment', data);&eol; }&eol; }&eol;};&eol;&eol;try {&eol; var params = JSON.parse(value),&eol; fields = {},&eol; jira = {},&eol; update = {},&eol; result = {tags: {}},&eol; required_params = ['alert_subject', 'summary', 'event_recovery_value', 'event_source', 'event_value'];&eol;&eol; Object.keys(params)&eol; .forEach(function (key) {&eol; if (key.startsWith('jira_')) {&eol; jira[key.substring(5)] = params[key];&eol; }&eol; else if (key.startsWith('customfield_')) {&eol; fields[key] = params[key];&eol; }&eol; else if (key.startsWith('event_update_')) {&eol; update[key.substring(13)] = params[key];&eol; }&eol; else if (required_params.indexOf(key) !== -1 && params[key] === '') {&eol; throw 'Parameter "' + key + '" can\'t be empty.';&eol; }&eol; });&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: ' + params.event_source + '\nMust be 0-3.';&eol; }&eol;&eol; // Check {EVENT.VALUE} for trigger-based and internal events.&eol; if (params.event_value !== '0' && params.event_value !== '1'&eol; && (params.event_source === '0' &pipe;&pipe; params.event_source === '3')) {&eol; throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';&eol; }&eol;&eol; // Check {EVENT.UPDATE.STATUS} only for trigger-based events.&eol; if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {&eol; throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';&eol; }&eol;&eol; if (params.event_source !== '0' && params.event_recovery_value === '0') {&eol; throw 'Recovery operations are supported only for trigger-based actions.';&eol; }&eol;&eol; Jira.setParams(jira);&eol; Jira.setProxy(params.HTTPProxy);&eol; Jira.setTags(params.event_tags_json);&eol;&eol; // Create issue for non trigger-based events.&eol; if (params.event_source !== '0' && params.event_recovery_value !== '0') {&eol; Jira.createIssue(params.alert_subject, params.alert_message);&eol; }&eol; // Create issue for trigger-based events.&eol; else if (params.event_value === '1' && update.status === '0' && !jira.issue_key.startsWith(jira.project_key)) {&eol; var key = Jira.createIssue(params.alert_subject,&eol; (Object.keys(fields).length ? params.trigger_description : params.alert_message), fields);&eol;&eol;&eol; result.tags.__zbx_jira_issuekey = key;&eol; result.tags.__zbx_jira_issuelink = params.jira_url +&eol; (params.jira_url.endsWith('/') ? '' : '/') + 'browse/' + key;&eol; }&eol; // Update created issue for trigger-based event.&eol; else {&eol; if (!jira.issue_key.startsWith(jira.project_key)) {&eol; throw 'Incorrect Issue key given: ' + jira.issue_key;&eol; }&eol; Jira.updateIssue(params.alert_subject, fields,&eol; ((params.event_value === '0' && !Object.keys(fields).length)&eol; ? params.alert_message : update));&eol; }&eol;&eol; return JSON.stringify(result);&eol;}&eol;catch (error) {&eol; Zabbix.log(3, '[ Jira Webhook ] ERROR: ' + error);&eol; throw 'Sending failed: ' + error;&eol;}|30s |1 |1 |{EVENT.TAGS.__zbx_jira_issuelink} |Jira: {EVENT.TAGS.__zbx_jira_issuekey} | |
ROW |14 |4 |MS Teams | | | | | | | |0 |25 |0 |0 |0 |0 | |1 |3 |10s |1 |var SEVERITY_COLORS = [&eol; '#97AAB3', // Not classified.&eol; '#7499FF', // Information.&eol; '#FFC859', // Warning.&eol; '#FFA059', // Average.&eol; '#E97659', // High.&eol; '#E45959', // Disaster.&eol; '#009900', // Resolved.&eol; '#000000' // Default.&eol;];&eol;&eol;try {&eol; var params = JSON.parse(value);&eol;&eol; if (typeof params.teams_endpoint !== 'string' &pipe;&pipe; params.teams_endpoint.trim() === '') {&eol; throw 'Cannot get teams_endpoint';&eol; }&eol; else if (!params.teams_endpoint.startsWith('http')) {&eol; throw 'Invalid MS Teams webhook URL: ' + params.teams_endpoint;&eol; }&eol;&eol; params.zabbix_url = (params.zabbix_url.endsWith('/'))&eol; ? params.zabbix_url.slice(0, -1) : params.zabbix_url;&eol;&eol; if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {&eol; throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';&eol; }&eol;&eol; // Set "use_default_message" to true for non trigger-based events.&eol; if (params.event_source !== '0') {&eol; params.use_default_message = 'true';&eol; }&eol;&eol; // Check {EVENT.VALUE} for trigger-based and internal events.&eol; if (params.event_value !== '0' && params.event_value !== '1'&eol; && (params.event_source === '0' &pipe;&pipe; params.event_source === '3')) {&eol; throw 'Incorrect "event_value" parameter given: "' + params.event_value + '".\nMust be 0 or 1.';&eol; }&eol;&eol; // Check {EVENT.UPDATE.STATUS} only for trigger-based events.&eol; if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {&eol; throw 'Incorrect "event_update_status" parameter given: "' + params.event_update_status + '".\nMust be 0 or 1.';&eol; }&eol;&eol; if (params.event_value == 0) {&eol; params.event_nseverity = '6';&eol; }&eol;&eol; if (!SEVERITY_COLORS[params.event_nseverity]) {&eol; params.event_nseverity = '7';&eol; }&eol;&eol; var request = new HttpRequest(),&eol; facts = [],&eol; body = {&eol; themeColor: SEVERITY_COLORS[params.event_nseverity].replace('#', ''),&eol; summary: params.alert_subject,&eol; sections: [&eol; {&eol; markdown: 'false',&eol; activityTitle: params.alert_subject,&eol; activitySubtitle: 'On ' + params.host_name + ' [' + params.host_ip + ']',&eol; text: (params.use_default_message.toLowerCase() == 'true')&eol; ? params.alert_message&eol; : params.trigger_description&eol; }&eol; ],&eol; potentialAction: [&eol; {&eol; '@type': 'OpenUri',&eol; name: (params.event_source === '0')&eol; ? 'Event Info'&eol; : 'Zabbix Home',&eol; targets: [&eol; {&eol; os: 'default',&eol; uri: (params.event_source === '0')&eol; ? params.zabbix_url + '/tr_events.php?triggerid=' +&eol; params.trigger_id + '&eventid=' + params.event_id&eol; : params.zabbix_url&eol; }&eol; ]&eol; }&eol; ]&eol; };&eol;&eol; if (params.use_default_message.toLowerCase() !== 'true') {&eol; // Problem message.&eol; if (params.event_value === '1' && params.event_update_status === '0') {&eol; facts.push({&eol; name: 'Event time',&eol; value: params.event_time + ' ' + params.event_date&eol; });&eol; }&eol; // Update message.&eol; else if (params.event_update_status === '1') {&eol; body.sections[0].text = params.event_update_user + ' ' + params.event_update_action + '.';&eol;&eol; if (params.event_update_message) {&eol; body.sections[0].text += '<br>Message:<br>' + params.event_update_message;&eol; }&eol;&eol; facts.push({&eol; name: 'Event update time',&eol; value: params.event_update_time + ' ' + params.event_update_date&eol; });&eol; }&eol; // Resolved message.&eol; else {&eol; facts.push({&eol; name: 'Recovery time',&eol; value: params.event_recovery_time + ' ' + params.event_recovery_date&eol; });&eol; }&eol;&eol; if (params.event_severity && params.event_severity !== '{EVENT.SEVERITY}') {&eol; facts.push({&eol; name: 'Severity',&eol; value: params.event_severity&eol; });&eol; }&eol;&eol;&eol; if (params.event_opdata && params.event_opdata !== '{EVENT.OPDATA}') {&eol; facts.push({&eol; name: 'Operational data',&eol; value: params.event_opdata&eol; });&eol; }&eol;&eol; if (params.event_tags && params.event_tags !== '{EVENT.TAGS}') {&eol; facts.push({&eol; name: 'Event tags',&eol; value: params.event_tags&eol; });&eol; }&eol;&eol; Object.keys(params)&eol; .forEach(function (key) {&eol; if (key.startsWith('fact_') && params[key] !== '') {&eol; facts.push({&eol; name: key.substring(5),&eol; value: params[key]&eol; });&eol; }&eol; else if (key.startsWith('openUri_') && params[key] !== '' && !params[key].startsWith('{')) {&eol; body.potentialAction.push({&eol; '@type': 'OpenUri',&eol; name: key.substring(8),&eol; targets: [&eol; {&eol; os: 'default',&eol; uri: params[key]&eol; }&eol; ]&eol; });&eol; }&eol; });&eol; body.sections[0].facts = facts;&eol; }&eol;&eol; body.sections[0].text = body.sections[0].text.replace(/(?:\r\n&pipe;\r&pipe;\n)/g, '<br>');&eol;&eol; request.addHeader('Content-Type: application/json');&eol;&eol; if (typeof params.HTTPProxy === 'string' && params.HTTPProxy !== '') {&eol; request.setProxy(params.HTTPProxy);&eol; }&eol;&eol; Zabbix.log(4, '[ MS Teams Webhook ] JSON: ' + JSON.stringify(body));&eol;&eol; var response = request.post(params.teams_endpoint, JSON.stringify(body));&eol;&eol; Zabbix.log(4, '[ MS Teams Webhook ] Response: ' + response);&eol;&eol; if (response === '1') {&eol; return 'OK';&eol; }&eol; else {&eol; Zabbix.log(4, '[ MS Teams Webhook ] FAILED with response: ' + response);&eol; throw response;&eol; }&eol;}&eol;catch (error) {&eol; Zabbix.log(3, '[ MS Teams Webhook ] ERROR: ' + error);&eol; throw 'Sending failed: ' + error;&eol;}|30s |0 |0 | | | |
@@ -843,10 +843,10 @@ ROW |3 |9 |2 |
ROW |4 |7 |1 |
TABLE |scripts
-FIELDS|scriptid|name |command |host_access|usrgrpid|groupid|description|confirmation|type|execute_on|timeout|scope|port|authtype|username|password|publickey|privatekey|menu_path|
-ROW |1 |Ping |ping -c 3 {HOST.CONN}; case $? in [01]) true;; *) false;; esac|2 |NULL |NULL | | |0 |2 |30s |2 | |0 | | | | | |
-ROW |2 |Traceroute |/usr/bin/traceroute {HOST.CONN} |2 |NULL |NULL | | |0 |2 |30s |2 | |0 | | | | | |
-ROW |3 |Detect operating system|sudo /usr/bin/nmap -O {HOST.CONN} |2 |7 |NULL | | |0 |2 |30s |2 | |0 | | | | | |
+FIELDS|scriptid|name |command |host_access|usrgrpid|groupid|description|confirmation|type|execute_on|timeout|scope|port|authtype|username|password|publickey|privatekey|menu_path|url |new_window|
+ROW |1 |Ping |ping -c 3 {HOST.CONN}; case $? in [01]) true;; *) false;; esac|2 |NULL |NULL | | |0 |2 |30s |2 | |0 | | | | | | |1 |
+ROW |2 |Traceroute |/usr/bin/traceroute {HOST.CONN} |2 |NULL |NULL | | |0 |2 |30s |2 | |0 | | | | | | |1 |
+ROW |3 |Detect operating system|sudo /usr/bin/nmap -O {HOST.CONN} |2 |7 |NULL | | |0 |2 |30s |2 | |0 | | | | | | |1 |
TABLE |actions
FIELDS|actionid|name |eventsource|evaltype|status|esc_period|formula|pause_suppressed|notify_if_canceled|
diff --git a/create/src/schema.tmpl b/create/src/schema.tmpl
index ef044a12ae6..e8a442406d2 100644
--- a/create/src/schema.tmpl
+++ b/create/src/schema.tmpl
@@ -114,7 +114,7 @@ INDEX |1 |hostid
TABLE|group_discovery|groupid|ZBX_TEMPLATE
FIELD |groupid |t_id | |NOT NULL |0 |1|hstgrp
FIELD |parent_group_prototypeid|t_id | |NOT NULL |0 |2|group_prototype|group_prototypeid|RESTRICT
-FIELD |name |t_varchar(64) |'' |NOT NULL |ZBX_NODATA
+FIELD |name |t_varchar(255) |'' |NOT NULL |ZBX_NODATA
FIELD |lastcheck |t_integer |'0' |NOT NULL |ZBX_NODATA
FIELD |ts_delete |t_time |'0' |NOT NULL |ZBX_NODATA
@@ -373,6 +373,8 @@ FIELD |password |t_varchar(64) |'' |NOT NULL |0
FIELD |publickey |t_varchar(64) |'' |NOT NULL |0
FIELD |privatekey |t_varchar(64) |'' |NOT NULL |0
FIELD |menu_path |t_varchar(255) |'' |NOT NULL |0
+FIELD |url |t_varchar(2048)|'' |NOT NULL |0
+FIELD |new_window |t_integer |'1' |NOT NULL |0
INDEX |1 |usrgrpid
INDEX |2 |groupid
UNIQUE |3 |name
@@ -1974,4 +1976,4 @@ TABLE|dbversion|dbversionid|
FIELD |dbversionid |t_id | |NOT NULL |0
FIELD |mandatory |t_integer |'0' |NOT NULL |
FIELD |optional |t_integer |'0' |NOT NULL |
-ROW |1 |6030000 |6030000
+ROW |1 |6030004 |6030004