-
-
Save huasome/b9a254888cc1dea10021 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
# Based on a gist by benwtr (https://gist.github.com/benwtr/5691225) | |
# Works with Slack -> Hubot -> Icinga | |
#s | |
# Description: | |
# This script receives alerts in the format: | |
# /usr/bin/curl -X POST \ | |
# "${HUBOT_URL}/${SLACKCHANNEL}@conference.${TEAM}.xmpp.slack.com" \ | |
# -d "type=host" \ | |
# -d "notificationtype=${NOTIFICATIONTYPE}" \ | |
# -d "host=${HOSTDISPLAYNAME}" \ | |
# -d "state=${HOSTSTATE}" \ | |
# -d "output=${HOSTOUTPUT}" \ | |
# -d "timestamp=${DATETIME}" | |
# | |
# /usr/bin/curl -X POST \ | |
# "${HUBOT_URL}/${SLACKCHANNEL}@conference.${TEAM}.xmpp.slack.com" \ | |
# -d "type=service" \ | |
# -d "notificationtype=${NOTIFICATIONTYPE}" \ | |
# -d "host=${HOSTDISPLAYNAME}" \ | |
# -d "service=${SERVICEDISPLAYNAME}" \ | |
# -d "state=${SERVICESTATE}" \ | |
# -d "output=${SERVICEOUTPUT}" \ | |
# -d "timestamp=${DATETIME}" | |
# | |
# Configuration: | |
# HUBOT_ICINGA_URL: https://$ICINGA_HOST/cgi-bin/icinga2-classicui/cmd.cgi | |
# HOBOT_ICINGA_USER: icingaadmin | |
# HUBOT_ICINGA_PASS: $icingaadmin_password | |
# | |
# Commands: | |
# icinga ack <host>:<service> <message> | |
# acknowledge icinga alert (:service is optional) | |
# icinga mute <host>:<service> <minutes> | |
# delay the next notification for x minutes | |
# icinga down <host>:<service> <hours> | |
# schedule immediate downtime for host or service for x hours | |
# icinga recheck <host>:<service> | |
# force the immediate recheck of a host or a service | |
# @hubot icinga all_alerts_off | |
# useful in emergencies. disable all alerts (email, pager, slack) | |
# @hubot icinga all_alerts_on | |
# useful in emergencies. enable all alerts (email, pager, slack) | |
# | |
# Note that the :<service> portion of any commands that uses <host>:<service> | |
# syntax is optional. If you do not specify :<service>, the bot assumes you | |
# are applying the command to the host. The downtime command should apply | |
# the downtime to a host and all of its services. | |
moment = require 'moment' | |
icinga_user = process.env.HUBOT_ICINGA_USER | |
icinga_pass = process.env.HUBOT_ICINGA_PASS | |
icinga_url = process.env.HUBOT_ICINGA_URL | |
module.exports = (robot) -> | |
robot.router.post '/hubot/icinga/:room', (req, res) -> | |
room = req.params.room | |
host = req.body.host | |
output = req.body.output | |
state = req.body.state | |
timestamp = req.body.timestamp | |
notificationtype = req.body.notificationtype | |
switch state | |
when 'UP', 'OK' then emoji = ':white_check_mark:' | |
when 'DOWN', 'CRITICAL' then emoji = ':fire:' | |
when 'WARNING' then emoji = ':warning:' | |
when 'UNKNOWN' then emoji = ':confused:' | |
if req.body.type == 'host' | |
robot.messageRoom "#{room}", "[icinga #{emoji} #{timestamp}] #{notificationtype}: #{host} is #{state}: #{output}" | |
else | |
service = req.body.service | |
robot.messageRoom "#{room}", "[icinga #{emoji} #{timestamp}] #{notificationtype}: #{host}:#{service} is #{state}: #{output}" | |
res.writeHead 204, { 'Content-Length': 0 } | |
res.end() | |
robot.hear /icinga\s+ack\s+(\S+)\s*(.*)?/i, (msg) -> | |
[ host, service ] = msg.match[1].replace(/^http\:\/\//, '').split(':') | |
message = encodeURIComponent(msg.match[2] || ' ') | |
if service | |
data = "cmd_typ=34&cmd_mod=2&host=#{host}&service=#{service}&sticky_ack=on&send_notification=on&com_author=#{msg.envelope.user.name}&com_data=#{message}}" | |
else | |
data = "cmd_typ=33&cmd_mod=2&host=#{host}&sticky_ack=on&send_notification=on&com_author=#{msg.envelope.user.name}&com_data=#{message}" | |
icinga_post robot, msg, data | |
robot.hear /icinga\s+mute\s+(\S+)\s*(\d+)?/i, (msg) -> | |
[ host, service ] = msg.match[1].replace(/^http\:\/\//, '').split(':') | |
minutes = msg.match[2] || 30 | |
if service | |
data = "cmd_typ=9&cmd_mod=2&host=#{host}&service=#{service}¬_dly=#{minutes}" | |
else | |
data = "cmd_typ=10&cmd_mod=2&host=#{host}¬_dly=#{minutes}" | |
icinga_post robot, msg, data | |
robot.hear /icinga\s+down\s+(\S+)\s*(\d+)?\s*(.*)?/i, (msg) -> | |
[ host, service ] = msg.match[1].replace(/^http\:\/\//, '').split(':') | |
hours = msg.match[2] || 2 | |
message = encodeURIComponent(msg.match[3] || ' ') | |
start = encodeURIComponent(moment().format('MM-DD-YYYY hh:mm:ss')) | |
stop = encodeURIComponent(moment().add(hours, 'hours').format('MM-DD-YYYY hh:mm:ss')) | |
if service | |
data = "cmd_typ=56&cmd_mod=2&host=#{host}&service=#{service}&trigger=0&fixed=on&start_time=#{start}&end_time=#{stop}&com_data=#{message}" | |
else | |
data = "cmd_typ=86&cmd_mod=2&host=#{host}&trigger=0&fixed=on&start_time=#{start}&end_time=#{stop}&com_data=#{message}" | |
icinga_post robot, msg, data | |
robot.hear /icinga\s+recheck\s+(\S+)/i, (msg) -> | |
[ host, service ] = msg.match[1].replace(/^http\:\/\//, '').split(':') | |
start = encodeURIComponent(moment().format('MM-DD-YYYY hh:mm:ss')) | |
if service | |
data = "cmd_typ=7&cmd_mod=2&host=#{host}&service=#{service}&force_check=on&start_time=#{start}" | |
else | |
data = "cmd_typ=96&cmd_mod=2&host=#{host}&force_check=on&start_time=#{start}" | |
icinga_post robot, msg, data | |
robot.respond /icinga (all_alerts_off|stfu)/i, (msg) -> | |
data = "cmd_typ=11&cmd_mod=2" | |
icinga_post robot, msg, data | |
robot.respond /icinga all_alerts_on/i, (msg) -> | |
data = "cmd_typ=12&cmd_mod=2" | |
icinga_post robot, msg, data | |
icinga_post = (robot, msg, data) -> | |
robot.logger.debug "icinga_url = #{icinga_url}" | |
robot.logger.debug "data = #{data}" | |
auth = 'Basic ' + new Buffer(icinga_user + ':' + icinga_pass).toString('base64'); | |
options = | |
rejectUnauthorized: false | |
msg.http("#{icinga_url}", options) | |
.header('Authorization', auth) | |
.header('Accept', '*/*') | |
.header('User-Agent', "Hubot/#{@version}") | |
.post(data) (err, res, body) -> | |
if err | |
msg.send "[icinga :thumbsdown:]: #{err}" | |
robot.logger.debug "#{err}" | |
else | |
robot.logger.debug "result = #{res}" | |
robot.logger.debug "body = #{body}" | |
if res.statusCode is 200 and body.match(/Your command requests? (was|were) successfully submitted to Icinga for processing/) | |
msg.send "[icinga: :thumbsup:] Command successfully submitted." | |
else | |
msg.send "[icinga: :thumbsdown:] Command not understood." | |
robot.logger.debug "#{res}" | |
return |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment