Skip to content

Commit

Permalink
fix: updated error handling; support for multiple SCHEDULE items
Browse files Browse the repository at this point in the history
  • Loading branch information
nadade committed Nov 25, 2016
1 parent 532a213 commit 398799b
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 53 deletions.
7 changes: 5 additions & 2 deletions README.md
Expand Up @@ -16,7 +16,7 @@
- `SCHEDULES` array can contain one or more `SCHEDULE` items to check
- every `SCHEDULE` should have a `NOTIFICATIONS` to create incident or send message if overlap is found

Currently, we only support Slack (`SLACK_WEBHOOK_URL`) and PagerDuty (`PAGERDUTY_TOKEN`) notifications.
Currently, we only support Slack (`SLACK` with `SLACK_WEBHOOK_URL` and `CHANNEL`) and PagerDuty (`PAGERDUTY_TOKEN`) notifications.

```json
{
Expand All @@ -26,7 +26,10 @@ Currently, we only support Slack (`SLACK_WEBHOOK_URL`) and PagerDuty (`PAGERDUTY
"SCHEDULES": [{
"SCHEDULE": ["PWEVPB6", "PT57OLG"],
"NOTIFICATIONS": {
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111"
"SLACK": {
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111",
"CHANNEL": "#channel-name"
}
}
}, {
"SCHEDULE": ["PWEVPB6", "PT57OLA"],
Expand Down
48 changes: 28 additions & 20 deletions bin/pdoverrides
Expand Up @@ -14,26 +14,34 @@ program
function runCheck(configFile) {
fsAccess(configFile, function (err) {
if (err) throw err;
config.setupConfig(configFile, function(err, res){
if (err) {
console.error(err);
process.exit(1);
}
var pd = require('../lib/pagerduty');
pd.checkSchedulesIds(function(error, res) {
if (!res) {
console.error("Check failed");
process.exit(1);
} else {
console.log("Config schedule IDs passed.")
pd.processSchedulesFromConfig(function(error, msg) {
console.log(msg);
process.exit(0);
});
}
});
});
});
config.setupConfig(configFile, function(err, res){
if (err) {
console.error(err);
process.exit(1);
}
var pd = require('../lib/pagerduty');
pd.checkSchedulesIds(function(error, res) {
if (error) {
console.error("Check failed with error:", error)
process.exit(1);
}
if (!res) {
console.error("Check failed - empty response");
process.exit(1);
} else {
console.log("Config schedule IDs passed.");
pd.processSchedulesFromConfig(function(error, msg) {
if (error) {
console.error("Error while processing schedules from config", error);
process.exit(1)
}
console.log(msg);
process.exit(0);
});
}
});
});
});
};

program
Expand Down
47 changes: 28 additions & 19 deletions src/notify.coffee
Expand Up @@ -23,7 +23,7 @@ createPagerDutyIncident = (options, message, cb) ->
, (err, res, body) ->
if body?.errors?.length > 0
err ?= new Error "INCIDENT_CREATION_FAILED Cannot create event: #{JSON.stringify body.errors}"
if res.statusCode isnt 200 and res.statusCode isnt 201
if res?.statusCode isnt 200 and res?.statusCode isnt 201
err ?= new Error "INCIDENT_CREATION_FAILED Creating incident failed with status #{res.statusCode}. Returned body: #{JSON.stringify body}"
if err
debug("INCIDENT_CREATION_FAILED: ", err)
Expand All @@ -34,7 +34,9 @@ createSlackMessage = (options, message, cb) ->
if options.webhookUrl
slack = new Slack(options.webhookUrl)
slack.notify message, (err, result) ->
if err then return cb err
if err
console.error("SLACK_SEND_MESSAGE_FAILED:", err)
return cb err
cb null, result
else
cb new Error "Missing Slack webhook URL."
Expand All @@ -51,28 +53,35 @@ formatMessage = (messages, option = 'plain') ->
send = (options, message, cb) ->
debug('send:', options, message)

async.series [
async.parallel [
(next) ->
if options['SLACK_WEBHOOK_URL']?
if options['SLACK']?
debug('Found Slack webhook, sending a notification')
slackMessage = {}
slackMessage.text = formatMessage(message)
slackMessage.channel = options['SLACK']['CHANNEL']
slackOptions = {}
slackOptions.webhookUrl = options['SLACK_WEBHOOK_URL']
createSlackMessage slackOptions, formatMessage(message), next
slackOptions.webhookUrl = options['SLACK']['SLACK_WEBHOOK_URL']
createSlackMessage slackOptions, slackMessage, next
else
debug('No Slack webhook defined')
next()
(next) ->
if options['PAGERDUTY_TOKEN']?
pdOptions = {}
pdOptions.serviceKey = options['PAGERDUTY_TOKEN']
pdOptions.description = message
pdOptions.details =
subject: "PagerDuty overlap incident"
createPagerDutyIncident pdOptions, formatMessage(message), next
else
next()
], (err, results) ->
if err then return cb err
output = results.filter (n) -> n isnt undefined
cb null, output
if options['PAGERDUTY_TOKEN']?
debug('Found PD token - creating an incident')
pdOptions = {}
pdOptions.serviceKey = options['PAGERDUTY_TOKEN']
pdOptions.description = message
pdOptions.details =
subject: "PagerDuty overlap incident"
createPagerDutyIncident pdOptions, formatMessage(message), next
else
debug('No PD token defined')
next()
], (err, results) ->
if err then return cb err
output = results.filter (n) -> n isnt undefined
cb null, output

