New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

pagerduty-overlap-checker

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pagerduty-overlap-checker - npm Package Compare versions

Comparing version 1.1.1 to 1.2.0

lib/pagerduty-api.js

100

lib/notify.js
// Generated by CoffeeScript 1.10.0
var Slack, async, createPagerDutyIncident, createSlackMessage, debug, formatMessage, nconf, request, send;
var Slack, async, createPagerDutyIncident, createSlackMessage, debug, formatMessage, nconf, pdApi, request, send;

@@ -14,21 +14,55 @@ Slack = require('node-slackr');

pdApi = require('./pagerduty-api');
createPagerDutyIncident = function(options, message, cb) {
debug("Creating PD incident " + options.description);
if (!options.serviceKey) {
return cb(new Error("Missing PD service key"));
var incident, incidentOptions;
debug("Creating PD incident " + (JSON.stringify(message)) + " with options " + (JSON.stringify(options)));
if (!(options.pdToken && options.serviceId && options.from)) {
cb(new Error("Missing PAGERDUTY settings (you'll need PAGERDUTY_TOKEN, PAGERDUTY_SERVICE_ID and PAGERDUTY_ESCALATION_POLICY_ID)"));
}
if (!(message.userId || options.escalationPolicyId)) {
return cb(new Error("No userId or escalation policy specified"));
} else {
return request({
uri: 'https://events.pagerduty.com/generic/2010-04-15/create_event.json',
incident = {
type: "incident",
title: "On-call overlap found!",
service: {
id: options.serviceId,
type: "service_reference"
},
body: {
type: "incident_body",
details: message.messages.join('\n')
}
};
if (options.escalationPolicyId) {
incident.escalationPolicy = {
id: options.escalationPolicyId,
type: "escalation_policy_reference"
};
} else {
incident.assignments = [
{
assignee: {
id: message.userId,
type: "user_reference"
}
}
];
}
incidentOptions = {
method: "POST",
json: {
service_key: options.serviceKey,
event_type: "trigger",
description: "On-call overlap found!",
details: message
incident: incident
},
headers: {
From: options.from,
Authorization: 'Token token=' + options.pdToken
}
}, function(err, res, body) {
};
return pdApi.send('/incidents', incidentOptions, function(err, res, body) {
var ref;
if ((body != null ? (ref = body.errors) != null ? ref.length : void 0 : void 0) > 0) {
if (err == null) {
err = new Error("INCIDENT_CREATION_FAILED Cannot create event: " + (JSON.stringify(body.errors)));
err = new Error("INCIDENT_CREATION_FAILED Errors: " + (JSON.stringify(body.errors)));
}

@@ -78,3 +112,3 @@ }

message = messages[i];
outputMessage += message.user + ": " + message.schedules[0] + " and " + message.schedules[1] + " on " + (message.date.toLocaleString()) + "\n";
outputMessage += message.user + ": " + message.schedules[0] + " and " + message.schedules[1] + " on " + (message.date.toUTCString()) + "\n";
}

@@ -86,3 +120,3 @@ break;

message = messages[j];
outputMessage += "*" + message.user + ":* `" + message.schedules[0] + "` and `" + message.schedules[1] + "` on " + (message.date.toLocaleString()) + "\n";
outputMessage += "*" + message.user + ":* `" + message.schedules[0] + "` and `" + message.schedules[1] + "` on " + (message.date.toUTCString()) + "\n";
}

@@ -92,7 +126,16 @@ break;

outputMessage = messages.reduce(function(acc, curr) {
var name;
if (acc[name = curr.user] == null) {
acc[name] = [];
var base, base1, base2, name;
if (acc[name = curr.userId] == null) {
acc[name] = {};
}
acc[curr.user].push(curr.schedules[0] + " and " + curr.schedules[1] + " on " + (curr.date.toLocaleString()));
if ((base = acc[curr.userId]).userId == null) {
base.userId = curr.userId;
}
if ((base1 = acc[curr.userId]).user == null) {
base1.user = curr.user;
}
if ((base2 = acc[curr.userId]).messages == null) {
base2.messages = [];
}
acc[curr.userId].messages.push(curr.schedules[0] + " and " + curr.schedules[1] + " " + (curr.date.toUTCString()));
return acc;

@@ -125,11 +168,20 @@ }, {});

}, function(next) {
var pdOptions;
if (options['PAGERDUTY_TOKEN'] != null) {
var messagesByUser, pdOptions, ref;
if (!options['PAGERDUTY'] && !options['PAGERDUTY_TOKEN']) {
return debug('No PAGERDUTY options defined');
} else if ((options['PAGERDUTY']['PAGERDUTY_TOKEN'] || options['PAGERDUTY_TOKEN']) && options['PAGERDUTY']['PAGERDUTY_SERVICE_ID'] && options['PAGERDUTY']['PAGERDUTY_FROM']) {
debug('Found PD token - creating an incident');
pdOptions = {};
pdOptions.serviceKey = options['PAGERDUTY_TOKEN'];
pdOptions.description = message;
return createPagerDutyIncident(pdOptions, formatMessage(message, 'json'), next);
pdOptions.pdToken = options['PAGERDUTY']['PAGERDUTY_TOKEN'] || options['PAGERDUTY_TOKEN'];
pdOptions.serviceId = options['PAGERDUTY']['PAGERDUTY_SERVICE_ID'];
pdOptions.escalationPolicyId = options['PAGERDUTY']['PAGERDUTY_ESCALATION_POLICY_ID'];
pdOptions.from = (ref = options['PAGERDUTY']) != null ? ref['PAGERDUTY_FROM'] : void 0;
messagesByUser = formatMessage(message, 'json');
return async.each(messagesByUser, function(item, cb) {
return createPagerDutyIncident(pdOptions, item, cb);
}, function(err) {
return next(err);
});
} else {
debug('No PD token defined');
console.log("No PD options defined or defined incorrectly (" + (JSON.stringify(options['PAGERDUTY'])) + ")");
return next();

@@ -136,0 +188,0 @@ }

// Generated by CoffeeScript 1.10.0
var _, async, checkSchedulesIds, debug, getDayAbbrev, getSchedule, getSchedulesIds, getUserId, nconf, notify, overrideUser, pdGet, processSchedules, processSchedulesFromConfig, request, sendNotification,
var _, async, checkSchedulesIds, debug, getDayAbbrev, getSchedule, getSchedulesIds, nconf, notify, pdApi, processSchedules, processSchedulesFromConfig, sendNotification,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

@@ -7,4 +7,2 @@

request = require('request');
nconf = require('nconf');

@@ -18,21 +16,3 @@

pdGet = function(endpointPath, overrideOptions, cb) {
var sharedOptions;
debug("Calling " + endpointPath + " with options:", overrideOptions);
sharedOptions = {
uri: nconf.get('PAGERDUTY_API_URL') + endpointPath,
method: 'GET',
json: true,
headers: {
'Authorization': 'Token token=' + nconf.get('PAGERDUTY_READ_ONLY_TOKEN')
}
};
if (typeof overrideOptions === 'function') {
cb = overrideOptions;
overrideOptions = {};
}
_.extend(sharedOptions, overrideOptions);
debug('Calling request with: ', sharedOptions);
return request(sharedOptions, cb);
};
pdApi = require('./pagerduty-api');

@@ -46,3 +26,4 @@ getSchedule = function(id, cb) {

scheduleOpts = {
form: {
qs: {
'schedule_ids[]': id,
until: timeUntil.toISOString(),

@@ -52,3 +33,7 @@ since: timeNow.toISOString()

};
return pdGet("/schedules/" + id + "/entries", scheduleOpts, function(err, res, body) {
return pdApi.send("/oncalls", scheduleOpts, function(err, res, body) {
if (err) {
console.log("Request send error:", err);
return cb(err);
}
if (res.statusCode !== 200) {

@@ -59,3 +44,3 @@ return cb(new Error("Entries returned status code " + res.statusCode));

id: id,
entries: body.entries
entries: body.oncalls
});

@@ -70,9 +55,9 @@ });

debug("Getting schedules from PD");
return pdGet("/schedules", {}, function(err, res, body) {
return pdApi.send("/schedules", {}, function(err, res, body) {
var j, len, ref, schedule, schedulesIds;
debug('Returned status code:', res.statusCode);
if (err) {
console.log("Cannot get request:", err);
console.log("Request send error:", err);
return cb(err);
}
debug('Returned status code:', res.statusCode);
schedulesIds = [];

@@ -86,3 +71,3 @@ ref = body.schedules;

debug("Schedules Ids from PD: ", schedulesIds);
debug("Schedules Names from PD: ", debug(nconf.get("schedulesNames")));
debug("Schedules Names from PD: ", nconf.get("schedulesNames"));
return cb(null, schedulesIds);

@@ -100,4 +85,4 @@ });

}
debug("Schedules Ids from config: ", _.flatten(listIds));
configSchedulesIds = _.uniq(_.flatten(listIds));
debug("Schedules Ids from config: ", configSchedulesIds);
return getSchedulesIds(function(err, schedulesIds) {

@@ -172,16 +157,13 @@ if (err) {

schedule = allSchedules[j];
debug('schedule:', schedule);
debug('schedule:', JSON.stringify(schedule));
otherSchedules = _.without(allSchedules, schedule);
debug('otherSchedules:', otherSchedules);
debug('otherSchedules:', JSON.stringify(otherSchedules));
ref1 = schedule.entries;
for (k = 0, len1 = ref1.length; k < len1; k++) {
entry = ref1[k];
debug('checking entry: ', JSON.stringify(entry));
myStart = entry.start;
debug(myStart);
myEnd = entry.end;
debug(myEnd);
myUserId = entry.user.id;
debug(myUserId);
myUserName = entry.user.name;
debug(myUserName);
myUserName = entry.user.summary;
if (duplicities.myUserName == null) {

@@ -202,2 +184,3 @@ duplicities.myUserName = [];

user: myUserName,
userId: myUserId,
schedules: [scheduleId, crossScheduleId],

@@ -243,57 +226,2 @@ date: startDate

getUserId = function(email, cb) {
var userOptions;
userOptions = {
form: {
query: email
}
};
return pdGet("/users", userOptions, function(err, res, body) {
var userId;
if (res.statusCode !== 200) {
return cb(new Error("Entries returned status code " + res.statusCode));
}
userId = body.users[0].id;
return cb(err, userId);
});
};
overrideUser = function(userId, scheduleId, durationInMinutes, cb) {
var duration, endDate, sharedOptions, startDate;
if (durationInMinutes == null) {
durationInMinutes = 30;
}
if (userId && scheduleId) {
duration = durationInMinutes * 60 * 1000;
startDate = new Date();
endDate = new Date(startDate.getTime() + duration);
sharedOptions = {
uri: nconf.get('PAGERDUTY_API_URL') + ("/schedules/" + scheduleId + "/overrides"),
method: 'POST',
headers: {
'Authorization': 'Token token=' + nconf.get('PAGERDUTY_TOKEN')
},
form: {
override: {
"user_id": userId,
"start": startDate.toISOString(),
"end": endDate.toISOString()
}
}
};
debug('Calling request with: ', sharedOptions);
return request(sharedOptions, function(err, res, body) {
var reponseObject;
if (err) {
return cb(err);
}
if (res.statusCode !== 201) {
return cb(new Error("Entries returned status code " + res.statusCode));
}
reponseObject = JSON.parse(body);
return cb(err, reponseObject.override);
});
}
};
getDayAbbrev = function(utcDay) {

@@ -306,3 +234,2 @@ var days;

module.exports = {
pdGet: pdGet,
getSchedulesIds: getSchedulesIds,

@@ -312,5 +239,3 @@ checkSchedulesIds: checkSchedulesIds,

processSchedulesFromConfig: processSchedulesFromConfig,
sendNotification: sendNotification,
getUserId: getUserId,
overrideUser: overrideUser
sendNotification: sendNotification
};
{
"name": "pagerduty-overlap-checker",
"version": "1.1.1",
"version": "1.2.0",
"description": "PagerDuty Overlap Duties Checker",

@@ -5,0 +5,0 @@ "main": "lib/",

@@ -7,4 +7,4 @@ [![Build Status](https://travis-ci.org/apiaryio/pagerduty-overlap-checker.svg?branch=master)](https://travis-ci.org/apiaryio/pagerduty-overlap-checker)

- 4.3 (LTS)
- 5.x latest
- 5.x
- 6.x (LTS)

@@ -19,29 +19,41 @@ # Pager Duty Overrides Checker

- `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
- every `SCHEDULE` should have a `NOTIFICATIONS` section to create a PagerDuty incident or send a Slack message if overlap is found
- `SCHEDULE` can contain a `EXCLUSION_DAYS` key, which specifies days (3 letter abb.) in form of object with optional `start` and `end` time (`hh:mm` format **UTC TIMEZONE**).If `start` or `end` is omitted, whole day is considered excluded.
Example below represents current weekend on-call setup.
Currently, we only support Slack (`SLACK` with `SLACK_WEBHOOK_URL` and `CHANNEL`) or shorthanded `SLACK_WEBHOOK_URL` and PagerDuty (`PAGERDUTY_TOKEN`) notifications.
Currently, we support Slack (`SLACK` with `SLACK_WEBHOOK_URL` and `CHANNEL`) or shorthanded `SLACK_WEBHOOK_URL` and
PagerDuty (`PAGERDUTY` with `PAGERDUTY_TOKEN`, `PAGERDUTY_SERVICE_ID` and `PAGERDUTY_FROM`) notifications. The
`PAGERDUTY_TOKEN` has to have full access.
For PagerDuty, an incident can either be directly assigned to the user with overlaps (default) or set to an escalation
policy (if specified by `PAGERDUTY_ESCALATION_POLICY_ID` in config).
All PagerDuty integrations are using [PagerDuty API v2](https://v2.developer.pagerduty.com/v2/page/api-reference#!/API_Reference/get_api_reference).
When generating an API token, select the v2 option.
```json
{
"PAGERDUTY_API_URL": "https://acme.pagerduty.com/api/v1",
"PAGERDUTY_READ_ONLY_TOKEN": "33333333333333333333",
"WEEKS_TO_CHECK": 2,
"SCHEDULES": [{
"SCHEDULE": ["PWEVPB6", "PT57OLG"],
"NOTIFICATIONS": {
"SLACK": {
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111",
"CHANNEL": "#channel-name"
}
}
}, {
"SCHEDULE": ["PWEVPB6", "PT57OLA"],
"NOTIFICATIONS": {
"PAGERDUTY_TOKEN": "22222222222222222222",
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111",
},
"EXCLUSION_DAYS": {"Fri": {"start": "14:00", "end": "23:59"}, "Sat": {}, "Sun": {"start": "00:00", "end": "14:00"}}
}]
"PAGERDUTY_API_URL": "https://acme.pagerduty.com/api/v1",
"PAGERDUTY_READ_ONLY_TOKEN": "33333333333333333333",
"WEEKS_TO_CHECK": 2,
"SCHEDULES": [{
"SCHEDULE": ["PWEVPB6", "PT57OLG"],
"NOTIFICATIONS": {
"SLACK": {
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111",
"CHANNEL": "#channel-name"
}
}
}, {
"SCHEDULE": ["PWEVPB6", "PT57OLA"],
"NOTIFICATIONS": {
"PAGERDUTY": {
"PAGERDUTY_TOKEN": "22222222222222222222",
"PAGERDUTY_SERVICE_ID": "PFARE53",
"PAGERDUTY_FROM": "test@test.com"
},
"SLACK_WEBHOOK_URL": "http://acme.slack.com/11111"
},
"EXCLUSION_DAYS": {"Fri": {"start": "14:00", "end": "23:59"}, "Sat": {}, "Sun": {"start": "00:00", "end": "14:00"}}
}]
}

@@ -48,0 +60,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc