@pagerduty/backstage-plugin-backend 0.6.1 → 0.7.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +157 -26
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/migrations/20240509_init.js +50 -0
- package/package.json +16 -13
package/dist/index.cjs.js
CHANGED
|
@@ -9,12 +9,13 @@ var fetch$1 = require('node-fetch');
|
|
|
9
9
|
var backstagePluginCommon = require('@pagerduty/backstage-plugin-common');
|
|
10
10
|
var luxon = require('luxon');
|
|
11
11
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
12
|
+
var uuid = require('uuid');
|
|
12
13
|
|
|
13
|
-
function
|
|
14
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
14
15
|
|
|
15
|
-
var express__default = /*#__PURE__*/
|
|
16
|
-
var Router__default = /*#__PURE__*/
|
|
17
|
-
var fetch__default = /*#__PURE__*/
|
|
16
|
+
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
17
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
18
|
+
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch$1);
|
|
18
19
|
|
|
19
20
|
let authPersistence;
|
|
20
21
|
async function getAuthToken() {
|
|
@@ -123,7 +124,7 @@ async function getEscalationPolicies(offset, limit) {
|
|
|
123
124
|
};
|
|
124
125
|
const baseUrl = `${apiBaseUrl}/escalation_policies`;
|
|
125
126
|
try {
|
|
126
|
-
response = await fetch__default
|
|
127
|
+
response = await fetch__default.default(`${baseUrl}?${params}`, options);
|
|
127
128
|
} catch (error) {
|
|
128
129
|
throw new Error(`Failed to retrieve escalation policies: ${error}`);
|
|
129
130
|
}
|
|
@@ -175,7 +176,7 @@ async function getOncallUsers(escalationPolicy) {
|
|
|
175
176
|
};
|
|
176
177
|
const baseUrl = `${apiBaseUrl}/oncalls`;
|
|
177
178
|
try {
|
|
178
|
-
response = await fetch__default
|
|
179
|
+
response = await fetch__default.default(`${baseUrl}?${params}`, options);
|
|
179
180
|
} catch (error) {
|
|
180
181
|
throw new Error(`Failed to retrieve oncalls: ${error}`);
|
|
181
182
|
}
|
|
@@ -216,6 +217,51 @@ async function getOncallUsers(escalationPolicy) {
|
|
|
216
217
|
throw new backstagePluginCommon.HttpError(`Failed to parse oncall information: ${error}`, 500);
|
|
217
218
|
}
|
|
218
219
|
}
|
|
220
|
+
async function getAllServices() {
|
|
221
|
+
let response;
|
|
222
|
+
const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
223
|
+
const options = {
|
|
224
|
+
method: "GET",
|
|
225
|
+
headers: {
|
|
226
|
+
Authorization: await getAuthToken(),
|
|
227
|
+
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
228
|
+
"Content-Type": "application/json"
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const baseUrl = `${apiBaseUrl}/services`;
|
|
232
|
+
let allServices = [];
|
|
233
|
+
let moreResults = true;
|
|
234
|
+
let offset = 0;
|
|
235
|
+
const limit = 50;
|
|
236
|
+
while (moreResults) {
|
|
237
|
+
try {
|
|
238
|
+
response = await fetch__default.default(`${baseUrl}?${params}&offset=${offset}&limit=${limit}`, options);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
throw new Error(`Failed to retrieve services: ${error}`);
|
|
241
|
+
}
|
|
242
|
+
switch (response.status) {
|
|
243
|
+
case 400:
|
|
244
|
+
throw new backstagePluginCommon.HttpError("Failed to get services. Caller provided invalid arguments.", 400);
|
|
245
|
+
case 401:
|
|
246
|
+
throw new backstagePluginCommon.HttpError("Failed to get services. Caller did not supply credentials or did not provide the correct credentials.", 401);
|
|
247
|
+
case 403:
|
|
248
|
+
throw new backstagePluginCommon.HttpError("Failed to get services. Caller is not authorized to view the requested resource.", 403);
|
|
249
|
+
}
|
|
250
|
+
let result;
|
|
251
|
+
try {
|
|
252
|
+
result = await response.json();
|
|
253
|
+
allServices = allServices.concat(result.services);
|
|
254
|
+
if (result.more) {
|
|
255
|
+
offset += limit;
|
|
256
|
+
} else {
|
|
257
|
+
moreResults = false;
|
|
258
|
+
}
|
|
259
|
+
} catch (error) {
|
|
260
|
+
throw new backstagePluginCommon.HttpError(`Failed to parse service information: ${error}`, 500);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return allServices;
|
|
264
|
+
}
|
|
219
265
|
async function getServiceById(serviceId) {
|
|
220
266
|
let response;
|
|
221
267
|
const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
@@ -229,7 +275,7 @@ async function getServiceById(serviceId) {
|
|
|
229
275
|
};
|
|
230
276
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
231
277
|
try {
|
|
232
|
-
response = await fetch__default
|
|
278
|
+
response = await fetch__default.default(`${baseUrl}/${serviceId}?${params}`, options);
|
|
233
279
|
} catch (error) {
|
|
234
280
|
throw new Error(`Failed to retrieve service: ${error}`);
|
|
235
281
|
}
|
|
@@ -264,7 +310,7 @@ async function getServiceByIntegrationKey(integrationKey) {
|
|
|
264
310
|
};
|
|
265
311
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
266
312
|
try {
|
|
267
|
-
response = await fetch__default
|
|
313
|
+
response = await fetch__default.default(`${baseUrl}?${params}`, options);
|
|
268
314
|
} catch (error) {
|
|
269
315
|
throw new Error(`Failed to retrieve service: ${error}`);
|
|
270
316
|
}
|
|
@@ -302,7 +348,7 @@ async function getChangeEvents(serviceId) {
|
|
|
302
348
|
};
|
|
303
349
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
304
350
|
try {
|
|
305
|
-
response = await fetch__default
|
|
351
|
+
response = await fetch__default.default(`${baseUrl}/${serviceId}/change_events?${params}`, options);
|
|
306
352
|
} catch (error) {
|
|
307
353
|
throw new Error(`Failed to retrieve change events for service: ${error}`);
|
|
308
354
|
}
|
|
@@ -337,7 +383,7 @@ async function getIncidents(serviceId) {
|
|
|
337
383
|
};
|
|
338
384
|
const baseUrl = `${apiBaseUrl}/incidents`;
|
|
339
385
|
try {
|
|
340
|
-
response = await fetch__default
|
|
386
|
+
response = await fetch__default.default(`${baseUrl}?${params}`, options);
|
|
341
387
|
} catch (error) {
|
|
342
388
|
throw new Error(`Failed to retrieve incidents for service: ${error}`);
|
|
343
389
|
}
|
|
@@ -373,7 +419,7 @@ async function getServiceStandards(serviceId) {
|
|
|
373
419
|
};
|
|
374
420
|
const baseUrl = `${apiBaseUrl}/standards/scores/technical_services/${serviceId}`;
|
|
375
421
|
try {
|
|
376
|
-
response = await fetch__default
|
|
422
|
+
response = await fetch__default.default(baseUrl, options);
|
|
377
423
|
} catch (error) {
|
|
378
424
|
throw new Error(`Failed to retrieve service standards for service: ${error}`);
|
|
379
425
|
}
|
|
@@ -416,7 +462,7 @@ async function getServiceMetrics(serviceId) {
|
|
|
416
462
|
};
|
|
417
463
|
const baseUrl = `${apiBaseUrl}/analytics/metrics/incidents/services`;
|
|
418
464
|
try {
|
|
419
|
-
response = await fetch__default
|
|
465
|
+
response = await fetch__default.default(baseUrl, options);
|
|
420
466
|
} catch (error) {
|
|
421
467
|
throw new Error(`Failed to retrieve service metrics for service: ${error}`);
|
|
422
468
|
}
|
|
@@ -434,13 +480,91 @@ async function getServiceMetrics(serviceId) {
|
|
|
434
480
|
}
|
|
435
481
|
}
|
|
436
482
|
|
|
483
|
+
var __defProp = Object.defineProperty;
|
|
484
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
485
|
+
var __publicField = (obj, key, value) => {
|
|
486
|
+
__defNormalProp(obj, key + "" , value);
|
|
487
|
+
return value;
|
|
488
|
+
};
|
|
489
|
+
const migrationsDir = backendPluginApi.resolvePackagePath(
|
|
490
|
+
"@pagerduty/backstage-plugin-backend",
|
|
491
|
+
"migrations"
|
|
492
|
+
);
|
|
493
|
+
class PagerDutyBackendDatabase {
|
|
494
|
+
constructor(options) {
|
|
495
|
+
__publicField(this, "database");
|
|
496
|
+
this.database = options.database;
|
|
497
|
+
}
|
|
498
|
+
static async create(options) {
|
|
499
|
+
const { database } = options;
|
|
500
|
+
await database.migrate.latest({
|
|
501
|
+
directory: migrationsDir
|
|
502
|
+
});
|
|
503
|
+
return new PagerDutyBackendDatabase(options);
|
|
504
|
+
}
|
|
505
|
+
async getAllEntityMappings() {
|
|
506
|
+
const results = await this.database("pagerduty_entity_mapping").select();
|
|
507
|
+
return results;
|
|
508
|
+
}
|
|
509
|
+
async insertEntityMapping(entity) {
|
|
510
|
+
const mappingId = uuid.v4();
|
|
511
|
+
const [result] = await this.database(
|
|
512
|
+
"pagerduty_entity_mapping"
|
|
513
|
+
).insert({
|
|
514
|
+
id: mappingId,
|
|
515
|
+
service_id: entity.serviceId,
|
|
516
|
+
entity_ref: entity.entityRef,
|
|
517
|
+
sync_status: "InSync",
|
|
518
|
+
last_synced_at: Date.now()
|
|
519
|
+
}).onConflict("entityRef").merge(["service_id", "sync_status", "last_synced_at"]).returning("id");
|
|
520
|
+
return result.id;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
437
524
|
async function createRouter(options) {
|
|
438
|
-
const { logger, config } = options;
|
|
525
|
+
const { logger, config, database } = options;
|
|
439
526
|
await loadAuthConfig(config, logger);
|
|
440
527
|
const baseUrl = config.getOptionalString("pagerDuty.apiBaseUrl") !== void 0 ? config.getString("pagerDuty.apiBaseUrl") : "https://api.pagerduty.com";
|
|
441
528
|
setAPIBaseUrl(baseUrl);
|
|
442
|
-
const
|
|
443
|
-
|
|
529
|
+
const pagerDutyEntityStore = await PagerDutyBackendDatabase.create({
|
|
530
|
+
database: await database.getClient()
|
|
531
|
+
});
|
|
532
|
+
const router = Router__default.default();
|
|
533
|
+
router.use(express__default.default.json());
|
|
534
|
+
router.post("/mapping/entity", async (request, response) => {
|
|
535
|
+
try {
|
|
536
|
+
const entity = request.body;
|
|
537
|
+
if (!entity.entity_ref) {
|
|
538
|
+
response.status(400).json("Bad Request: 'entity_ref' is required");
|
|
539
|
+
}
|
|
540
|
+
const entityMappingId = pagerDutyEntityStore.insertEntityMapping(entity);
|
|
541
|
+
response.json({
|
|
542
|
+
id: entityMappingId
|
|
543
|
+
});
|
|
544
|
+
} catch (error) {
|
|
545
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
546
|
+
response.status(error.status).json({
|
|
547
|
+
errors: [
|
|
548
|
+
`${error.message}`
|
|
549
|
+
]
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
router.get("/mapping", async (_, response) => {
|
|
555
|
+
try {
|
|
556
|
+
const entityMappings = await pagerDutyEntityStore.getAllEntityMappings();
|
|
557
|
+
response.json(entityMappings);
|
|
558
|
+
} catch (error) {
|
|
559
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
560
|
+
response.status(error.status).json({
|
|
561
|
+
errors: [
|
|
562
|
+
`${error.message}`
|
|
563
|
+
]
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
});
|
|
444
568
|
router.get("/escalation_policies", async (_, response) => {
|
|
445
569
|
try {
|
|
446
570
|
const escalationPolicyList = await getAllEscalationPolicies();
|
|
@@ -506,14 +630,19 @@ async function createRouter(options) {
|
|
|
506
630
|
router.get("/services", async (request, response) => {
|
|
507
631
|
try {
|
|
508
632
|
const integrationKey = request.query.integration_key || "";
|
|
509
|
-
if (integrationKey
|
|
510
|
-
|
|
633
|
+
if (integrationKey !== "") {
|
|
634
|
+
const service = await getServiceByIntegrationKey(integrationKey);
|
|
635
|
+
const serviceResponse = {
|
|
636
|
+
service
|
|
637
|
+
};
|
|
638
|
+
response.json(serviceResponse);
|
|
639
|
+
} else {
|
|
640
|
+
const allServices = await getAllServices();
|
|
641
|
+
const allServicesResponse = {
|
|
642
|
+
services: allServices
|
|
643
|
+
};
|
|
644
|
+
response.json(allServicesResponse);
|
|
511
645
|
}
|
|
512
|
-
const service = await getServiceByIntegrationKey(integrationKey);
|
|
513
|
-
const serviceResponse = {
|
|
514
|
-
service
|
|
515
|
-
};
|
|
516
|
-
response.json(serviceResponse);
|
|
517
646
|
} catch (error) {
|
|
518
647
|
if (error instanceof backstagePluginCommon.HttpError) {
|
|
519
648
|
response.status(error.status).json({
|
|
@@ -610,13 +739,15 @@ const pagerDutyPlugin = backendPluginApi.createBackendPlugin({
|
|
|
610
739
|
deps: {
|
|
611
740
|
logger: backendPluginApi.coreServices.logger,
|
|
612
741
|
config: backendPluginApi.coreServices.rootConfig,
|
|
613
|
-
httpRouter: backendPluginApi.coreServices.httpRouter
|
|
742
|
+
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
743
|
+
database: backendPluginApi.coreServices.database
|
|
614
744
|
},
|
|
615
|
-
async init({ config, logger, httpRouter }) {
|
|
745
|
+
async init({ config, logger, httpRouter, database }) {
|
|
616
746
|
httpRouter.use(
|
|
617
747
|
await createRouter({
|
|
618
748
|
config,
|
|
619
|
-
logger
|
|
749
|
+
logger,
|
|
750
|
+
database
|
|
620
751
|
})
|
|
621
752
|
);
|
|
622
753
|
httpRouter.addAuthPolicy({
|
|
@@ -629,5 +760,5 @@ const pagerDutyPlugin = backendPluginApi.createBackendPlugin({
|
|
|
629
760
|
});
|
|
630
761
|
|
|
631
762
|
exports.createRouter = createRouter;
|
|
632
|
-
exports
|
|
763
|
+
exports.default = pagerDutyPlugin;
|
|
633
764
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/auth/auth.ts","../src/apis/pagerduty.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import { LoggerService, RootConfigService } from \"@backstage/backend-plugin-api\";\nimport { HttpError } from \"@pagerduty/backstage-plugin-common\";\n\ntype Auth = {\n config: RootConfigService;\n logger: LoggerService;\n authToken: string;\n authTokenExpiryDate: number;\n}\n\nlet authPersistence: Auth;\n\nexport async function getAuthToken(): Promise<string> {\n // check if token already exists and is valid\n if (\n (authPersistence.authToken !== '' &&\n authPersistence.authToken.includes('Bearer') &&\n authPersistence.authTokenExpiryDate > Date.now()) // case where OAuth token is still valid\n ||\n (authPersistence.authToken !== '' &&\n authPersistence.authToken.includes('Token'))) { // case where API token is used\n return authPersistence.authToken;\n }\n\n await loadAuthConfig(authPersistence.config, authPersistence.logger);\n return authPersistence.authToken;\n}\n\nexport async function loadAuthConfig(config : RootConfigService, logger: LoggerService) {\n try {\n\n // initiliaze the authPersistence in-memory object\n authPersistence = {\n config,\n logger,\n authToken: '',\n authTokenExpiryDate: Date.now()\n };\n\n if (!config.getOptionalString('pagerDuty.apiToken')) {\n logger.warn('No PagerDuty API token found in config file. Trying OAuth token instead...');\n\n if (!config.getOptional('pagerDuty.oauth')) {\n \n logger.error('No PagerDuty OAuth configuration found in config file.');\n\n } else if (!config.getOptionalString('pagerDuty.oauth.clientId') || !config.getOptionalString('pagerDuty.oauth.clientSecret') || !config.getOptionalString('pagerDuty.oauth.subDomain')) {\n \n logger.error(\"Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.\");\n\n } else {\n\n authPersistence.authToken = await getOAuthToken(\n config.getString('pagerDuty.oauth.clientId'),\n config.getString('pagerDuty.oauth.clientSecret'),\n config.getString('pagerDuty.oauth.subDomain'),\n config.getOptionalString('pagerDuty.oauth.region') ?? 'us');\n\n logger.info('PagerDuty OAuth configuration loaded successfully.');\n }\n } else {\n authPersistence.authToken = `Token token=${config.getString('pagerDuty.apiToken')}`;\n\n logger.info('PagerDuty API token loaded successfully.');\n }\n }\n catch (error) {\n logger.error(`Unable to retrieve valid PagerDuty AUTH configuration from config file: ${error}`);\n }\n}\n\nasync function getOAuthToken(clientId: string, clientSecret: string, subDomain: string, region: string): Promise<string> {\n // check if required parameters are provided\n if (!clientId || !clientSecret || !subDomain) {\n throw new Error('Missing required PagerDuty OAuth parameters.');\n }\n\n // define the scopes required for the OAuth token\n const scopes = `\n abilities.read \n analytics.read\n change_events.read \n escalation_policies.read \n incidents.read \n oncalls.read \n schedules.read \n services.read \n services.write \n standards.read\n teams.read \n users.read \n vendors.read\n `;\n\n // encode the parameters for the request\n const urlencoded = new URLSearchParams();\n urlencoded.append(\"grant_type\", \"client_credentials\");\n urlencoded.append(\"client_id\", clientId);\n urlencoded.append(\"client_secret\", clientSecret);\n urlencoded.append(\"scope\", `as_account-${region}.${subDomain} ${scopes}`);\n\n let response: Response;\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: urlencoded,\n };\n const baseUrl = 'https://identity.pagerduty.com/oauth/token';\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve oauth token: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to retrieve valid token. Bad Request - Invalid arguments provided.\", 400);\n case 401:\n throw new HttpError(\"Failed to retrieve valid token. Forbidden - Invalid credentials provided.\", 401);\n default: // 200\n break;\n }\n\n const authResponse = await response.json();\n authPersistence.authTokenExpiryDate = Date.now() + (authResponse.expires_in * 1000);\n return `Bearer ${authResponse.access_token}`;\n}","import fetch from 'node-fetch';\nimport type { RequestInit, Response } from 'node-fetch';\n\nimport { getAuthToken } from '../auth/auth';\n\nimport {\n PagerDutyServiceResponse,\n PagerDutyServicesResponse,\n PagerDutyEscalationPolicy,\n PagerDutyEscalationPoliciesResponse,\n PagerDutyAbilitiesResponse,\n PagerDutyOnCallsResponse,\n PagerDutyUser,\n PagerDutyService,\n PagerDutyChangeEventsResponse,\n PagerDutyChangeEvent,\n PagerDutyIncident,\n PagerDutyIncidentsResponse,\n PagerDutyServiceStandards,\n PagerDutyServiceMetrics,\n HttpError\n} from '@pagerduty/backstage-plugin-common';\n\nimport { DateTime } from 'luxon';\n\nlet apiBaseUrl = 'https://api.pagerduty.com';\nexport function setAPIBaseUrl(url: string): void {\n apiBaseUrl = url;\n}\n\n// Supporting router\n\nasync function getEscalationPolicies(offset: number, limit: number): Promise<[Boolean, PagerDutyEscalationPolicy[]]> {\n let response: Response;\n const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/escalation_policies`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve escalation policies: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to list escalation policies. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to list escalation policies. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to list escalation policies. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to list escalation policies. Rate limit exceeded.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyEscalationPoliciesResponse;\n try {\n result = await response.json() as PagerDutyEscalationPoliciesResponse;\n\n return [result.more ?? false, result.escalation_policies];\n\n } catch (error) {\n throw new HttpError(`Failed to parse escalation policy information: ${error}`, 500);\n }\n}\n\nexport async function getAllEscalationPolicies(offset: number = 0): Promise<PagerDutyEscalationPolicy[]> {\n const limit = 50;\n\n try {\n const res = await getEscalationPolicies(offset, limit);\n const results = res[1];\n\n // if more results exist\n if (res[0]) {\n return results.concat((await getAllEscalationPolicies(offset + limit)));\n }\n\n return results;\n } catch (error) {\n if (error instanceof HttpError) {\n throw error;\n }\n else {\n throw new HttpError(`${error}`, 500);\n }\n }\n}\n\nexport async function isEventNoiseReductionEnabled(): Promise<boolean> {\n let response: Response;\n const baseUrl = 'https://api.pagerduty.com';\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n\n try {\n response = await fetch(`${baseUrl}/abilities`, options);\n } catch (error) {\n throw new Error(`Failed to read abilities: ${error}`);\n }\n\n switch (response.status) {\n case 401:\n throw new Error(`Failed to read abilities. Caller did not supply credentials or did not provide the correct credentials.`);\n case 403:\n throw new Error(`Failed to read abilities. Caller is not authorized to view the requested resource.`);\n case 429:\n throw new Error(`Failed to read abilities. Rate limit exceeded.`);\n default: // 200\n break;\n }\n\n let result: PagerDutyAbilitiesResponse;\n try {\n result = await response.json() as PagerDutyAbilitiesResponse;\n\n if (result.abilities.includes('preview_intelligent_alert_grouping')\n && result.abilities.includes('time_based_alert_grouping')) {\n return true;\n }\n\n return false;\n\n } catch (error) {\n throw new Error(`Failed to parse abilities information: ${error}`);\n }\n}\n\nexport async function getOncallUsers(escalationPolicy: string): Promise<PagerDutyUser[]> {\n let response: Response;\n const params = `time_zone=UTC&include[]=users&escalation_policy_ids[]=${escalationPolicy}`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/oncalls`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve oncalls: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to list oncalls. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to list oncalls. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to list oncalls. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to list oncalls. Rate limit exceeded.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyOnCallsResponse;\n let usersItem: PagerDutyUser[];\n try {\n result = await response.json() as PagerDutyOnCallsResponse;\n\n if (result.oncalls.length !== 0) {\n const oncallsSorted = [...result.oncalls].sort((a, b) => {\n return a.escalation_level - b.escalation_level;\n });\n\n const oncallsFiltered = oncallsSorted.filter((oncall) => {\n return oncall.escalation_level === oncallsSorted[0].escalation_level;\n });\n\n usersItem = [...oncallsFiltered]\n .sort((a, b) => a.user.name > b.user.name ? 1 : -1)\n .map((oncall) => oncall.user);\n\n\n // remove duplicates from usersItem\n const uniqueUsers = new Map();\n usersItem.forEach((user) => {\n uniqueUsers.set(user.id, user);\n });\n\n usersItem.length = 0;\n uniqueUsers.forEach((user) => {\n usersItem.push(user);\n });\n\n return usersItem;\n }\n\n return [];\n\n } catch (error) {\n throw new HttpError(`Failed to parse oncall information: ${error}`, 500);\n }\n}\n\nexport async function getServiceById(serviceId: string): Promise<PagerDutyService> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}/${serviceId}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyServiceResponse;\n try {\n result = await response.json() as PagerDutyServiceResponse;\n\n return result.service;\n } catch (error) {\n throw new HttpError(`Failed to parse service information: ${error}`, 500);\n }\n}\n\nexport async function getServiceByIntegrationKey(integrationKey: string): Promise<PagerDutyService> {\n let response: Response;\n const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyServicesResponse;\n try {\n result = await response.json() as PagerDutyServicesResponse;\n } catch (error) {\n throw new HttpError(`Failed to parse service information: ${error}`, 500);\n }\n\n if (result.services.length === 0) {\n throw new HttpError(`Failed to get service. The requested resource was not found.`, 404);\n }\n\n return result.services[0];\n}\n\nexport async function getChangeEvents(serviceId: string): Promise<PagerDutyChangeEvent[]> {\n let response: Response;\n const params = `limit=5&time_zone=UTC&sort_by=timestamp`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}/${serviceId}/change_events?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve change events for service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get change events for service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get change events for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get change events for service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get change events for service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyChangeEventsResponse;\n try {\n result = await response.json() as PagerDutyChangeEventsResponse;\n\n return result.change_events;\n } catch (error) {\n throw new HttpError(`Failed to parse change events information: ${error}`, 500);\n }\n}\n\nexport async function getIncidents(serviceId: string): Promise<PagerDutyIncident[]> {\n let response: Response;\n const params = `time_zone=UTC&sort_by=created_at&statuses[]=triggered&statuses[]=acknowledged&service_ids[]=${serviceId}`;\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/incidents`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve incidents for service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get incidents for service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get incidents for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 402:\n throw new HttpError(\"Failed to get incidents for service. Account does not have the abilities to perform the action. Please review the response for the required abilities.\", 402);\n case 403:\n throw new HttpError(\"Failed to get incidents for service. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to get incidents for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyIncidentsResponse;\n try {\n result = await response.json() as PagerDutyIncidentsResponse;\n\n return result.incidents;\n } catch (error) {\n throw new HttpError(`Failed to parse incidents information: ${error}`, 500);\n }\n}\n\nexport async function getServiceStandards(serviceId: string): Promise<PagerDutyServiceStandards> {\n let response: Response;\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/standards/scores/technical_services/${serviceId}`;\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service standards for service: ${error}`);\n }\n\n switch (response.status) {\n case 401:\n throw new HttpError(\"Failed to get service standards for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service standards for service. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to get service standards for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n try {\n const result = await response.json();\n return result;\n } catch (error) {\n throw new HttpError(`Failed to parse service standards information: ${error}`, 500);\n }\n}\n\nexport async function getServiceMetrics(serviceId: string): Promise<PagerDutyServiceMetrics[]> {\n let response: Response;\n \n const endDate = DateTime.now();\n const startDate = endDate.minus({ days: 30 });\n const body = JSON.stringify({\n filters: {\n created_at_start: startDate.toISO(),\n created_at_end: endDate.toISO(),\n service_ids: [\n serviceId\n ]\n }\n });\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n body: body\n };\n const baseUrl = `${apiBaseUrl}/analytics/metrics/incidents/services`;\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service metrics for service: ${error}`);\n }\n \n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service metrics for service. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.\", 400);\n case 429:\n throw new HttpError(\"Failed to get service metrics for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n try {\n const result = await response.json();\n\n return result.data;\n } catch (error) {\n throw new HttpError(`Failed to parse service metrics information: ${error}`, 500);\n }\n}\n\n","import { errorHandler } from '@backstage/backend-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { getAllEscalationPolicies, getChangeEvents, getIncidents, getOncallUsers, getServiceById, getServiceByIntegrationKey, setAPIBaseUrl, getServiceStandards, getServiceMetrics } from '../apis/pagerduty';\nimport { HttpError, PagerDutyChangeEventsResponse, PagerDutyIncidentsResponse, PagerDutyOnCallUsersResponse, PagerDutyServiceResponse, PagerDutyServiceStandardsResponse, PagerDutyServiceMetricsResponse } from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport { LoggerService, RootConfigService } from '@backstage/backend-plugin-api';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n}\n\nexport async function createRouter(\n options: RouterOptions\n): Promise<express.Router> {\n const { logger, config } = options; \n\n // Get authentication Config\n await loadAuthConfig(config, logger);\n\n // Get the PagerDuty API Base URL from config\n const baseUrl = config.getOptionalString('pagerDuty.apiBaseUrl') !== undefined ? config.getString('pagerDuty.apiBaseUrl') : 'https://api.pagerduty.com';\n setAPIBaseUrl(baseUrl);\n\n // Create the router\n const router = Router(); \n router.use(express.json());\n\n // Add routes\n // GET /escalation_policies\n router.get('/escalation_policies', async (_, response) => {\n try {\n const escalationPolicyList = await getAllEscalationPolicies();\n\n const escalationPolicyDropDownOptions = escalationPolicyList.map((policy) => {\n return {\n label: policy.name,\n value: policy.id,\n };\n });\n\n response.json(escalationPolicyDropDownOptions);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /oncall\n router.get('/oncall-users', async (request, response) => {\n try {\n // Get the escalation policy ID from the request parameters with parameter name \"escalation_policy_ids[]\"\n const escalationPolicyId: string = request.query.escalation_policy_ids as string || '';\n\n if (escalationPolicyId === '') {\n response.status(400).json(\"Bad Request: 'escalation_policy_ids[]' is required\");\n }\n\n const oncallUsers = await getOncallUsers(escalationPolicyId);\n const onCallUsersResponse: PagerDutyOnCallUsersResponse = {\n users: oncallUsers\n };\n\n response.json(onCallUsersResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId\n router.get('/services/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n if (serviceId === '') {\n response.status(400).json(\"Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter\");\n }\n\n const service = await getServiceById(serviceId);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services?integration_key=:integrationKey\n router.get('/services', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const integrationKey: string = request.query.integration_key as string || '';\n\n if (integrationKey === '') {\n response.status(400).json(\"Bad Request: 'integration_key' parameter is required\");\n }\n\n const service = await getServiceByIntegrationKey(integrationKey);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/change-events\n router.get('/services/:serviceId/change-events', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const changeEvents = await getChangeEvents(serviceId);\n const changeEventsResponse: PagerDutyChangeEventsResponse = {\n change_events: changeEvents\n }\n\n response.json(changeEventsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/incidents\n router.get('/services/:serviceId/incidents', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const incidents = await getIncidents(serviceId);\n const incidentsResponse: PagerDutyIncidentsResponse = {\n incidents\n }\n\n response.json(incidentsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/standards\n router.get('/services/:serviceId/standards', async (request, response) => {\n try {\n\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const serviceStandards = await getServiceStandards(serviceId);\n const serviceStandardsResponse: PagerDutyServiceStandardsResponse = {\n standards: serviceStandards\n }\n\n response.json(serviceStandardsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/metrics\n router.get('/services/:serviceId/metrics', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const metrics = await getServiceMetrics(serviceId);\n\n\n const metricsResponse: PagerDutyServiceMetricsResponse = {\n metrics: metrics\n };\n\n response.json(metricsResponse);\n\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /health\n router.get('/health', async (_, response) => {\n response.status(200).json({ status: 'ok' });\n });\n\n // Add error handler\n router.use(errorHandler());\n\n // Return the router\n return router;\n}","import { coreServices, createBackendPlugin } from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/** @public */\nexport const pagerDutyPlugin = createBackendPlugin({\n pluginId: 'pagerduty',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n httpRouter: coreServices.httpRouter, \n },\n async init({ config, logger, httpRouter }) {\n httpRouter.use(\n await createRouter({\n config,\n logger,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/',\n allow: 'unauthenticated',\n });\n },\n });\n }\n});"],"names":["HttpError","fetch","DateTime","Router","express","errorHandler","createBackendPlugin","coreServices"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/auth/auth.ts","../src/apis/pagerduty.ts","../src/db/PagerDutyBackendDatabase.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import { LoggerService, RootConfigService } from \"@backstage/backend-plugin-api\";\nimport { HttpError } from \"@pagerduty/backstage-plugin-common\";\n\ntype Auth = {\n config: RootConfigService;\n logger: LoggerService;\n authToken: string;\n authTokenExpiryDate: number;\n}\n\nlet authPersistence: Auth;\n\nexport async function getAuthToken(): Promise<string> {\n // check if token already exists and is valid\n if (\n (authPersistence.authToken !== '' &&\n authPersistence.authToken.includes('Bearer') &&\n authPersistence.authTokenExpiryDate > Date.now()) // case where OAuth token is still valid\n ||\n (authPersistence.authToken !== '' &&\n authPersistence.authToken.includes('Token'))) { // case where API token is used\n return authPersistence.authToken;\n }\n\n await loadAuthConfig(authPersistence.config, authPersistence.logger);\n return authPersistence.authToken;\n}\n\nexport async function loadAuthConfig(config : RootConfigService, logger: LoggerService) {\n try {\n\n // initiliaze the authPersistence in-memory object\n authPersistence = {\n config,\n logger,\n authToken: '',\n authTokenExpiryDate: Date.now()\n };\n\n if (!config.getOptionalString('pagerDuty.apiToken')) {\n logger.warn('No PagerDuty API token found in config file. Trying OAuth token instead...');\n\n if (!config.getOptional('pagerDuty.oauth')) {\n \n logger.error('No PagerDuty OAuth configuration found in config file.');\n\n } else if (!config.getOptionalString('pagerDuty.oauth.clientId') || !config.getOptionalString('pagerDuty.oauth.clientSecret') || !config.getOptionalString('pagerDuty.oauth.subDomain')) {\n \n logger.error(\"Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.\");\n\n } else {\n\n authPersistence.authToken = await getOAuthToken(\n config.getString('pagerDuty.oauth.clientId'),\n config.getString('pagerDuty.oauth.clientSecret'),\n config.getString('pagerDuty.oauth.subDomain'),\n config.getOptionalString('pagerDuty.oauth.region') ?? 'us');\n\n logger.info('PagerDuty OAuth configuration loaded successfully.');\n }\n } else {\n authPersistence.authToken = `Token token=${config.getString('pagerDuty.apiToken')}`;\n\n logger.info('PagerDuty API token loaded successfully.');\n }\n }\n catch (error) {\n logger.error(`Unable to retrieve valid PagerDuty AUTH configuration from config file: ${error}`);\n }\n}\n\nasync function getOAuthToken(clientId: string, clientSecret: string, subDomain: string, region: string): Promise<string> {\n // check if required parameters are provided\n if (!clientId || !clientSecret || !subDomain) {\n throw new Error('Missing required PagerDuty OAuth parameters.');\n }\n\n // define the scopes required for the OAuth token\n const scopes = `\n abilities.read \n analytics.read\n change_events.read \n escalation_policies.read \n incidents.read \n oncalls.read \n schedules.read \n services.read \n services.write \n standards.read\n teams.read \n users.read \n vendors.read\n `;\n\n // encode the parameters for the request\n const urlencoded = new URLSearchParams();\n urlencoded.append(\"grant_type\", \"client_credentials\");\n urlencoded.append(\"client_id\", clientId);\n urlencoded.append(\"client_secret\", clientSecret);\n urlencoded.append(\"scope\", `as_account-${region}.${subDomain} ${scopes}`);\n\n let response: Response;\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: urlencoded,\n };\n const baseUrl = 'https://identity.pagerduty.com/oauth/token';\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve oauth token: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to retrieve valid token. Bad Request - Invalid arguments provided.\", 400);\n case 401:\n throw new HttpError(\"Failed to retrieve valid token. Forbidden - Invalid credentials provided.\", 401);\n default: // 200\n break;\n }\n\n const authResponse = await response.json();\n authPersistence.authTokenExpiryDate = Date.now() + (authResponse.expires_in * 1000);\n return `Bearer ${authResponse.access_token}`;\n}","import fetch from 'node-fetch';\nimport type { RequestInit, Response } from 'node-fetch';\n\nimport { getAuthToken } from '../auth/auth';\n\nimport {\n PagerDutyServiceResponse,\n PagerDutyServicesResponse,\n PagerDutyEscalationPolicy,\n PagerDutyEscalationPoliciesResponse,\n PagerDutyAbilitiesResponse,\n PagerDutyOnCallsResponse,\n PagerDutyUser,\n PagerDutyService,\n PagerDutyChangeEventsResponse,\n PagerDutyChangeEvent,\n PagerDutyIncident,\n PagerDutyIncidentsResponse,\n PagerDutyServiceStandards,\n PagerDutyServiceMetrics,\n HttpError,\n PagerDutyServicesAPIResponse\n} from '@pagerduty/backstage-plugin-common';\n\nimport { DateTime } from 'luxon';\n\nlet apiBaseUrl = 'https://api.pagerduty.com';\nexport function setAPIBaseUrl(url: string): void {\n apiBaseUrl = url;\n}\n\n// Supporting router\n\nasync function getEscalationPolicies(offset: number, limit: number): Promise<[Boolean, PagerDutyEscalationPolicy[]]> {\n let response: Response;\n const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/escalation_policies`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve escalation policies: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to list escalation policies. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to list escalation policies. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to list escalation policies. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to list escalation policies. Rate limit exceeded.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyEscalationPoliciesResponse;\n try {\n result = await response.json() as PagerDutyEscalationPoliciesResponse;\n\n return [result.more ?? false, result.escalation_policies];\n\n } catch (error) {\n throw new HttpError(`Failed to parse escalation policy information: ${error}`, 500);\n }\n}\n\nexport async function getAllEscalationPolicies(offset: number = 0): Promise<PagerDutyEscalationPolicy[]> {\n const limit = 50;\n\n try {\n const res = await getEscalationPolicies(offset, limit);\n const results = res[1];\n\n // if more results exist\n if (res[0]) {\n return results.concat((await getAllEscalationPolicies(offset + limit)));\n }\n\n return results;\n } catch (error) {\n if (error instanceof HttpError) {\n throw error;\n }\n else {\n throw new HttpError(`${error}`, 500);\n }\n }\n}\n\nexport async function isEventNoiseReductionEnabled(): Promise<boolean> {\n let response: Response;\n const baseUrl = 'https://api.pagerduty.com';\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n\n try {\n response = await fetch(`${baseUrl}/abilities`, options);\n } catch (error) {\n throw new Error(`Failed to read abilities: ${error}`);\n }\n\n switch (response.status) {\n case 401:\n throw new Error(`Failed to read abilities. Caller did not supply credentials or did not provide the correct credentials.`);\n case 403:\n throw new Error(`Failed to read abilities. Caller is not authorized to view the requested resource.`);\n case 429:\n throw new Error(`Failed to read abilities. Rate limit exceeded.`);\n default: // 200\n break;\n }\n\n let result: PagerDutyAbilitiesResponse;\n try {\n result = await response.json() as PagerDutyAbilitiesResponse;\n\n if (result.abilities.includes('preview_intelligent_alert_grouping')\n && result.abilities.includes('time_based_alert_grouping')) {\n return true;\n }\n\n return false;\n\n } catch (error) {\n throw new Error(`Failed to parse abilities information: ${error}`);\n }\n}\n\nexport async function getOncallUsers(escalationPolicy: string): Promise<PagerDutyUser[]> {\n let response: Response;\n const params = `time_zone=UTC&include[]=users&escalation_policy_ids[]=${escalationPolicy}`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/oncalls`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve oncalls: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to list oncalls. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to list oncalls. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to list oncalls. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to list oncalls. Rate limit exceeded.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyOnCallsResponse;\n let usersItem: PagerDutyUser[];\n try {\n result = await response.json() as PagerDutyOnCallsResponse;\n\n if (result.oncalls.length !== 0) {\n const oncallsSorted = [...result.oncalls].sort((a, b) => {\n return a.escalation_level - b.escalation_level;\n });\n\n const oncallsFiltered = oncallsSorted.filter((oncall) => {\n return oncall.escalation_level === oncallsSorted[0].escalation_level;\n });\n\n usersItem = [...oncallsFiltered]\n .sort((a, b) => a.user.name > b.user.name ? 1 : -1)\n .map((oncall) => oncall.user);\n\n\n // remove duplicates from usersItem\n const uniqueUsers = new Map();\n usersItem.forEach((user) => {\n uniqueUsers.set(user.id, user);\n });\n\n usersItem.length = 0;\n uniqueUsers.forEach((user) => {\n usersItem.push(user);\n });\n\n return usersItem;\n }\n\n return [];\n\n } catch (error) {\n throw new HttpError(`Failed to parse oncall information: ${error}`, 500);\n }\n}\n\nexport async function getAllServices(): Promise<PagerDutyService[]> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n let allServices: PagerDutyService[] = [];\n let moreResults = true;\n let offset = 0;\n const limit = 50;\n while (moreResults) {\n try {\n response = await fetch(`${baseUrl}?${params}&offset=${offset}&limit=${limit}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve services: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get services. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get services. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get services. Caller is not authorized to view the requested resource.\", 403);\n default: // 200\n break;\n }\n\n let result: PagerDutyServicesAPIResponse;\n try {\n result = await response.json() as PagerDutyServicesAPIResponse;\n allServices = allServices.concat(result.services);\n if (result.more) {\n offset += limit;\n } else {\n moreResults = false;\n }\n } catch (error) {\n throw new HttpError(`Failed to parse service information: ${error}`, 500);\n }\n }\n return allServices;\n}\n\nexport async function getServiceById(serviceId: string): Promise<PagerDutyService> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}/${serviceId}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyServiceResponse;\n try {\n result = await response.json() as PagerDutyServiceResponse;\n\n return result.service;\n } catch (error) {\n throw new HttpError(`Failed to parse service information: ${error}`, 500);\n }\n}\n\nexport async function getServiceByIntegrationKey(integrationKey: string): Promise<PagerDutyService> {\n let response: Response;\n const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyServicesResponse;\n try {\n result = await response.json() as PagerDutyServicesResponse;\n } catch (error) {\n throw new HttpError(`Failed to parse service information: ${error}`, 500);\n }\n\n if (result.services.length === 0) {\n throw new HttpError(`Failed to get service. The requested resource was not found.`, 404);\n }\n\n return result.services[0];\n}\n\nexport async function getChangeEvents(serviceId: string): Promise<PagerDutyChangeEvent[]> {\n let response: Response;\n const params = `limit=5&time_zone=UTC&sort_by=timestamp`;\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/services`;\n\n try {\n response = await fetch(`${baseUrl}/${serviceId}/change_events?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve change events for service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get change events for service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get change events for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get change events for service. Caller is not authorized to view the requested resource.\", 403);\n case 404:\n throw new HttpError(\"Failed to get change events for service. The requested resource was not found.\", 404);\n default: // 200\n break;\n }\n\n let result: PagerDutyChangeEventsResponse;\n try {\n result = await response.json() as PagerDutyChangeEventsResponse;\n\n return result.change_events;\n } catch (error) {\n throw new HttpError(`Failed to parse change events information: ${error}`, 500);\n }\n}\n\nexport async function getIncidents(serviceId: string): Promise<PagerDutyIncident[]> {\n let response: Response;\n const params = `time_zone=UTC&sort_by=created_at&statuses[]=triggered&statuses[]=acknowledged&service_ids[]=${serviceId}`;\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/incidents`;\n\n try {\n response = await fetch(`${baseUrl}?${params}`, options);\n } catch (error) {\n throw new Error(`Failed to retrieve incidents for service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get incidents for service. Caller provided invalid arguments.\", 400);\n case 401:\n throw new HttpError(\"Failed to get incidents for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 402:\n throw new HttpError(\"Failed to get incidents for service. Account does not have the abilities to perform the action. Please review the response for the required abilities.\", 402);\n case 403:\n throw new HttpError(\"Failed to get incidents for service. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to get incidents for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n let result: PagerDutyIncidentsResponse;\n try {\n result = await response.json() as PagerDutyIncidentsResponse;\n\n return result.incidents;\n } catch (error) {\n throw new HttpError(`Failed to parse incidents information: ${error}`, 500);\n }\n}\n\nexport async function getServiceStandards(serviceId: string): Promise<PagerDutyServiceStandards> {\n let response: Response;\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n };\n const baseUrl = `${apiBaseUrl}/standards/scores/technical_services/${serviceId}`;\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service standards for service: ${error}`);\n }\n\n switch (response.status) {\n case 401:\n throw new HttpError(\"Failed to get service standards for service. Caller did not supply credentials or did not provide the correct credentials.\", 401);\n case 403:\n throw new HttpError(\"Failed to get service standards for service. Caller is not authorized to view the requested resource.\", 403);\n case 429:\n throw new HttpError(\"Failed to get service standards for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n try {\n const result = await response.json();\n return result;\n } catch (error) {\n throw new HttpError(`Failed to parse service standards information: ${error}`, 500);\n }\n}\n\nexport async function getServiceMetrics(serviceId: string): Promise<PagerDutyServiceMetrics[]> {\n let response: Response;\n\n const endDate = DateTime.now();\n const startDate = endDate.minus({ days: 30 });\n const body = JSON.stringify({\n filters: {\n created_at_start: startDate.toISO(),\n created_at_end: endDate.toISO(),\n service_ids: [\n serviceId\n ]\n }\n });\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n Authorization: await getAuthToken(),\n 'Accept': 'application/vnd.pagerduty+json;version=2',\n 'Content-Type': 'application/json',\n },\n body: body\n };\n const baseUrl = `${apiBaseUrl}/analytics/metrics/incidents/services`;\n\n try {\n response = await fetch(baseUrl, options);\n } catch (error) {\n throw new Error(`Failed to retrieve service metrics for service: ${error}`);\n }\n\n switch (response.status) {\n case 400:\n throw new HttpError(\"Failed to get service metrics for service. Caller provided invalid arguments. Please review the response for error details. Retrying with the same arguments will not work.\", 400);\n case 429:\n throw new HttpError(\"Failed to get service metrics for service. Too many requests have been made, the rate limit has been reached.\", 429);\n default: // 200\n break;\n }\n\n try {\n const result = await response.json();\n\n return result.data;\n } catch (error) {\n throw new HttpError(`Failed to parse service metrics information: ${error}`, 500);\n }\n}\n\n","import { resolvePackagePath } from \"@backstage/backend-plugin-api\";\nimport { Knex } from \"knex\";\nimport { v4 as uuid } from \"uuid\";\nimport { PagerDutyEntityMapping } from \"../types\";\n\nexport type RawDbEntityResultRow = {\n id: string;\n entity_ref: string;\n service_id: string;\n sync_status: \"InSync\" | \"OutOfSync\" | \"NotMapped\";\n last_synced_at: number;\n};\n\n\nconst migrationsDir = resolvePackagePath(\n '@pagerduty/backstage-plugin-backend',\n 'migrations',\n);\n\ntype Options = {\n database: Knex;\n};\n\n/** @public */\nexport class PagerDutyBackendDatabase {\n static async create(options: Options): Promise<PagerDutyBackendDatabase> {\n const { database } = options;\n\n await database.migrate.latest({\n directory: migrationsDir,\n });\n\n return new PagerDutyBackendDatabase(options);\n }\n\n private readonly database: Knex;\n\n private constructor(options: Options) {\n this.database = options.database;\n }\n\n async getAllEntityMappings(): Promise<RawDbEntityResultRow[]> {\n const results = await this.database<RawDbEntityResultRow>(\"pagerduty_entity_mapping\").select();\n return results;\n }\n\n async insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string> {\n const mappingId = uuid();\n\n const [result] = await this.database<RawDbEntityResultRow>(\n \"pagerduty_entity_mapping\"\n )\n .insert({\n id: mappingId,\n service_id: entity.serviceId,\n entity_ref: entity.entityRef,\n sync_status: \"InSync\",\n last_synced_at: Date.now(),\n })\n .onConflict(\"entityRef\")\n .merge([\"service_id\", \"sync_status\", \"last_synced_at\"])\n .returning(\"id\");\n\n return result.id;\n }\n}\n","import { PluginDatabaseManager, errorHandler } from '@backstage/backend-common';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { getAllEscalationPolicies, getChangeEvents, getIncidents, getOncallUsers, getServiceById, getServiceByIntegrationKey, setAPIBaseUrl, getServiceStandards, getServiceMetrics, getAllServices } from '../apis/pagerduty';\nimport { HttpError, PagerDutyChangeEventsResponse, PagerDutyIncidentsResponse, PagerDutyOnCallUsersResponse, PagerDutyServiceResponse, PagerDutyServiceStandardsResponse, PagerDutyServiceMetricsResponse, PagerDutyServicesResponse } from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport { LoggerService, RootConfigService } from '@backstage/backend-plugin-api';\nimport { PagerDutyBackendDatabase } from '../db';\n// import { PagerDutyBackendDatabase } from '../db';\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n database: PluginDatabaseManager;\n}\n\nexport async function createRouter(\n options: RouterOptions\n): Promise<express.Router> {\n const { logger, config, database } = options;\n\n // Get authentication Config\n await loadAuthConfig(config, logger);\n\n // Get the PagerDuty API Base URL from config\n const baseUrl = config.getOptionalString('pagerDuty.apiBaseUrl') !== undefined ? config.getString('pagerDuty.apiBaseUrl') : 'https://api.pagerduty.com';\n setAPIBaseUrl(baseUrl);\n\n // get database client\n const pagerDutyEntityStore = await PagerDutyBackendDatabase.create({\n database: await database.getClient()\n });\n\n // Create the router\n const router = Router();\n router.use(express.json());\n\n // Database persistence\n // POST /mapping/entity\n router.post('/mapping/entity', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const entity = request.body;\n\n if (!entity.entity_ref) {\n response.status(400).json(\"Bad Request: 'entity_ref' is required\");\n }\n\n const entityMappingId = pagerDutyEntityStore.insertEntityMapping(entity);\n\n response.json({\n id: entityMappingId\n });\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /mapping/\n router.get('/mapping', async (_, response) => {\n try {\n const entityMappings = await pagerDutyEntityStore.getAllEntityMappings();\n\n response.json(entityMappings);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // Add routes\n // GET /escalation_policies\n router.get('/escalation_policies', async (_, response) => {\n try {\n const escalationPolicyList = await getAllEscalationPolicies();\n\n const escalationPolicyDropDownOptions = escalationPolicyList.map((policy) => {\n return {\n label: policy.name,\n value: policy.id,\n };\n });\n\n response.json(escalationPolicyDropDownOptions);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /oncall\n router.get('/oncall-users', async (request, response) => {\n try {\n // Get the escalation policy ID from the request parameters with parameter name \"escalation_policy_ids[]\"\n const escalationPolicyId: string = request.query.escalation_policy_ids as string || '';\n\n if (escalationPolicyId === '') {\n response.status(400).json(\"Bad Request: 'escalation_policy_ids[]' is required\");\n }\n\n const oncallUsers = await getOncallUsers(escalationPolicyId);\n const onCallUsersResponse: PagerDutyOnCallUsersResponse = {\n users: oncallUsers\n };\n\n response.json(onCallUsersResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId\n router.get('/services/:serviceId', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n if (serviceId === '') {\n response.status(400).json(\"Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter\");\n }\n\n const service = await getServiceById(serviceId);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services?integration_key=:integrationKey\n router.get('/services', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const integrationKey: string = request.query.integration_key as string || '';\n\n if (integrationKey !== '') {\n // response.status(400).json(\"Bad Request: 'integration_key' parameter is required\");\n // }\n const service = await getServiceByIntegrationKey(integrationKey);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } else {\n const allServices = await getAllServices();\n const allServicesResponse: PagerDutyServicesResponse = {\n services: allServices\n }\n\n response.json(allServicesResponse);\n }\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/change-events\n router.get('/services/:serviceId/change-events', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const changeEvents = await getChangeEvents(serviceId);\n const changeEventsResponse: PagerDutyChangeEventsResponse = {\n change_events: changeEvents\n }\n\n response.json(changeEventsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/incidents\n router.get('/services/:serviceId/incidents', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const incidents = await getIncidents(serviceId);\n const incidentsResponse: PagerDutyIncidentsResponse = {\n incidents\n }\n\n response.json(incidentsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/standards\n router.get('/services/:serviceId/standards', async (request, response) => {\n try {\n\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const serviceStandards = await getServiceStandards(serviceId);\n const serviceStandardsResponse: PagerDutyServiceStandardsResponse = {\n standards: serviceStandards\n }\n\n response.json(serviceStandardsResponse);\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /services/:serviceId/metrics\n router.get('/services/:serviceId/metrics', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const serviceId: string = request.params.serviceId || '';\n\n const metrics = await getServiceMetrics(serviceId);\n\n\n const metricsResponse: PagerDutyServiceMetricsResponse = {\n metrics: metrics\n };\n\n response.json(metricsResponse);\n\n } catch (error) {\n if (error instanceof HttpError) {\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /health\n router.get('/health', async (_, response) => {\n response.status(200).json({ status: 'ok' });\n });\n\n // Add error handler\n router.use(errorHandler());\n\n // Return the router\n return router;\n}","import { coreServices, createBackendPlugin } from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/** @public */\nexport const pagerDutyPlugin = createBackendPlugin({\n pluginId: 'pagerduty',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n httpRouter: coreServices.httpRouter, \n database: coreServices.database, \n },\n async init({ config, logger, httpRouter, database }) {\n httpRouter.use(\n await createRouter({\n config,\n logger,\n database,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/',\n allow: 'unauthenticated',\n });\n },\n });\n }\n});"],"names":["HttpError","fetch","DateTime","resolvePackagePath","uuid","Router","express","errorHandler","createBackendPlugin","coreServices"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PluginDatabaseManager } from '@backstage/backend-common';
|
|
1
2
|
import express from 'express';
|
|
2
3
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
3
4
|
import { LoggerService, RootConfigService } from '@backstage/backend-plugin-api';
|
|
@@ -5,10 +6,11 @@ import { LoggerService, RootConfigService } from '@backstage/backend-plugin-api'
|
|
|
5
6
|
interface RouterOptions {
|
|
6
7
|
logger: LoggerService;
|
|
7
8
|
config: RootConfigService;
|
|
9
|
+
database: PluginDatabaseManager;
|
|
8
10
|
}
|
|
9
11
|
declare function createRouter(options: RouterOptions): Promise<express.Router>;
|
|
10
12
|
|
|
11
13
|
/** @public */
|
|
12
14
|
declare const pagerDutyPlugin: () => _backstage_backend_plugin_api.BackendFeature;
|
|
13
15
|
|
|
14
|
-
export { RouterOptions, createRouter, pagerDutyPlugin as default };
|
|
16
|
+
export { type RouterOptions, createRouter, pagerDutyPlugin as default };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
// @ts-check
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {import('knex').Knex} knex
|
|
6
|
+
*/
|
|
7
|
+
exports.up = async function up(knex) {
|
|
8
|
+
// Note for the reader: the knex increments types automatically make it a
|
|
9
|
+
// primary column, whether you like it or not. That's why the id column is
|
|
10
|
+
// not marked as primary as one might have expected; it's only used for
|
|
11
|
+
// lookups by ID. Because, SQLite and MySQL don't return RETURNING on
|
|
12
|
+
// inserts ... so we want a manually generated key for lookups (an uuid),
|
|
13
|
+
// and also an index for ordering guarantees :)
|
|
14
|
+
await knex.schema.createTable('pagerduty_entity_mapping', table => {
|
|
15
|
+
table.comment('Table containing entity mappings for PagerDuty services');
|
|
16
|
+
table.uuid('id').notNullable().comment('The ID of the mapping');
|
|
17
|
+
table
|
|
18
|
+
.string('entity_ref')
|
|
19
|
+
.unique()
|
|
20
|
+
.notNullable()
|
|
21
|
+
.comment('The entity ref that this mapping applies to');
|
|
22
|
+
table
|
|
23
|
+
.string('service_id')
|
|
24
|
+
.notNullable()
|
|
25
|
+
.comment('The PagerDuty service ID that this entity is mapped to');
|
|
26
|
+
table
|
|
27
|
+
.string('sync_status')
|
|
28
|
+
.notNullable()
|
|
29
|
+
.defaultTo('NotMapped')
|
|
30
|
+
.comment('The status of the sync for this entity');
|
|
31
|
+
table
|
|
32
|
+
.dateTime('last_synced_at')
|
|
33
|
+
.defaultTo(knex.fn.now())
|
|
34
|
+
.notNullable()
|
|
35
|
+
.comment('The timestamp when this entry was processed');
|
|
36
|
+
table.index('id', 'entity_mapping_id_idx');
|
|
37
|
+
table.index('entity_ref', 'entity_mapping_entity_ref_idx');
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {import('knex').Knex} knex
|
|
43
|
+
*/
|
|
44
|
+
exports.down = async function down(knex) {
|
|
45
|
+
await knex.schema.alterTable('entity_result', table => {
|
|
46
|
+
table.dropIndex([], 'entity_mapping_id_idx');
|
|
47
|
+
table.dropIndex([], 'entity_mapping_entity_ref_idx');
|
|
48
|
+
});
|
|
49
|
+
await knex.schema.dropTable('pagerduty_entity_mapping');
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagerduty/backstage-plugin-backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-next.0",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,32 +22,34 @@
|
|
|
22
22
|
"postpack": "backstage-cli package postpack"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@backstage/backend-common": "^0.
|
|
26
|
-
"@backstage/backend-defaults": "^0.2.
|
|
27
|
-
"@backstage/backend-plugin-api": "^0.6.
|
|
25
|
+
"@backstage/backend-common": "^0.22.0",
|
|
26
|
+
"@backstage/backend-defaults": "^0.2.18",
|
|
27
|
+
"@backstage/backend-plugin-api": "^0.6.18",
|
|
28
28
|
"@backstage/config": "^1.2.0",
|
|
29
|
-
"@backstage/core-plugin-api": "^1.9.
|
|
30
|
-
"@backstage/plugin-scaffolder-node": "^0.4.
|
|
29
|
+
"@backstage/core-plugin-api": "^1.9.2",
|
|
30
|
+
"@backstage/plugin-scaffolder-node": "^0.4.4",
|
|
31
31
|
"@material-ui/core": "^4.12.4",
|
|
32
|
+
"@pagerduty/backstage-plugin-common": "0.1.4-next.1",
|
|
32
33
|
"@rjsf/core": "^5.14.3",
|
|
33
34
|
"@types/express": "^4.17.6",
|
|
35
|
+
"better-sqlite3": "^10.0.0",
|
|
34
36
|
"express": "^4.19.2",
|
|
35
37
|
"express-promise-router": "^4.1.0",
|
|
38
|
+
"knex": "^3.1.0",
|
|
36
39
|
"luxon": "^3.4.4",
|
|
37
40
|
"node-fetch": "^2.6.7",
|
|
41
|
+
"uuid": "^9.0.1",
|
|
38
42
|
"winston": "^3.2.1",
|
|
39
43
|
"yn": "^4.0.0",
|
|
40
44
|
"zod": "^3.22.4"
|
|
41
45
|
},
|
|
42
|
-
"peerDependencies": {
|
|
43
|
-
"@pagerduty/backstage-plugin-common": "^0.1.3"
|
|
44
|
-
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@backstage/
|
|
47
|
-
"@
|
|
47
|
+
"@backstage/backend-test-utils": "^0.3.8",
|
|
48
|
+
"@backstage/cli": "^0.26.5",
|
|
48
49
|
"@types/node": "^20.9.2",
|
|
49
50
|
"@types/node-fetch": "2.6.11",
|
|
50
51
|
"@types/supertest": "^2.0.12",
|
|
52
|
+
"@types/uuid": "^9.0.8",
|
|
51
53
|
"@types/webpack-env": "1.18.4",
|
|
52
54
|
"jest-mock": "29.7.0",
|
|
53
55
|
"msw": "^1.0.0",
|
|
@@ -56,8 +58,9 @@
|
|
|
56
58
|
},
|
|
57
59
|
"files": [
|
|
58
60
|
"dist",
|
|
59
|
-
"config.d.ts"
|
|
61
|
+
"config.d.ts",
|
|
62
|
+
"migrations/**/*.{js,d.ts}"
|
|
60
63
|
],
|
|
61
64
|
"configSchema": "config.d.ts",
|
|
62
|
-
"packageManager": "yarn@
|
|
65
|
+
"packageManager": "yarn@4.2.2"
|
|
63
66
|
}
|