module.exports = {
send
Expand Down
22 changes: 12 additions & 10 deletions src/pagerduty.coffee
Expand Up @@ -74,32 +74,34 @@ checkSchedulesIds = (cb) ->
else
cb null, false

processSchedulesFromConfig = (cb) ->
processSchedulesFromConfig = (done) ->
messages = []
configSchedules = nconf.get('SCHEDULES')
debug('configSchedules:', configSchedules.length)
processedConfig = null
end = configSchedules.length - 1
for index in [0..end]
processedConfig = configSchedules[index]
async.forEach configSchedules, (processedConfig, cb) ->
debug('Process schedule:', )
async.mapSeries configSchedules[index]['SCHEDULE'], (i, next) ->
async.mapSeries processedConfig['SCHEDULE'], (i, next) ->
getSchedule i, next
, (err, results) ->
if err then cb err
if results
processSchedules results, (err, message) ->
messages = messages.concat(message)
debug('processSchedules:', processedConfig)
if processedConfig['NOTIFICATIONS'] && message isnt "OK"
debug('Sending notifications.')
sendNotification processedConfig['NOTIFICATIONS'], message
cb null, message
sendNotification processedConfig['NOTIFICATIONS'], message, cb
else
cb new Error "No schedule to process."
, (err) ->
if err then done err
done null, messages

sendNotification = (options, message) ->
sendNotification = (options, message, cb) ->
debug("NOTIFICATIONS:", message)
debug("NOTIFICATIONS-OPTIONS:", options)
notify.send options, message, (err) ->
if err then console.error "Notification failed.", err
cb err

processSchedules = (allSchedules, cb) ->
schedulesMap = {}
Expand Down
5 changes: 4 additions & 1 deletion test/fixtures/config.json
Expand Up @@ -5,7 +5,10 @@
"SCHEDULES": [{
"SCHEDULE": ["PWEVPB6", "PT57OLG"],
"NOTIFICATIONS": {
"SLACK_WEBHOOK_URL": "https://incomingUrl/",
"SLACK": {
"SLACK_WEBHOOK_URL": "https://incomingUrl/",
"CHANNEL": "#channel-name"
},
"PAGERDUTY_TOKEN" : "111111111111"
}
}]
Expand Down
4 changes: 3 additions & 1 deletion test/notify-test.coffee
Expand Up @@ -8,6 +8,8 @@ notify = require '../src/notify'

configPath = __dirname + '/fixtures/config.json'

nock.disableNetConnect();

# https://github.com/chenka/node-slackr/blob/master/test/index.coffee
describe 'Test send message using notify.send for both', ->

Expand All @@ -17,7 +19,7 @@ describe 'Test send message using notify.send for both', ->

expectBody =
text:"Message"
channel:"#general"
channel:"#channel-name"

config.setupConfig configPath, (err) ->
if err then return done err
Expand Down
17 changes: 17 additions & 0 deletions test/pagerduty-test.coffee
Expand Up @@ -9,6 +9,8 @@ pd = require '../src/pagerduty'
configPath = __dirname + '/fixtures/config.json'
configWrongPath = __dirname + '/fixtures/config-wrong.json'

nock.disableNetConnect();

describe 'Get schedules Ids', ->
schedules = null

Expand Down Expand Up @@ -81,6 +83,21 @@ describe 'Compare schedules', ->
.get('/schedules/PT57OLG/entries')
.replyWithFile(200, __dirname + '/fixtures/entries.json')

expectedBody = {
service_key:"111111111111",
event_type:"trigger",
description:[
"Overlapping duty found for user Gregory\nfrom 2012-08-19T00:00:00-04:00 to 2012-08-19T12:00:00-04:00 on schedule ID PWEVPB6!",
"Overlapping duty found for user Halie\nfrom 2012-08-19T12:00:00-04:00 to 2012-08-20T00:00:00-04:00 on schedule ID PWEVPB6!",
"Overlapping duty found for user Gregory\nfrom 2012-08-19T00:00:00-04:00 to 2012-08-19T12:00:00-04:00 on schedule ID PT57OLG!",
"Overlapping duty found for user Halie\nfrom 2012-08-19T12:00:00-04:00 to 2012-08-20T00:00:00-04:00 on schedule ID PT57OLG!"
],
details:{subject:"PagerDuty overlap incident"}
}
nock('https://events.pagerduty.com/generic/2010-04-15/')
.post('/create_event.json', expectedBody)
.reply(200, 'ok')

nock('https://incomingUrl/').post("/").reply(200, 'ok')

pd.checkSchedulesIds (err, res) ->
Expand Down

0 comments on commit 398799b

Please sign in to comment.