@pagerduty/backstage-plugin-backend 0.8.0-next.2 → 0.8.0-next.21
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/README.md +1 -2
- package/config.d.ts +1 -6
- package/dist/index.cjs.js +144 -51
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,7 +12,6 @@ The PagerDuty backend plugin augments the capabilities of the [PagerDuty fronten
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- **REST APIs** The backend is responsible for all requests to PagerDuty REST APIs. Centralizing these in the backend plugin allows us to only expose the information the frontend needs and therefore improve security and performance.
|
|
15
|
-
- **Data Persistence** The backend component is also responsible for the data persistence layer for the PagerDuty plugin for Backstage.
|
|
16
15
|
|
|
17
16
|
## Getting Started
|
|
18
17
|
|
|
@@ -25,7 +24,7 @@ The installation of the PagerDuty plugin for Backstage is done with *yarn* as al
|
|
|
25
24
|
To install this plugin run the following command from the Backstage root folder.
|
|
26
25
|
|
|
27
26
|
```bash
|
|
28
|
-
yarn add --cwd packages/backend @pagerduty/backstage-plugin-backend
|
|
27
|
+
yarn add --cwd packages/backend @pagerduty/backstage-plugin-backend @pagerduty/backstage-plugin-common
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
### Configuration
|
package/config.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { PagerDutyOAuthConfig
|
|
17
|
+
import { PagerDutyOAuthConfig } from '@pagerduty/backstage-plugin-common';
|
|
18
18
|
|
|
19
19
|
export interface Config {
|
|
20
20
|
/**
|
|
@@ -42,10 +42,5 @@ export interface Config {
|
|
|
42
42
|
* @deepVisibility secret
|
|
43
43
|
*/
|
|
44
44
|
oauth?: PagerDutyOAuthConfig;
|
|
45
|
-
/**
|
|
46
|
-
* Optional configuration for PagerDuty accounts.
|
|
47
|
-
* @deepVisibility secret
|
|
48
|
-
*/
|
|
49
|
-
accounts?: PagerDutyAccountConfig[];
|
|
50
45
|
};
|
|
51
46
|
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -37,43 +37,118 @@ var express__namespace = /*#__PURE__*/_interopNamespaceCompat(express);
|
|
|
37
37
|
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
38
38
|
|
|
39
39
|
let authPersistence;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
let isLegacyConfig = false;
|
|
41
|
+
async function getAuthToken(accountId) {
|
|
42
|
+
var _a;
|
|
43
|
+
if (!authPersistence || !authPersistence.accountTokens) {
|
|
44
|
+
authPersistence.logger.info("AUTH - Auth config not loaded. Loading auth config...");
|
|
45
|
+
await loadAuthConfig(authPersistence.config, authPersistence.logger);
|
|
46
|
+
}
|
|
47
|
+
if (isLegacyConfig) {
|
|
48
|
+
authPersistence.logger.info("AUTH - Using legacy configuration.");
|
|
49
|
+
if (authPersistence.accountTokens.default.authToken !== "" && authPersistence.accountTokens.default.authToken.includes("Bearer") && authPersistence.accountTokens.default.authTokenExpiryDate > Date.now() || authPersistence.accountTokens.default.authToken !== "" && authPersistence.accountTokens.default.authToken.includes("Token")) {
|
|
50
|
+
authPersistence.logger.info("AUTH - Using default account token: ${authPersistence.accountTokens.default.authToken}");
|
|
51
|
+
return authPersistence.accountTokens.default.authToken;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
if (accountId && accountId !== "") {
|
|
55
|
+
if (authPersistence.accountTokens[accountId].authToken !== "" && authPersistence.accountTokens[accountId].authToken.includes("Bearer") && authPersistence.accountTokens[accountId].authTokenExpiryDate > Date.now() || authPersistence.accountTokens[accountId].authToken !== "" && authPersistence.accountTokens[accountId].authToken.includes("Token")) {
|
|
56
|
+
authPersistence.logger.info(`AUTH - Using account ${accountId} token: ${authPersistence.accountTokens[accountId].authToken}`);
|
|
57
|
+
return authPersistence.accountTokens[accountId].authToken;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
const defaultFallback = (_a = authPersistence.defaultAccount) != null ? _a : "";
|
|
61
|
+
if (authPersistence.accountTokens[defaultFallback].authToken !== "" && authPersistence.accountTokens[defaultFallback].authToken.includes("Bearer") && authPersistence.accountTokens[defaultFallback].authTokenExpiryDate > Date.now() || authPersistence.accountTokens[defaultFallback].authToken !== "" && authPersistence.accountTokens[defaultFallback].authToken.includes("Token")) {
|
|
62
|
+
authPersistence.logger.info(`AUTH - Using fallback account ${defaultFallback} token: ${authPersistence.accountTokens[defaultFallback].authToken}`);
|
|
63
|
+
return authPersistence.accountTokens[defaultFallback].authToken;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
43
66
|
}
|
|
44
|
-
|
|
45
|
-
return authPersistence.authToken;
|
|
67
|
+
return "";
|
|
46
68
|
}
|
|
47
69
|
async function loadAuthConfig(config, logger) {
|
|
48
70
|
var _a;
|
|
49
71
|
try {
|
|
72
|
+
const defaultAccountId = "default";
|
|
50
73
|
authPersistence = {
|
|
51
74
|
config,
|
|
52
75
|
logger,
|
|
53
|
-
|
|
54
|
-
authTokenExpiryDate: Date.now()
|
|
76
|
+
accountTokens: {}
|
|
55
77
|
};
|
|
56
|
-
if (config.getOptional("pagerDuty.accounts")) {
|
|
57
|
-
|
|
58
|
-
logger.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
if (!config.getOptional("pagerDuty.accounts")) {
|
|
79
|
+
isLegacyConfig = true;
|
|
80
|
+
logger.warn("No PagerDuty accounts configuration found in config file. Reverting to legacy configuration.");
|
|
81
|
+
if (!config.getOptionalString("pagerDuty.apiToken")) {
|
|
82
|
+
logger.warn("No PagerDuty API token found in config file. Trying OAuth token instead...");
|
|
83
|
+
if (!config.getOptional("pagerDuty.oauth")) {
|
|
84
|
+
logger.error("No PagerDuty OAuth configuration found in config file.");
|
|
85
|
+
} else if (!config.getOptionalString("pagerDuty.oauth.clientId") || !config.getOptionalString("pagerDuty.oauth.clientSecret") || !config.getOptionalString("pagerDuty.oauth.subDomain")) {
|
|
86
|
+
logger.error("Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.");
|
|
87
|
+
} else {
|
|
88
|
+
const tokenInfo = await getOAuthToken(
|
|
89
|
+
config.getString("pagerDuty.oauth.clientId"),
|
|
90
|
+
config.getString("pagerDuty.oauth.clientSecret"),
|
|
91
|
+
config.getString("pagerDuty.oauth.subDomain"),
|
|
92
|
+
(_a = config.getOptionalString("pagerDuty.oauth.region")) != null ? _a : "us"
|
|
93
|
+
);
|
|
94
|
+
logger.info(`tokenInfo: ${JSON.stringify(tokenInfo)}`);
|
|
95
|
+
logger.info(`authPersistence.accountTokens: ${JSON.stringify(authPersistence.accountTokens)}`);
|
|
96
|
+
logger.info(`tokenInfo: ${JSON.stringify(tokenInfo)}`);
|
|
97
|
+
authPersistence.accountTokens[defaultAccountId] = tokenInfo;
|
|
98
|
+
logger.info("PagerDuty OAuth configuration loaded successfully.");
|
|
99
|
+
}
|
|
65
100
|
} else {
|
|
66
|
-
authPersistence.
|
|
67
|
-
config.getString("pagerDuty.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
72
|
-
logger.info("PagerDuty OAuth configuration loaded successfully.");
|
|
101
|
+
authPersistence.accountTokens[defaultAccountId] = {
|
|
102
|
+
authToken: `Token token=${config.getString("pagerDuty.apiToken")}`,
|
|
103
|
+
authTokenExpiryDate: Date.now() + 36e5 * 24 * 365 * 2
|
|
104
|
+
// 2 years
|
|
105
|
+
};
|
|
106
|
+
logger.info("PagerDuty API token loaded successfully.");
|
|
73
107
|
}
|
|
74
108
|
} else {
|
|
75
|
-
|
|
76
|
-
|
|
109
|
+
logger.info("New PagerDuty accounts configuration found in config file.");
|
|
110
|
+
isLegacyConfig = false;
|
|
111
|
+
const accounts = config.getOptional("pagerDuty.accounts");
|
|
112
|
+
if (accounts && (accounts == null ? void 0 : accounts.length) === 1) {
|
|
113
|
+
logger.info("Only one account found in config file. Setting it as default.");
|
|
114
|
+
authPersistence.defaultAccount = accounts[0].id;
|
|
115
|
+
}
|
|
116
|
+
accounts == null ? void 0 : accounts.forEach(async (account) => {
|
|
117
|
+
var _a2;
|
|
118
|
+
const maskedAccountId = maskString(account.id);
|
|
119
|
+
if (account.isDefault && !authPersistence.defaultAccount) {
|
|
120
|
+
logger.info(`Default account found in config file. Setting it as default.`);
|
|
121
|
+
authPersistence.defaultAccount = account.id;
|
|
122
|
+
}
|
|
123
|
+
if (!account.apiToken) {
|
|
124
|
+
logger.warn("No PagerDuty API token found in config file. Trying OAuth token instead...");
|
|
125
|
+
if (!account.oauth) {
|
|
126
|
+
logger.error("No PagerDuty OAuth configuration found in config file.");
|
|
127
|
+
} else if (!account.oauth.clientId || !account.oauth.clientSecret || !account.oauth.subDomain) {
|
|
128
|
+
logger.error("Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.");
|
|
129
|
+
} else {
|
|
130
|
+
const tokenInfo = await getOAuthToken(
|
|
131
|
+
account.oauth.clientId,
|
|
132
|
+
account.oauth.clientSecret,
|
|
133
|
+
account.oauth.subDomain,
|
|
134
|
+
(_a2 = account.oauth.region) != null ? _a2 : "us"
|
|
135
|
+
);
|
|
136
|
+
authPersistence.accountTokens[account.id] = tokenInfo;
|
|
137
|
+
logger.info(`tokenInfo: ${JSON.stringify(tokenInfo)}`);
|
|
138
|
+
logger.info(`PagerDuty OAuth configuration loaded successfully for account ${maskedAccountId}.`);
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
authPersistence.accountTokens[account.id] = {
|
|
142
|
+
authToken: `Token token=${account.apiToken}`,
|
|
143
|
+
authTokenExpiryDate: Date.now() + 36e5 * 24 * 365 * 2
|
|
144
|
+
// 2 years
|
|
145
|
+
};
|
|
146
|
+
logger.info(`PagerDuty API token loaded successfully for account ${maskedAccountId}.`);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (!authPersistence.defaultAccount) {
|
|
150
|
+
logger.error("No default account found in config file. One account must be marked as default.");
|
|
151
|
+
}
|
|
77
152
|
}
|
|
78
153
|
} catch (error) {
|
|
79
154
|
logger.error(`Unable to retrieve valid PagerDuty AUTH configuration from config file: ${error}`);
|
|
@@ -124,22 +199,28 @@ async function getOAuthToken(clientId, clientSecret, subDomain, region) {
|
|
|
124
199
|
throw new backstagePluginCommon.HttpError("Failed to retrieve valid token. Forbidden - Invalid credentials provided.", 401);
|
|
125
200
|
}
|
|
126
201
|
const authResponse = await response.json();
|
|
127
|
-
|
|
128
|
-
|
|
202
|
+
const result = {
|
|
203
|
+
authToken: `Bearer ${authResponse.access_token}`,
|
|
204
|
+
authTokenExpiryDate: Date.now() + authResponse.expires_in * 1e3
|
|
205
|
+
};
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
function maskString(str) {
|
|
209
|
+
return str[0] + "*".repeat(str.length - 2) + str.slice(-1);
|
|
129
210
|
}
|
|
130
211
|
|
|
131
212
|
let apiBaseUrl = "https://api.pagerduty.com";
|
|
132
213
|
function setAPIBaseUrl(url) {
|
|
133
214
|
apiBaseUrl = url;
|
|
134
215
|
}
|
|
135
|
-
async function getEscalationPolicies(offset, limit) {
|
|
216
|
+
async function getEscalationPolicies(offset, limit, account) {
|
|
136
217
|
var _a;
|
|
137
218
|
let response;
|
|
138
219
|
const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;
|
|
139
220
|
const options = {
|
|
140
221
|
method: "GET",
|
|
141
222
|
headers: {
|
|
142
|
-
Authorization: await getAuthToken(),
|
|
223
|
+
Authorization: await getAuthToken(account),
|
|
143
224
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
144
225
|
"Content-Type": "application/json"
|
|
145
226
|
}
|
|
@@ -185,13 +266,13 @@ async function getAllEscalationPolicies(offset = 0) {
|
|
|
185
266
|
}
|
|
186
267
|
}
|
|
187
268
|
}
|
|
188
|
-
async function getOncallUsers(escalationPolicy) {
|
|
269
|
+
async function getOncallUsers(escalationPolicy, account) {
|
|
189
270
|
let response;
|
|
190
271
|
const params = `time_zone=UTC&include[]=users&escalation_policy_ids[]=${escalationPolicy}`;
|
|
191
272
|
const options = {
|
|
192
273
|
method: "GET",
|
|
193
274
|
headers: {
|
|
194
|
-
Authorization: await getAuthToken(),
|
|
275
|
+
Authorization: await getAuthToken(account),
|
|
195
276
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
196
277
|
"Content-Type": "application/json"
|
|
197
278
|
}
|
|
@@ -239,13 +320,15 @@ async function getOncallUsers(escalationPolicy) {
|
|
|
239
320
|
throw new backstagePluginCommon.HttpError(`Failed to parse oncall information: ${error}`, 500);
|
|
240
321
|
}
|
|
241
322
|
}
|
|
242
|
-
async function getServiceById(serviceId) {
|
|
323
|
+
async function getServiceById(serviceId, account) {
|
|
243
324
|
let response;
|
|
244
325
|
const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
326
|
+
const token = await getAuthToken(account);
|
|
327
|
+
console.log(`Token being used for request: ${token}`);
|
|
245
328
|
const options = {
|
|
246
329
|
method: "GET",
|
|
247
330
|
headers: {
|
|
248
|
-
Authorization:
|
|
331
|
+
Authorization: token,
|
|
249
332
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
250
333
|
"Content-Type": "application/json"
|
|
251
334
|
}
|
|
@@ -274,13 +357,13 @@ async function getServiceById(serviceId) {
|
|
|
274
357
|
throw new backstagePluginCommon.HttpError(`Failed to parse service information: ${error}`, 500);
|
|
275
358
|
}
|
|
276
359
|
}
|
|
277
|
-
async function getServiceByIntegrationKey(integrationKey) {
|
|
360
|
+
async function getServiceByIntegrationKey(integrationKey, account) {
|
|
278
361
|
let response;
|
|
279
362
|
const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
280
363
|
const options = {
|
|
281
364
|
method: "GET",
|
|
282
365
|
headers: {
|
|
283
|
-
Authorization: await getAuthToken(),
|
|
366
|
+
Authorization: await getAuthToken(account),
|
|
284
367
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
285
368
|
"Content-Type": "application/json"
|
|
286
369
|
}
|
|
@@ -351,13 +434,13 @@ async function getAllServices() {
|
|
|
351
434
|
}
|
|
352
435
|
return allServices;
|
|
353
436
|
}
|
|
354
|
-
async function getChangeEvents(serviceId) {
|
|
437
|
+
async function getChangeEvents(serviceId, account) {
|
|
355
438
|
let response;
|
|
356
439
|
const params = `limit=5&time_zone=UTC&sort_by=timestamp`;
|
|
357
440
|
const options = {
|
|
358
441
|
method: "GET",
|
|
359
442
|
headers: {
|
|
360
|
-
Authorization: await getAuthToken(),
|
|
443
|
+
Authorization: await getAuthToken(account),
|
|
361
444
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
362
445
|
"Content-Type": "application/json"
|
|
363
446
|
}
|
|
@@ -386,13 +469,13 @@ async function getChangeEvents(serviceId) {
|
|
|
386
469
|
throw new backstagePluginCommon.HttpError(`Failed to parse change events information: ${error}`, 500);
|
|
387
470
|
}
|
|
388
471
|
}
|
|
389
|
-
async function getIncidents(serviceId) {
|
|
472
|
+
async function getIncidents(serviceId, account) {
|
|
390
473
|
let response;
|
|
391
474
|
const params = `time_zone=UTC&sort_by=created_at&statuses[]=triggered&statuses[]=acknowledged&service_ids[]=${serviceId}`;
|
|
392
475
|
const options = {
|
|
393
476
|
method: "GET",
|
|
394
477
|
headers: {
|
|
395
|
-
Authorization: await getAuthToken(),
|
|
478
|
+
Authorization: await getAuthToken(account),
|
|
396
479
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
397
480
|
"Content-Type": "application/json"
|
|
398
481
|
}
|
|
@@ -423,12 +506,12 @@ async function getIncidents(serviceId) {
|
|
|
423
506
|
throw new backstagePluginCommon.HttpError(`Failed to parse incidents information: ${error}`, 500);
|
|
424
507
|
}
|
|
425
508
|
}
|
|
426
|
-
async function getServiceStandards(serviceId) {
|
|
509
|
+
async function getServiceStandards(serviceId, account) {
|
|
427
510
|
let response;
|
|
428
511
|
const options = {
|
|
429
512
|
method: "GET",
|
|
430
513
|
headers: {
|
|
431
|
-
Authorization: await getAuthToken(),
|
|
514
|
+
Authorization: await getAuthToken(account),
|
|
432
515
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
433
516
|
"Content-Type": "application/json"
|
|
434
517
|
}
|
|
@@ -454,7 +537,7 @@ async function getServiceStandards(serviceId) {
|
|
|
454
537
|
throw new backstagePluginCommon.HttpError(`Failed to parse service standards information: ${error}`, 500);
|
|
455
538
|
}
|
|
456
539
|
}
|
|
457
|
-
async function getServiceMetrics(serviceId) {
|
|
540
|
+
async function getServiceMetrics(serviceId, account) {
|
|
458
541
|
let response;
|
|
459
542
|
const endDate = luxon.DateTime.now();
|
|
460
543
|
const startDate = endDate.minus({ days: 30 });
|
|
@@ -470,7 +553,7 @@ async function getServiceMetrics(serviceId) {
|
|
|
470
553
|
const options = {
|
|
471
554
|
method: "POST",
|
|
472
555
|
headers: {
|
|
473
|
-
Authorization: await getAuthToken(),
|
|
556
|
+
Authorization: await getAuthToken(account),
|
|
474
557
|
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
475
558
|
"Content-Type": "application/json"
|
|
476
559
|
},
|
|
@@ -499,16 +582,18 @@ async function getServiceMetrics(serviceId) {
|
|
|
499
582
|
async function createComponentEntitiesReferenceDict({ items: componentEntities }) {
|
|
500
583
|
const componentEntitiesDict = {};
|
|
501
584
|
await Promise.all(componentEntities.map(async (entity) => {
|
|
585
|
+
var _a;
|
|
502
586
|
const annotations = JSON.parse(JSON.stringify(entity.metadata.annotations));
|
|
503
587
|
const serviceId = annotations["pagerduty.com/service-id"];
|
|
504
588
|
const integrationKey = annotations["pagerduty.com/integration-key"];
|
|
589
|
+
const account = (_a = annotations["pagerduty.com/account"]) != null ? _a : "";
|
|
505
590
|
if (serviceId !== void 0 && serviceId !== "") {
|
|
506
591
|
componentEntitiesDict[serviceId] = {
|
|
507
592
|
ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),
|
|
508
593
|
name: entity.metadata.name
|
|
509
594
|
};
|
|
510
595
|
} else if (integrationKey !== void 0 && integrationKey !== "") {
|
|
511
|
-
const service = await getServiceByIntegrationKey(integrationKey);
|
|
596
|
+
const service = await getServiceByIntegrationKey(integrationKey, account);
|
|
512
597
|
if (service !== void 0) {
|
|
513
598
|
componentEntitiesDict[service.id] = {
|
|
514
599
|
ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),
|
|
@@ -744,10 +829,11 @@ async function createRouter(options) {
|
|
|
744
829
|
router.get("/oncall-users", async (request, response) => {
|
|
745
830
|
try {
|
|
746
831
|
const escalationPolicyId = request.query.escalation_policy_ids || "";
|
|
832
|
+
const account = request.query.account || "";
|
|
747
833
|
if (escalationPolicyId === "") {
|
|
748
834
|
response.status(400).json("Bad Request: 'escalation_policy_ids[]' is required");
|
|
749
835
|
}
|
|
750
|
-
const oncallUsers = await getOncallUsers(escalationPolicyId);
|
|
836
|
+
const oncallUsers = await getOncallUsers(escalationPolicyId, account);
|
|
751
837
|
const onCallUsersResponse = {
|
|
752
838
|
users: oncallUsers
|
|
753
839
|
};
|
|
@@ -765,10 +851,12 @@ async function createRouter(options) {
|
|
|
765
851
|
router.get("/services/:serviceId", async (request, response) => {
|
|
766
852
|
try {
|
|
767
853
|
const serviceId = request.params.serviceId || "";
|
|
854
|
+
logger.info(`request: ${JSON.stringify(request.query)}`);
|
|
855
|
+
const account = request.query.account || "";
|
|
768
856
|
if (serviceId === "") {
|
|
769
857
|
response.status(400).json("Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter");
|
|
770
858
|
}
|
|
771
|
-
const service = await getServiceById(serviceId);
|
|
859
|
+
const service = await getServiceById(serviceId, account);
|
|
772
860
|
const serviceResponse = {
|
|
773
861
|
service
|
|
774
862
|
};
|
|
@@ -786,8 +874,9 @@ async function createRouter(options) {
|
|
|
786
874
|
router.get("/services", async (request, response) => {
|
|
787
875
|
try {
|
|
788
876
|
const integrationKey = request.query.integration_key || "";
|
|
877
|
+
const account = request.query.account || "";
|
|
789
878
|
if (integrationKey !== "") {
|
|
790
|
-
const service = await getServiceByIntegrationKey(integrationKey);
|
|
879
|
+
const service = await getServiceByIntegrationKey(integrationKey, account);
|
|
791
880
|
const serviceResponse = {
|
|
792
881
|
service
|
|
793
882
|
};
|
|
@@ -812,7 +901,8 @@ async function createRouter(options) {
|
|
|
812
901
|
router.get("/services/:serviceId/change-events", async (request, response) => {
|
|
813
902
|
try {
|
|
814
903
|
const serviceId = request.params.serviceId || "";
|
|
815
|
-
const
|
|
904
|
+
const account = request.query.account || "";
|
|
905
|
+
const changeEvents = await getChangeEvents(serviceId, account);
|
|
816
906
|
const changeEventsResponse = {
|
|
817
907
|
change_events: changeEvents
|
|
818
908
|
};
|
|
@@ -830,7 +920,8 @@ async function createRouter(options) {
|
|
|
830
920
|
router.get("/services/:serviceId/incidents", async (request, response) => {
|
|
831
921
|
try {
|
|
832
922
|
const serviceId = request.params.serviceId || "";
|
|
833
|
-
const
|
|
923
|
+
const account = request.query.account || "";
|
|
924
|
+
const incidents = await getIncidents(serviceId, account);
|
|
834
925
|
const incidentsResponse = {
|
|
835
926
|
incidents
|
|
836
927
|
};
|
|
@@ -848,7 +939,8 @@ async function createRouter(options) {
|
|
|
848
939
|
router.get("/services/:serviceId/standards", async (request, response) => {
|
|
849
940
|
try {
|
|
850
941
|
const serviceId = request.params.serviceId || "";
|
|
851
|
-
const
|
|
942
|
+
const account = request.query.account || "";
|
|
943
|
+
const serviceStandards = await getServiceStandards(serviceId, account);
|
|
852
944
|
const serviceStandardsResponse = {
|
|
853
945
|
standards: serviceStandards
|
|
854
946
|
};
|
|
@@ -866,7 +958,8 @@ async function createRouter(options) {
|
|
|
866
958
|
router.get("/services/:serviceId/metrics", async (request, response) => {
|
|
867
959
|
try {
|
|
868
960
|
const serviceId = request.params.serviceId || "";
|
|
869
|
-
const
|
|
961
|
+
const account = request.query.account || "";
|
|
962
|
+
const metrics = await getServiceMetrics(serviceId, account);
|
|
870
963
|
const metricsResponse = {
|
|
871
964
|
metrics
|
|
872
965
|
};
|
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/db/PagerDutyBackendDatabase.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.getOptional('pagerDuty.accounts')) {\n logger.info(\"PagerDuty accounts configuration found. Loading accounts configuration...\");\n\n logger.info(`PagerDuty accounts configured: ${JSON.stringify(config.getOptional('pagerDuty.accounts'))}`);\n\n\n\n } else 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 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 getAllServices(): Promise<PagerDutyService[]> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies&include[]=teams&total=true`;\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 const allServices: PagerDutyService[] = [];\n let offset = 0;\n const limit = 50;\n let result: PagerDutyServicesAPIResponse;\n\n try {\n do {\n const paginatedUrl = `${baseUrl}?${params}&offset=${offset}&limit=${limit}`;\n response = await fetch(paginatedUrl, options);\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 result = await response.json() as PagerDutyServicesAPIResponse;\n \n allServices.push(...result.services);\n\n offset += limit;\n } while (offset < result.total!);\n } catch (error) {\n throw error;\n }\n\n return allServices;\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 { AuthService, DiscoveryService, LoggerService, RootConfigService } from '@backstage/backend-plugin-api';\nimport { createLegacyAuthAdapters, errorHandler } from '@backstage/backend-common';\nimport { getAllEscalationPolicies, getChangeEvents, getIncidents, getOncallUsers, getServiceById, getServiceByIntegrationKey, setAPIBaseUrl, getServiceStandards, getServiceMetrics, getAllServices } from '../apis/pagerduty';\nimport { HttpError, PagerDutyChangeEventsResponse, PagerDutyIncidentsResponse, PagerDutyOnCallUsersResponse, PagerDutyServiceResponse, PagerDutyServiceStandardsResponse, PagerDutyServiceMetricsResponse, PagerDutyServicesResponse, PagerDutyEntityMapping, PagerDutyEntityMappingsResponse, PagerDutyService } from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport { PagerDutyBackendStore, RawDbEntityResultRow } from '../db/PagerDutyBackendDatabase';\nimport * as express from 'express';\nimport Router from 'express-promise-router';\nimport type { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client';\n\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n store: PagerDutyBackendStore;\n discovery: DiscoveryService;\n auth?: AuthService;\n catalogApi?: CatalogApi;\n}\n\nexport type Annotations = {\n \"pagerduty.com/integration-key\": string;\n \"pagerduty.com/service-id\": string;\n}\n\nexport async function createComponentEntitiesReferenceDict({ items: componentEntities }: GetEntitiesResponse): Promise<Record<string, { ref: string, name: string }>> {\n const componentEntitiesDict: Record<string, { ref: string, name: string }> = {};\n\n await Promise.all(componentEntities.map(async (entity) => {\n const annotations: Annotations = JSON.parse(JSON.stringify(entity.metadata.annotations));\n const serviceId = annotations['pagerduty.com/service-id'];\n const integrationKey = annotations['pagerduty.com/integration-key'];\n\n if (serviceId !== undefined && serviceId !== \"\") {\n componentEntitiesDict[serviceId] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n }\n else if (integrationKey !== undefined && integrationKey !== \"\") {\n // get service id from integration key\n const service : PagerDutyService = await getServiceByIntegrationKey(integrationKey);\n\n if (service !== undefined) {\n componentEntitiesDict[service.id] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n }\n }\n }));\n\n return componentEntitiesDict;\n}\n\nexport async function buildEntityMappingsResponse(\n entityMappings: RawDbEntityResultRow[],\n componentEntitiesDict: Record<string, {\n ref: string;\n name: string;\n }>,\n componentEntities: GetEntitiesResponse,\n pagerDutyServices: PagerDutyService[]\n ) : Promise<PagerDutyEntityMappingsResponse> {\n\n const result: PagerDutyEntityMappingsResponse = {\n mappings: []\n };\n\n pagerDutyServices.forEach((service) => {\n // Check for service mapping annotation in any entity config file and get the entity ref\n const entityRef = componentEntitiesDict[service.id]?.ref;\n const entityName = componentEntitiesDict[service.id]?.name;\n\n // Check if the service is mapped to an entity in the database\n const entityMapping = entityMappings.find((mapping) => mapping.serviceId === service.id);\n\n if (entityMapping) {\n if (entityRef === undefined) {\n if (entityMapping.entityRef === \"\" || entityMapping.entityRef === undefined) {\n result.mappings.push({\n entityRef: \"\",\n entityName: \"\",\n integrationKey: entityMapping.integrationKey,\n serviceId: entityMapping.serviceId,\n status: \"NotMapped\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n else {\n const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? \"\";\n\n result.mappings.push({\n entityRef: entityMapping.entityRef,\n entityName: entityRefName,\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"OutOfSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n } else if (entityRef !== entityMapping.entityRef) {\n const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? \"\";\n\n result.mappings.push({\n entityRef: entityMapping.entityRef !== \"\" ? entityMapping.entityRef : \"\",\n entityName: entityMapping.entityRef !== \"\" ? entityRefName : \"\",\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"OutOfSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n } else if (entityRef === entityMapping.entityRef) {\n result.mappings.push({\n entityRef: entityMapping.entityRef !== \"\" ? entityMapping.entityRef : \"\",\n entityName: entityMapping.entityRef !== \"\" ? entityName : \"\",\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"InSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n } else {\n const backstageVendorId = 'PRO19CT';\n const backstageIntegrationKey = service.integrations?.find((integration) => integration.vendor?.id === backstageVendorId)?.integration_key ?? \"\";\n\n if (entityRef !== undefined) {\n result.mappings.push({\n entityRef: entityRef,\n entityName: entityName,\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: \"InSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n } else {\n result.mappings.push({\n entityRef: \"\",\n entityName: \"\",\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: \"NotMapped\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n }\n });\n\n const sortedResult = result.mappings.sort((a, b) => {\n if (a.serviceName! < b.serviceName!) { return -1; }\n else if (a.serviceName! > b.serviceName!) { return 1; }\n return 0;\n });\n\n result.mappings = sortedResult;\n\n return result;\n}\n\nexport async function createRouter(\n options: RouterOptions\n): Promise<express.Router> {\n const { logger, config, store, catalogApi } = options;\n let { auth } = options;\n\n if (!auth) {\n auth = createLegacyAuthAdapters(options).auth;\n }\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 // POST /mapping/entity\n router.post('/mapping/entity', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const entity: PagerDutyEntityMapping = request.body;\n\n if (!entity.serviceId) {\n response.status(400).json(\"Bad Request: 'service_id' is required\");\n }\n\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n const oldMapping = entityMappings.find((mapping) => mapping.serviceId === entity.serviceId);\n\n const entityMappingId = await store.insertEntityMapping(entity);\n\n // Refresh new and old entity unless they are empty strings\n if (entity.entityRef !== \"\") {\n // force refresh of new entity\n await catalogApi?.refreshEntity(entity.entityRef);\n }\n\n if (oldMapping && oldMapping.entityRef !== \"\") {\n // force refresh of old entity\n await catalogApi?.refreshEntity(oldMapping.entityRef);\n }\n\n response.json({\n id: entityMappingId,\n entityRef: entity.entityRef,\n integrationKey: entity.integrationKey,\n serviceId: entity.serviceId,\n status: entity.status,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(`Error occurred while processing request: ${error.message}`);\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /mapping/entity\n router.get('/mapping/entity', async (_, response) => {\n try {\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n\n // Get all the entities from the catalog\n const componentEntities = await catalogApi!.getEntities({\n filter: {\n kind: 'Component',\n }\n });\n\n // Build reference dictionary of componentEntities with serviceId as the key and entity reference and name pair as the value\n const componentEntitiesDict: Record<string, { ref: string, name: string }> = await createComponentEntitiesReferenceDict(componentEntities);\n\n // Get all services from PagerDuty\n const pagerDutyServices = await getAllServices();\n\n // Build the response object\n const result: PagerDutyEntityMappingsResponse = await buildEntityMappingsResponse(entityMappings, componentEntitiesDict, componentEntities, pagerDutyServices);\n\n response.json(result);\n } catch (error) {\n console.log(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/entity\n router.get('/mapping/entity/:type/:namespace/:name', async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const entityType: string = request.params.type || '';\n const entityNamespace: string = request.params.namespace || '';\n const entityName: string = request.params.name || '';\n\n\n if (entityType === ''\n || entityNamespace === ''\n || entityName === '') {\n response.status(400).json(\"Required params not specified.\");\n return;\n }\n\n const entityRef = `${entityType}:${entityNamespace}/${entityName}`.toLowerCase();\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByEntityRef(entityRef);\n\n if (!entityMapping) {\n response.status(404).json(`Mapping for entityRef ${entityRef} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping\n });\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 // 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 const service = await getServiceByIntegrationKey(integrationKey);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } else {\n const services = await getAllServices();\n const servicesResponse: PagerDutyServicesResponse = {\n services: services\n }\n\n response.json(servicesResponse);\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 { PagerDutyEntityMapping } from \"@pagerduty/backstage-plugin-common\";\nimport { resolvePackagePath } from \"@backstage/backend-plugin-api\";\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nexport type RawDbEntityResultRow = {\n id: string;\n entityRef: string;\n serviceId: string;\n integrationKey: string;\n processedDate?: Date;\n};\n\n/** @public */\nexport interface PagerDutyBackendStore {\n insertEntityMapping(entity: PagerDutyEntityMapping): Promise <string> \n getAllEntityMappings(): Promise<RawDbEntityResultRow[]>\n findEntityMappingByEntityRef(entityRef: string): Promise<RawDbEntityResultRow | undefined>\n}\n\ntype Options = {\n skipMigrations?: boolean;\n};\n\n/** @public */\nexport class PagerDutyBackendDatabase implements PagerDutyBackendStore {\n static async create(knex: Knex, options?: Options): Promise<PagerDutyBackendStore> {\n if(options?.skipMigrations) {\n const migrationsDir = resolvePackagePath(\"@pagerduty/backstage-plugin-backend\", \"migrations\");\n \n await knex.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new PagerDutyBackendDatabase(knex);\n }\n\n constructor(private readonly db: Knex) { }\n\n async insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string> {\n const entityMappingId = uuid();\n\n const [result] = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping')\n .insert({\n id: entityMappingId,\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n integrationKey: entity.integrationKey,\n processedDate: new Date(),\n })\n .onConflict('serviceId')\n .merge(['entityRef', 'integrationKey', 'processedDate'])\n .returning('id');\n\n return result.id;\n }\n\n async getAllEntityMappings(): Promise<RawDbEntityResultRow[]> {\n const rawEntities = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping');\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n\n async findEntityMappingByEntityRef(entityRef: string): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping')\n .where('entityRef', entityRef)\n .first();\n\n return rawEntity;\n }\n}","import { AuthService, LoggerService, coreServices, createBackendPlugin } from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\nimport { PagerDutyBackendDatabase, PagerDutyBackendStore } from './db';\nimport { CatalogClient } from '@backstage/catalog-client';\n\nclass CatalogFetchApi {\n constructor(\n private readonly logger: LoggerService,\n private readonly auth: AuthService,\n ) {}\n\n async fetch(input: any, init: RequestInit | undefined) : Promise<Response>{\n const request = new Request(input as any, init);\n const { token } = await this.auth.getPluginRequestToken({\n onBehalfOf: await this.auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n request.headers.set('Authorization', `Bearer ${token}`);\n this.logger.debug(`Added token to outgoing request to ${request.url}`);\n return fetch(request);\n }\n}\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 discovery: coreServices.discovery,\n auth: coreServices.auth,\n },\n async init({ config, logger, httpRouter, database, discovery, auth }) {\n\n const pagerDutyBackendStore : PagerDutyBackendStore = await PagerDutyBackendDatabase.create(\n await database.getClient(),\n { skipMigrations: true },\n );\n\n httpRouter.use(\n await createRouter({\n config,\n logger,\n store: pagerDutyBackendStore,\n discovery,\n auth,\n catalogApi: new CatalogClient({\n discoveryApi: discovery,\n fetchApi: new CatalogFetchApi(logger, auth),\n })\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/',\n allow: 'unauthenticated',\n });\n },\n });\n }\n});"],"names":["HttpError","fetch","DateTime","_a","createLegacyAuthAdapters","Router","express","errorHandler","resolvePackagePath","uuid","createBackendPlugin","coreServices","CatalogClient"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/auth/auth.ts","../src/apis/pagerduty.ts","../src/service/router.ts","../src/db/PagerDutyBackendDatabase.ts","../src/plugin.ts"],"sourcesContent":["import { LoggerService, RootConfigService } from \"@backstage/backend-plugin-api\";\nimport { HttpError, PagerDutyAccountConfig } from \"@pagerduty/backstage-plugin-common\";\n\ntype AccountTokenInfo = {\n authToken: string;\n authTokenExpiryDate: number;\n}\n\ntype Auth = {\n config: RootConfigService;\n logger: LoggerService;\n accountTokens: Record<string, AccountTokenInfo>;\n defaultAccount?: string;\n}\n\nlet authPersistence: Auth;\nlet isLegacyConfig = false;\n\nexport async function getAuthToken(accountId? : string): Promise<string> {\n\n // if authPersistence is not initialized, load the auth config\n if (!authPersistence || !authPersistence.accountTokens) {\n authPersistence.logger.info('AUTH - Auth config not loaded. Loading auth config...');\n await loadAuthConfig(authPersistence.config, authPersistence.logger);\n }\n\n if(isLegacyConfig){\n authPersistence.logger.info('AUTH - Using legacy configuration.');\n if (\n (authPersistence.accountTokens.default.authToken !== '' &&\n authPersistence.accountTokens.default.authToken.includes('Bearer') &&\n authPersistence.accountTokens.default.authTokenExpiryDate > Date.now()) // case where OAuth token is still valid\n ||\n (authPersistence.accountTokens.default.authToken !== '' &&\n authPersistence.accountTokens.default.authToken.includes('Token'))) { // case where API token is used\n \n authPersistence.logger.info('AUTH - Using default account token: ${authPersistence.accountTokens.default.authToken}');\n return authPersistence.accountTokens.default.authToken;\n }\n }\n else {\n // check if accountId is provided\n if (accountId && accountId !== '') {\n if (\n (authPersistence.accountTokens[accountId].authToken !== '' &&\n authPersistence.accountTokens[accountId].authToken.includes('Bearer') &&\n authPersistence.accountTokens[accountId].authTokenExpiryDate > Date.now()) // case where OAuth token is still valid\n ||\n (authPersistence.accountTokens[accountId].authToken !== '' &&\n authPersistence.accountTokens[accountId].authToken.includes('Token'))) { // case where API token is used\n\n authPersistence.logger.info(`AUTH - Using account ${accountId} token: ${authPersistence.accountTokens[accountId].authToken}`);\n return authPersistence.accountTokens[accountId].authToken;\n }\n }\n\n else { // return default account token if accountId is not provided\n const defaultFallback = authPersistence.defaultAccount ?? \"\";\n\n if (\n (authPersistence.accountTokens[defaultFallback].authToken !== '' &&\n authPersistence.accountTokens[defaultFallback].authToken.includes('Bearer') &&\n authPersistence.accountTokens[defaultFallback].authTokenExpiryDate > Date.now()) // case where OAuth token is still valid\n ||\n (authPersistence.accountTokens[defaultFallback].authToken !== '' &&\n authPersistence.accountTokens[defaultFallback].authToken.includes('Token'))) { // case where API token is used\n \n authPersistence.logger.info(`AUTH - Using fallback account ${defaultFallback} token: ${authPersistence.accountTokens[defaultFallback].authToken}`);\n\n return authPersistence.accountTokens[defaultFallback].authToken;\n }\n }\n }\n\n return '';\n}\n\nexport async function loadAuthConfig(config : RootConfigService, logger: LoggerService) {\n try {\n const defaultAccountId = 'default';\n\n // initiliaze the authPersistence in-memory object\n authPersistence = {\n config,\n logger,\n accountTokens: {}\n };\n\n // check if new accounts config is present\n if(!config.getOptional('pagerDuty.accounts')){\n isLegacyConfig = true;\n logger.warn('No PagerDuty accounts configuration found in config file. Reverting to legacy configuration.');\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 const tokenInfo : AccountTokenInfo = 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(`tokenInfo: ${JSON.stringify(tokenInfo)}`);\n\n logger.info(`authPersistence.accountTokens: ${JSON.stringify(authPersistence.accountTokens)}`);\n\n logger.info(`tokenInfo: ${JSON.stringify(tokenInfo)}`);\n\n authPersistence.accountTokens[defaultAccountId] = tokenInfo;\n\n logger.info('PagerDuty OAuth configuration loaded successfully.');\n }\n } else {\n authPersistence.accountTokens[defaultAccountId] = {\n authToken: `Token token=${config.getString('pagerDuty.apiToken')}`,\n authTokenExpiryDate: Date.now() + 3600000 * 24 * 365 * 2 // 2 years\n };\n\n logger.info('PagerDuty API token loaded successfully.');\n }\n } \n else { // new accounts config is present\n logger.info('New PagerDuty accounts configuration found in config file.');\n isLegacyConfig = false;\n const accounts = config.getOptional<PagerDutyAccountConfig[]>('pagerDuty.accounts');\n\n\n if(accounts && accounts?.length === 1){\n logger.info('Only one account found in config file. Setting it as default.');\n authPersistence.defaultAccount = accounts[0].id;\n }\n\n accounts?.forEach(async account => {\n const maskedAccountId = maskString(account.id);\n\n if(account.isDefault && !authPersistence.defaultAccount){\n logger.info(`Default account found in config file. Setting it as default.`);\n authPersistence.defaultAccount = account.id;\n }\n\n if (!account.apiToken) {\n logger.warn('No PagerDuty API token found in config file. Trying OAuth token instead...');\n\n if (!account.oauth) {\n logger.error('No PagerDuty OAuth configuration found in config file.');\n } else if (!account.oauth.clientId || !account.oauth.clientSecret || !account.oauth.subDomain) {\n logger.error(\"Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.\");\n } else {\n const tokenInfo : AccountTokenInfo = await getOAuthToken(\n account.oauth.clientId,\n account.oauth.clientSecret,\n account.oauth.subDomain,\n account.oauth.region ?? 'us');\n\n authPersistence.accountTokens[account.id] = tokenInfo;\n\n logger.info(`tokenInfo: ${JSON.stringify(tokenInfo)}`);\n\n logger.info(`PagerDuty OAuth configuration loaded successfully for account ${maskedAccountId}.`);\n }\n } else {\n authPersistence.accountTokens[account.id] = {\n authToken: `Token token=${account.apiToken}`,\n authTokenExpiryDate: Date.now() + 3600000 * 24 * 365 * 2 // 2 years\n };\n\n logger.info(`PagerDuty API token loaded successfully for account ${maskedAccountId}.`);\n }\n });\n\n if(!authPersistence.defaultAccount){\n logger.error('No default account found in config file. One account must be marked as default.');\n }\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<AccountTokenInfo> {\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\n const result : AccountTokenInfo = {\n authToken: `Bearer ${authResponse.access_token}`,\n authTokenExpiryDate: Date.now() + (authResponse.expires_in * 1000)\n };\n\n return result;\n}\n\nfunction maskString(str: string) : string {\n return str[0] + '*'.repeat(str.length - 2) + str.slice(-1);\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, account?: string): 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(account),\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(account?: string): 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(account),\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, account?: 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(account),\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, account?: string): Promise<PagerDutyService> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;\n const token = await getAuthToken(account);\n\n console.log(`Token being used for request: ${token}`);\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: token,\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, account?: 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(account),\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 getAllServices(): Promise<PagerDutyService[]> {\n let response: Response;\n const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies&include[]=teams&total=true`;\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 const allServices: PagerDutyService[] = [];\n let offset = 0;\n const limit = 50;\n let result: PagerDutyServicesAPIResponse;\n\n try {\n do {\n const paginatedUrl = `${baseUrl}?${params}&offset=${offset}&limit=${limit}`;\n response = await fetch(paginatedUrl, options);\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 result = await response.json() as PagerDutyServicesAPIResponse;\n \n allServices.push(...result.services);\n\n offset += limit;\n } while (offset < result.total!);\n } catch (error) {\n throw error;\n }\n\n return allServices;\n}\n\nexport async function getChangeEvents(serviceId: string, account?: 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(account),\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, account?: 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(account),\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, account?: string): Promise<PagerDutyServiceStandards> {\n let response: Response;\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n Authorization: await getAuthToken(account),\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, account?: 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(account),\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 { AuthService, DiscoveryService, LoggerService, RootConfigService } from '@backstage/backend-plugin-api';\nimport { createLegacyAuthAdapters, errorHandler } from '@backstage/backend-common';\nimport { getAllEscalationPolicies, getChangeEvents, getIncidents, getOncallUsers, getServiceById, getServiceByIntegrationKey, setAPIBaseUrl, getServiceStandards, getServiceMetrics, getAllServices } from '../apis/pagerduty';\nimport { HttpError, PagerDutyChangeEventsResponse, PagerDutyIncidentsResponse, PagerDutyOnCallUsersResponse, PagerDutyServiceResponse, PagerDutyServiceStandardsResponse, PagerDutyServiceMetricsResponse, PagerDutyServicesResponse, PagerDutyEntityMapping, PagerDutyEntityMappingsResponse, PagerDutyService } from '@pagerduty/backstage-plugin-common';\nimport { loadAuthConfig } from '../auth/auth';\nimport { PagerDutyBackendStore, RawDbEntityResultRow } from '../db/PagerDutyBackendDatabase';\nimport * as express from 'express';\nimport Router from 'express-promise-router';\nimport type { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client';\n\n\nexport interface RouterOptions {\n logger: LoggerService;\n config: RootConfigService;\n store: PagerDutyBackendStore;\n discovery: DiscoveryService;\n auth?: AuthService;\n catalogApi?: CatalogApi;\n}\n\nexport type Annotations = {\n \"pagerduty.com/integration-key\": string;\n \"pagerduty.com/service-id\": string;\n \"pagerduty.com/account\": string;\n}\n\nexport async function createComponentEntitiesReferenceDict({ items: componentEntities }: GetEntitiesResponse): Promise<Record<string, { ref: string, name: string }>> {\n const componentEntitiesDict: Record<string, { ref: string, name: string }> = {};\n\n await Promise.all(componentEntities.map(async (entity) => {\n const annotations: Annotations = JSON.parse(JSON.stringify(entity.metadata.annotations));\n const serviceId = annotations['pagerduty.com/service-id'];\n const integrationKey = annotations['pagerduty.com/integration-key'];\n const account = annotations['pagerduty.com/account'] ?? \"\";\n\n if (serviceId !== undefined && serviceId !== \"\") {\n componentEntitiesDict[serviceId] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n }\n else if (integrationKey !== undefined && integrationKey !== \"\") {\n // get service id from integration key\n const service : PagerDutyService = await getServiceByIntegrationKey(integrationKey, account);\n\n if (service !== undefined) {\n componentEntitiesDict[service.id] = {\n ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),\n name: entity.metadata.name,\n };\n }\n }\n }));\n\n return componentEntitiesDict;\n}\n\nexport async function buildEntityMappingsResponse(\n entityMappings: RawDbEntityResultRow[],\n componentEntitiesDict: Record<string, {\n ref: string;\n name: string;\n }>,\n componentEntities: GetEntitiesResponse,\n pagerDutyServices: PagerDutyService[]\n ) : Promise<PagerDutyEntityMappingsResponse> {\n\n const result: PagerDutyEntityMappingsResponse = {\n mappings: []\n };\n\n pagerDutyServices.forEach((service) => {\n // Check for service mapping annotation in any entity config file and get the entity ref\n const entityRef = componentEntitiesDict[service.id]?.ref;\n const entityName = componentEntitiesDict[service.id]?.name;\n\n // Check if the service is mapped to an entity in the database\n const entityMapping = entityMappings.find((mapping) => mapping.serviceId === service.id);\n\n if (entityMapping) {\n if (entityRef === undefined) {\n if (entityMapping.entityRef === \"\" || entityMapping.entityRef === undefined) {\n result.mappings.push({\n entityRef: \"\",\n entityName: \"\",\n integrationKey: entityMapping.integrationKey,\n serviceId: entityMapping.serviceId,\n status: \"NotMapped\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n else {\n const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? \"\";\n\n result.mappings.push({\n entityRef: entityMapping.entityRef,\n entityName: entityRefName,\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"OutOfSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n } else if (entityRef !== entityMapping.entityRef) {\n const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? \"\";\n\n result.mappings.push({\n entityRef: entityMapping.entityRef !== \"\" ? entityMapping.entityRef : \"\",\n entityName: entityMapping.entityRef !== \"\" ? entityRefName : \"\",\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"OutOfSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n } else if (entityRef === entityMapping.entityRef) {\n result.mappings.push({\n entityRef: entityMapping.entityRef !== \"\" ? entityMapping.entityRef : \"\",\n entityName: entityMapping.entityRef !== \"\" ? entityName : \"\",\n serviceId: entityMapping.serviceId,\n integrationKey: entityMapping.integrationKey,\n status: \"InSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n } else {\n const backstageVendorId = 'PRO19CT';\n const backstageIntegrationKey = service.integrations?.find((integration) => integration.vendor?.id === backstageVendorId)?.integration_key ?? \"\";\n\n if (entityRef !== undefined) {\n result.mappings.push({\n entityRef: entityRef,\n entityName: entityName,\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: \"InSync\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n } else {\n result.mappings.push({\n entityRef: \"\",\n entityName: \"\",\n serviceId: service.id,\n integrationKey: backstageIntegrationKey,\n status: \"NotMapped\",\n serviceName: service.name,\n team: service.teams?.[0]?.name ?? \"\",\n escalationPolicy: service.escalation_policy !== undefined ? service.escalation_policy.name : \"\",\n serviceUrl: service.html_url,\n });\n }\n }\n });\n\n const sortedResult = result.mappings.sort((a, b) => {\n if (a.serviceName! < b.serviceName!) { return -1; }\n else if (a.serviceName! > b.serviceName!) { return 1; }\n return 0;\n });\n\n result.mappings = sortedResult;\n\n return result;\n}\n\nexport async function createRouter(\n options: RouterOptions\n): Promise<express.Router> {\n const { logger, config, store, catalogApi } = options;\n let { auth } = options;\n\n if (!auth) {\n auth = createLegacyAuthAdapters(options).auth;\n }\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 // POST /mapping/entity\n router.post('/mapping/entity', async (request, response) => {\n try {\n // Get the serviceId from the request parameters\n const entity: PagerDutyEntityMapping = request.body;\n\n if (!entity.serviceId) {\n response.status(400).json(\"Bad Request: 'service_id' is required\");\n }\n\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n const oldMapping = entityMappings.find((mapping) => mapping.serviceId === entity.serviceId);\n\n const entityMappingId = await store.insertEntityMapping(entity);\n\n // Refresh new and old entity unless they are empty strings\n if (entity.entityRef !== \"\") {\n // force refresh of new entity\n await catalogApi?.refreshEntity(entity.entityRef);\n }\n\n if (oldMapping && oldMapping.entityRef !== \"\") {\n // force refresh of old entity\n await catalogApi?.refreshEntity(oldMapping.entityRef);\n }\n\n response.json({\n id: entityMappingId,\n entityRef: entity.entityRef,\n integrationKey: entity.integrationKey,\n serviceId: entity.serviceId,\n status: entity.status,\n });\n } catch (error) {\n if (error instanceof HttpError) {\n logger.error(`Error occurred while processing request: ${error.message}`);\n response.status(error.status).json({\n errors: [\n `${error.message}`\n ]\n });\n }\n }\n });\n\n // GET /mapping/entity\n router.get('/mapping/entity', async (_, response) => {\n try {\n // Get all the entity mappings from the database\n const entityMappings = await store.getAllEntityMappings();\n\n // Get all the entities from the catalog\n const componentEntities = await catalogApi!.getEntities({\n filter: {\n kind: 'Component',\n }\n });\n\n // Build reference dictionary of componentEntities with serviceId as the key and entity reference and name pair as the value\n const componentEntitiesDict: Record<string, { ref: string, name: string }> = await createComponentEntitiesReferenceDict(componentEntities);\n\n // Get all services from PagerDuty\n const pagerDutyServices = await getAllServices();\n\n // Build the response object\n const result: PagerDutyEntityMappingsResponse = await buildEntityMappingsResponse(entityMappings, componentEntitiesDict, componentEntities, pagerDutyServices);\n\n response.json(result);\n } catch (error) {\n console.log(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/entity\n router.get('/mapping/entity/:type/:namespace/:name', async (request, response) => {\n try {\n // Get the type, namespace and entity name from the request parameters\n const entityType: string = request.params.type || '';\n const entityNamespace: string = request.params.namespace || '';\n const entityName: string = request.params.name || '';\n\n\n if (entityType === ''\n || entityNamespace === ''\n || entityName === '') {\n response.status(400).json(\"Required params not specified.\");\n return;\n }\n\n const entityRef = `${entityType}:${entityNamespace}/${entityName}`.toLowerCase();\n\n // Get all the entity mappings from the database\n const entityMapping = await store.findEntityMappingByEntityRef(entityRef);\n\n if (!entityMapping) {\n response.status(404).json(`Mapping for entityRef ${entityRef} not found.`);\n return;\n }\n\n response.json({\n mapping: entityMapping\n });\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 // 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 const account = request.query.account 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, account);\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 logger.info(`request: ${JSON.stringify(request.query)}`);\n const account = request.query.account as string || '';\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, account);\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 const account = request.query.account as string || '';\n\n if (integrationKey !== '') {\n const service = await getServiceByIntegrationKey(integrationKey, account);\n const serviceResponse: PagerDutyServiceResponse = {\n service: service\n }\n\n response.json(serviceResponse);\n } else {\n const services = await getAllServices();\n const servicesResponse: PagerDutyServicesResponse = {\n services: services\n }\n\n response.json(servicesResponse);\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 const account = request.query.account as string || '';\n\n const changeEvents = await getChangeEvents(serviceId, account);\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 const account = request.query.account as string || '';\n\n const incidents = await getIncidents(serviceId, account);\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 const account = request.query.account as string || '';\n\n const serviceStandards = await getServiceStandards(serviceId, account);\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 const account = request.query.account as string || '';\n\n const metrics = await getServiceMetrics(serviceId, account);\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 { PagerDutyEntityMapping } from \"@pagerduty/backstage-plugin-common\";\nimport { resolvePackagePath } from \"@backstage/backend-plugin-api\";\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\n\nexport type RawDbEntityResultRow = {\n id: string;\n entityRef: string;\n serviceId: string;\n integrationKey: string;\n processedDate?: Date;\n};\n\n/** @public */\nexport interface PagerDutyBackendStore {\n insertEntityMapping(entity: PagerDutyEntityMapping): Promise <string> \n getAllEntityMappings(): Promise<RawDbEntityResultRow[]>\n findEntityMappingByEntityRef(entityRef: string): Promise<RawDbEntityResultRow | undefined>\n}\n\ntype Options = {\n skipMigrations?: boolean;\n};\n\n/** @public */\nexport class PagerDutyBackendDatabase implements PagerDutyBackendStore {\n static async create(knex: Knex, options?: Options): Promise<PagerDutyBackendStore> {\n if(options?.skipMigrations) {\n const migrationsDir = resolvePackagePath(\"@pagerduty/backstage-plugin-backend\", \"migrations\");\n \n await knex.migrate.latest({\n directory: migrationsDir,\n });\n }\n\n return new PagerDutyBackendDatabase(knex);\n }\n\n constructor(private readonly db: Knex) { }\n\n async insertEntityMapping(entity: PagerDutyEntityMapping): Promise<string> {\n const entityMappingId = uuid();\n\n const [result] = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping')\n .insert({\n id: entityMappingId,\n entityRef: entity.entityRef,\n serviceId: entity.serviceId,\n integrationKey: entity.integrationKey,\n processedDate: new Date(),\n })\n .onConflict('serviceId')\n .merge(['entityRef', 'integrationKey', 'processedDate'])\n .returning('id');\n\n return result.id;\n }\n\n async getAllEntityMappings(): Promise<RawDbEntityResultRow[]> {\n const rawEntities = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping');\n\n if (!rawEntities) {\n return [];\n }\n\n return rawEntities;\n }\n\n async findEntityMappingByEntityRef(entityRef: string): Promise<RawDbEntityResultRow | undefined> {\n const rawEntity = await this.db<RawDbEntityResultRow>('pagerduty_entity_mapping')\n .where('entityRef', entityRef)\n .first();\n\n return rawEntity;\n }\n}","import { AuthService, LoggerService, coreServices, createBackendPlugin } from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\nimport { PagerDutyBackendDatabase, PagerDutyBackendStore } from './db';\nimport { CatalogClient } from '@backstage/catalog-client';\n\nclass CatalogFetchApi {\n constructor(\n private readonly logger: LoggerService,\n private readonly auth: AuthService,\n ) {}\n\n async fetch(input: any, init: RequestInit | undefined) : Promise<Response>{\n const request = new Request(input as any, init);\n const { token } = await this.auth.getPluginRequestToken({\n onBehalfOf: await this.auth.getOwnServiceCredentials(),\n targetPluginId: 'catalog',\n });\n\n request.headers.set('Authorization', `Bearer ${token}`);\n this.logger.debug(`Added token to outgoing request to ${request.url}`);\n return fetch(request);\n }\n}\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 discovery: coreServices.discovery,\n auth: coreServices.auth,\n },\n async init({ config, logger, httpRouter, database, discovery, auth }) {\n\n const pagerDutyBackendStore : PagerDutyBackendStore = await PagerDutyBackendDatabase.create(\n await database.getClient(),\n { skipMigrations: true },\n );\n\n httpRouter.use(\n await createRouter({\n config,\n logger,\n store: pagerDutyBackendStore,\n discovery,\n auth,\n catalogApi: new CatalogClient({\n discoveryApi: discovery,\n fetchApi: new CatalogFetchApi(logger, auth),\n })\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/',\n allow: 'unauthenticated',\n });\n },\n });\n }\n});"],"names":["_a","HttpError","fetch","DateTime","createLegacyAuthAdapters","Router","express","errorHandler","resolvePackagePath","uuid","createBackendPlugin","coreServices","CatalogClient"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ interface RouterOptions {
|
|
|
29
29
|
type Annotations = {
|
|
30
30
|
"pagerduty.com/integration-key": string;
|
|
31
31
|
"pagerduty.com/service-id": string;
|
|
32
|
+
"pagerduty.com/account": string;
|
|
32
33
|
};
|
|
33
34
|
declare function createComponentEntitiesReferenceDict({ items: componentEntities }: GetEntitiesResponse): Promise<Record<string, {
|
|
34
35
|
ref: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagerduty/backstage-plugin-backend",
|
|
3
|
-
"version": "0.8.0-next.
|
|
3
|
+
"version": "0.8.0-next.21",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@backstage/plugin-catalog-node": "^1.12.0",
|
|
40
40
|
"@backstage/plugin-scaffolder-node": "^0.4.4",
|
|
41
41
|
"@material-ui/core": "^4.12.4",
|
|
42
|
-
"@pagerduty/backstage-plugin-common": "0.1.
|
|
42
|
+
"@pagerduty/backstage-plugin-common": "0.1.5",
|
|
43
43
|
"@rjsf/core": "^5.14.3",
|
|
44
44
|
"@types/express": "^4.17.6",
|
|
45
45
|
"express": "^4.19.2",
|