@pagerduty/backstage-plugin-backend 0.10.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/apis/pagerduty.cjs.js +327 -64
- package/dist/apis/pagerduty.cjs.js.map +1 -1
- package/dist/auth/auth.cjs.js +5 -4
- package/dist/auth/auth.cjs.js.map +1 -1
- package/dist/controllers/mappings-controller.cjs.js +388 -0
- package/dist/controllers/mappings-controller.cjs.js.map +1 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js +16 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js.map +1 -1
- package/dist/index.cjs.js +0 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/service/router.cjs.js +280 -42
- package/dist/service/router.cjs.js.map +1 -1
- package/dist/services/dataLoader.cjs.js +73 -0
- package/dist/services/dataLoader.cjs.js.map +1 -0
- package/dist/services/matchingEngine.cjs.js +99 -0
- package/dist/services/matchingEngine.cjs.js.map +1 -0
- package/dist/services/pagerduty/index.cjs.js +11 -0
- package/dist/services/pagerduty/index.cjs.js.map +1 -0
- package/dist/utils/catalog-entity.cjs.js +50 -0
- package/dist/utils/catalog-entity.cjs.js.map +1 -0
- package/dist/utils/normalization.cjs.js +67 -0
- package/dist/utils/normalization.cjs.js.map +1 -0
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @pagerduty/backstage-plugin-backend
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ae2a9c3: Refactor the service mappings screen and add an auto-matching functionality to mass map PagerDuty service to Backstage entities
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [ae2a9c3]
|
|
12
|
+
- @pagerduty/backstage-plugin-common@0.3.0
|
|
13
|
+
|
|
14
|
+
## 0.11.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- dae278a: Add auto-matching algorithm for mapping PagerDuty services to Backstage components
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- 821f4e2: Include x-pagerduty-client header in PagerDuty API requests
|
|
23
|
+
- 47afbbc: Make changesets mandatory for all the packages
|
|
24
|
+
- Updated dependencies [47afbbc]
|
|
25
|
+
- @pagerduty/backstage-plugin-common@0.2.6
|
|
26
|
+
|
|
3
27
|
## 0.10.3
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -12,25 +12,33 @@ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
|
|
|
12
12
|
const EndpointConfig = {};
|
|
13
13
|
let fallbackEndpointConfig;
|
|
14
14
|
let isLegacyConfig = false;
|
|
15
|
-
|
|
15
|
+
const SubdomainConfig = {};
|
|
16
|
+
let fallbackSubdomain;
|
|
17
|
+
function setFallbackAccountConfig(account) {
|
|
16
18
|
fallbackEndpointConfig = {
|
|
17
19
|
eventsBaseUrl: account.eventsBaseUrl ?? "https://events.pagerduty.com/v2",
|
|
18
20
|
apiBaseUrl: account.apiBaseUrl ?? "https://api.pagerduty.com"
|
|
19
21
|
};
|
|
22
|
+
if (account.oauth?.subDomain) {
|
|
23
|
+
fallbackSubdomain = account.oauth.subDomain;
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
|
-
function
|
|
26
|
+
function insertAccountConfig(account) {
|
|
22
27
|
EndpointConfig[account.id] = {
|
|
23
28
|
eventsBaseUrl: account.eventsBaseUrl ?? "https://events.pagerduty.com/v2",
|
|
24
29
|
apiBaseUrl: account.apiBaseUrl ?? "https://api.pagerduty.com"
|
|
25
30
|
};
|
|
31
|
+
if (account.oauth?.subDomain) {
|
|
32
|
+
SubdomainConfig[account.id] = account.oauth.subDomain;
|
|
33
|
+
}
|
|
26
34
|
}
|
|
27
35
|
function loadPagerDutyEndpointsFromConfig(config, logger) {
|
|
28
|
-
|
|
36
|
+
const accounts = config.getOptional("pagerDuty.accounts");
|
|
37
|
+
if (accounts) {
|
|
29
38
|
logger.debug(
|
|
30
39
|
`New accounts configuration detected. Loading PagerDuty endpoints from config.`
|
|
31
40
|
);
|
|
32
41
|
isLegacyConfig = false;
|
|
33
|
-
const accounts = config.getOptional("pagerDuty.accounts");
|
|
34
42
|
if (accounts?.length === 1) {
|
|
35
43
|
logger.debug(
|
|
36
44
|
`Single account configuration detected. Loading PagerDuty endpoints from config to 'default'.`
|
|
@@ -39,15 +47,18 @@ function loadPagerDutyEndpointsFromConfig(config, logger) {
|
|
|
39
47
|
eventsBaseUrl: accounts[0].eventsBaseUrl !== void 0 ? accounts[0].eventsBaseUrl : "https://events.pagerduty.com/v2",
|
|
40
48
|
apiBaseUrl: accounts[0].apiBaseUrl !== void 0 ? accounts[0].apiBaseUrl : "https://api.pagerduty.com"
|
|
41
49
|
};
|
|
50
|
+
if (accounts[0].oauth?.subDomain) {
|
|
51
|
+
SubdomainConfig.default = accounts[0].oauth.subDomain;
|
|
52
|
+
}
|
|
42
53
|
} else {
|
|
43
54
|
logger.debug(
|
|
44
55
|
`Multiple account configuration detected. Loading PagerDuty endpoints from config.`
|
|
45
56
|
);
|
|
46
57
|
accounts?.forEach((account) => {
|
|
47
58
|
if (account.isDefault) {
|
|
48
|
-
|
|
59
|
+
setFallbackAccountConfig(account);
|
|
49
60
|
}
|
|
50
|
-
|
|
61
|
+
insertAccountConfig(account);
|
|
51
62
|
});
|
|
52
63
|
}
|
|
53
64
|
} else {
|
|
@@ -57,6 +68,10 @@ function loadPagerDutyEndpointsFromConfig(config, logger) {
|
|
|
57
68
|
eventsBaseUrl: config.getOptionalString("pagerDuty.eventsBaseUrl") !== void 0 ? config.getString("pagerDuty.eventsBaseUrl") : "https://events.pagerduty.com/v2",
|
|
58
69
|
apiBaseUrl: config.getOptionalString("pagerDuty.apiBaseUrl") !== void 0 ? config.getString("pagerDuty.apiBaseUrl") : "https://api.pagerduty.com"
|
|
59
70
|
};
|
|
71
|
+
const legacySubdomain = config.getOptionalString("pagerDuty.oauth.subDomain");
|
|
72
|
+
if (legacySubdomain) {
|
|
73
|
+
SubdomainConfig.default = legacySubdomain;
|
|
74
|
+
}
|
|
60
75
|
}
|
|
61
76
|
}
|
|
62
77
|
function getApiBaseUrl(account) {
|
|
@@ -68,15 +83,30 @@ function getApiBaseUrl(account) {
|
|
|
68
83
|
}
|
|
69
84
|
return fallbackEndpointConfig.apiBaseUrl;
|
|
70
85
|
}
|
|
86
|
+
function getSubdomain(account) {
|
|
87
|
+
if (isLegacyConfig === true) {
|
|
88
|
+
return SubdomainConfig.default;
|
|
89
|
+
}
|
|
90
|
+
if (account && account !== "default") {
|
|
91
|
+
return SubdomainConfig[account] ?? fallbackSubdomain ?? SubdomainConfig.default;
|
|
92
|
+
}
|
|
93
|
+
return fallbackSubdomain ?? SubdomainConfig.default;
|
|
94
|
+
}
|
|
95
|
+
async function getDefaultHeaders(account) {
|
|
96
|
+
const subdomain = getSubdomain(account);
|
|
97
|
+
const clientHeader = `"Backstage" <https://${subdomain}.backstage.com>`;
|
|
98
|
+
return {
|
|
99
|
+
Authorization: await auth.getAuthToken(account),
|
|
100
|
+
Accept: "application/vnd.pagerduty+json;version=2",
|
|
101
|
+
"Content-Type": "application/json",
|
|
102
|
+
"X-PagerDuty-Client": clientHeader
|
|
103
|
+
};
|
|
104
|
+
}
|
|
71
105
|
async function addServiceRelationsToService(serviceRelations, account) {
|
|
72
106
|
let response;
|
|
73
107
|
const options = {
|
|
74
108
|
method: "POST",
|
|
75
|
-
headers:
|
|
76
|
-
Authorization: await auth.getAuthToken(account),
|
|
77
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
78
|
-
"Content-Type": "application/json"
|
|
79
|
-
},
|
|
109
|
+
headers: await getDefaultHeaders(account),
|
|
80
110
|
body: JSON.stringify({
|
|
81
111
|
relationships: serviceRelations
|
|
82
112
|
})
|
|
@@ -131,11 +161,7 @@ async function removeServiceRelationsFromService(serviceRelations, account) {
|
|
|
131
161
|
let response;
|
|
132
162
|
const options = {
|
|
133
163
|
method: "POST",
|
|
134
|
-
headers:
|
|
135
|
-
Authorization: await auth.getAuthToken(account),
|
|
136
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
137
|
-
"Content-Type": "application/json"
|
|
138
|
-
},
|
|
164
|
+
headers: await getDefaultHeaders(account),
|
|
139
165
|
body: JSON.stringify({
|
|
140
166
|
relationships: serviceRelations
|
|
141
167
|
})
|
|
@@ -190,11 +216,7 @@ async function getServiceRelationshipsById(serviceId, account) {
|
|
|
190
216
|
let response;
|
|
191
217
|
const options = {
|
|
192
218
|
method: "GET",
|
|
193
|
-
headers:
|
|
194
|
-
Authorization: await auth.getAuthToken(account),
|
|
195
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
196
|
-
"Content-Type": "application/json"
|
|
197
|
-
}
|
|
219
|
+
headers: await getDefaultHeaders(account)
|
|
198
220
|
};
|
|
199
221
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
200
222
|
const baseUrl = `${apiBaseUrl}/service_dependencies/technical_services/${serviceId}`;
|
|
@@ -247,11 +269,7 @@ async function getEscalationPolicies(offset, limit, account) {
|
|
|
247
269
|
const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;
|
|
248
270
|
const options = {
|
|
249
271
|
method: "GET",
|
|
250
|
-
headers:
|
|
251
|
-
Authorization: await auth.getAuthToken(account),
|
|
252
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
253
|
-
"Content-Type": "application/json"
|
|
254
|
-
}
|
|
272
|
+
headers: await getDefaultHeaders(account)
|
|
255
273
|
};
|
|
256
274
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
257
275
|
const baseUrl = `${apiBaseUrl}/escalation_policies`;
|
|
@@ -332,9 +350,9 @@ async function getAllEscalationPolicies() {
|
|
|
332
350
|
);
|
|
333
351
|
return results;
|
|
334
352
|
}
|
|
335
|
-
async function
|
|
353
|
+
async function getTeams(offset, limit, account) {
|
|
336
354
|
let response;
|
|
337
|
-
const params = `
|
|
355
|
+
const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;
|
|
338
356
|
const options = {
|
|
339
357
|
method: "GET",
|
|
340
358
|
headers: {
|
|
@@ -344,6 +362,88 @@ async function getOncallUsers(escalationPolicy, account) {
|
|
|
344
362
|
}
|
|
345
363
|
};
|
|
346
364
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
365
|
+
const baseUrl = `${apiBaseUrl}/teams`;
|
|
366
|
+
try {
|
|
367
|
+
response = await fetchWithRetries(`${baseUrl}?${params}`, options);
|
|
368
|
+
} catch (error) {
|
|
369
|
+
throw new Error(`Failed to retrieve teams: ${error}`);
|
|
370
|
+
}
|
|
371
|
+
if (response.status >= 500) {
|
|
372
|
+
throw new backstagePluginCommon.HttpError(
|
|
373
|
+
`Failed to list teams. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,
|
|
374
|
+
response.status
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
switch (response.status) {
|
|
378
|
+
case 400:
|
|
379
|
+
throw new backstagePluginCommon.HttpError(
|
|
380
|
+
"Failed to list teams. Caller provided invalid arguments.",
|
|
381
|
+
400
|
|
382
|
+
);
|
|
383
|
+
case 401:
|
|
384
|
+
throw new backstagePluginCommon.HttpError(
|
|
385
|
+
"Failed to list teams. Caller did not supply credentials or did not provide the correct credentials.",
|
|
386
|
+
401
|
|
387
|
+
);
|
|
388
|
+
case 403:
|
|
389
|
+
throw new backstagePluginCommon.HttpError(
|
|
390
|
+
"Failed to list teams. Caller is not authorized to view the requested resource.",
|
|
391
|
+
403
|
|
392
|
+
);
|
|
393
|
+
case 429:
|
|
394
|
+
throw new backstagePluginCommon.HttpError("Failed to list teams. Rate limit exceeded.", 429);
|
|
395
|
+
}
|
|
396
|
+
let result;
|
|
397
|
+
try {
|
|
398
|
+
result = await response.json();
|
|
399
|
+
return [result.more ?? false, result.teams];
|
|
400
|
+
} catch (error) {
|
|
401
|
+
throw new backstagePluginCommon.HttpError(`Failed to parse team information: ${error}`, 500);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async function getAllTeams(account) {
|
|
405
|
+
const limit = 50;
|
|
406
|
+
let offset = 0;
|
|
407
|
+
let moreResults = false;
|
|
408
|
+
let results = [];
|
|
409
|
+
const accountsToFetch = account ? [account] : Object.keys(EndpointConfig);
|
|
410
|
+
await Promise.all(
|
|
411
|
+
accountsToFetch.map(async (acc) => {
|
|
412
|
+
try {
|
|
413
|
+
offset = 0;
|
|
414
|
+
do {
|
|
415
|
+
const res = await getTeams(offset, limit, acc);
|
|
416
|
+
res[1].forEach((team) => {
|
|
417
|
+
team.account = acc;
|
|
418
|
+
});
|
|
419
|
+
results = results.concat(res[1]);
|
|
420
|
+
if (res[0] === true) {
|
|
421
|
+
moreResults = true;
|
|
422
|
+
offset += limit;
|
|
423
|
+
} else {
|
|
424
|
+
moreResults = false;
|
|
425
|
+
}
|
|
426
|
+
} while (moreResults === true);
|
|
427
|
+
} catch (error) {
|
|
428
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
429
|
+
throw error;
|
|
430
|
+
} else {
|
|
431
|
+
throw new backstagePluginCommon.HttpError(`${error}`, 500);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
})
|
|
435
|
+
);
|
|
436
|
+
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
437
|
+
return results;
|
|
438
|
+
}
|
|
439
|
+
async function getOncallUsers(escalationPolicy, account) {
|
|
440
|
+
let response;
|
|
441
|
+
const params = `time_zone=UTC&include[]=users&escalation_policy_ids[]=${escalationPolicy}`;
|
|
442
|
+
const options = {
|
|
443
|
+
method: "GET",
|
|
444
|
+
headers: await getDefaultHeaders(account)
|
|
445
|
+
};
|
|
446
|
+
const apiBaseUrl = getApiBaseUrl(account);
|
|
347
447
|
const baseUrl = `${apiBaseUrl}/oncalls`;
|
|
348
448
|
try {
|
|
349
449
|
response = await fetchWithRetries(`${baseUrl}?${params}`, options);
|
|
@@ -405,14 +505,9 @@ async function getOncallUsers(escalationPolicy, account) {
|
|
|
405
505
|
async function getServiceById(serviceId, account) {
|
|
406
506
|
let response;
|
|
407
507
|
const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
408
|
-
const token = await auth.getAuthToken(account);
|
|
409
508
|
const options = {
|
|
410
509
|
method: "GET",
|
|
411
|
-
headers:
|
|
412
|
-
Authorization: token,
|
|
413
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
414
|
-
"Content-Type": "application/json"
|
|
415
|
-
}
|
|
510
|
+
headers: await getDefaultHeaders(account)
|
|
416
511
|
};
|
|
417
512
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
418
513
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
@@ -460,9 +555,8 @@ async function getServiceById(serviceId, account) {
|
|
|
460
555
|
throw new backstagePluginCommon.HttpError(`Failed to parse service information: ${error}`, 500);
|
|
461
556
|
}
|
|
462
557
|
}
|
|
463
|
-
async function
|
|
558
|
+
async function getSerivcesByIdsAndAccount(serviceIds, account) {
|
|
464
559
|
let response;
|
|
465
|
-
const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
466
560
|
const token = await auth.getAuthToken(account);
|
|
467
561
|
const options = {
|
|
468
562
|
method: "GET",
|
|
@@ -474,6 +568,59 @@ async function getServiceByIntegrationKey(integrationKey, account) {
|
|
|
474
568
|
};
|
|
475
569
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
476
570
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
571
|
+
try {
|
|
572
|
+
response = await fetchWithRetries(
|
|
573
|
+
`${baseUrl}?id[]=${serviceIds.join("&id[]=")}`,
|
|
574
|
+
options
|
|
575
|
+
);
|
|
576
|
+
} catch (error) {
|
|
577
|
+
throw new Error(`Failed to retrieve service: ${error}`);
|
|
578
|
+
}
|
|
579
|
+
if (response.status >= 500) {
|
|
580
|
+
throw new backstagePluginCommon.HttpError(
|
|
581
|
+
`Failed to get service. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,
|
|
582
|
+
response.status
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
switch (response.status) {
|
|
586
|
+
case 400:
|
|
587
|
+
throw new backstagePluginCommon.HttpError(
|
|
588
|
+
"Failed to get service. Caller provided invalid arguments.",
|
|
589
|
+
400
|
|
590
|
+
);
|
|
591
|
+
case 401:
|
|
592
|
+
throw new backstagePluginCommon.HttpError(
|
|
593
|
+
"Failed to get service. Caller did not supply credentials or did not provide the correct credentials.",
|
|
594
|
+
401
|
|
595
|
+
);
|
|
596
|
+
case 403:
|
|
597
|
+
throw new backstagePluginCommon.HttpError(
|
|
598
|
+
"Failed to get service. Caller is not authorized to view the requested resource.",
|
|
599
|
+
403
|
|
600
|
+
);
|
|
601
|
+
case 404:
|
|
602
|
+
throw new backstagePluginCommon.HttpError(
|
|
603
|
+
"Failed to get service. The requested resource was not found.",
|
|
604
|
+
404
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
let result;
|
|
608
|
+
try {
|
|
609
|
+
result = await response.json();
|
|
610
|
+
return result.services ?? [];
|
|
611
|
+
} catch (error) {
|
|
612
|
+
throw new backstagePluginCommon.HttpError(`Failed to parse service information: ${error}`, 500);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
async function getServiceByIntegrationKey(integrationKey, account) {
|
|
616
|
+
let response;
|
|
617
|
+
const params = `query=${integrationKey}&time_zone=UTC&include[]=integrations&include[]=escalation_policies`;
|
|
618
|
+
const options = {
|
|
619
|
+
method: "GET",
|
|
620
|
+
headers: await getDefaultHeaders(account)
|
|
621
|
+
};
|
|
622
|
+
const apiBaseUrl = getApiBaseUrl(account);
|
|
623
|
+
const baseUrl = `${apiBaseUrl}/services`;
|
|
477
624
|
try {
|
|
478
625
|
response = await fetchWithRetries(`${baseUrl}?${params}`, options);
|
|
479
626
|
} catch (error) {
|
|
@@ -521,12 +668,79 @@ async function getServiceByIntegrationKey(integrationKey, account) {
|
|
|
521
668
|
}
|
|
522
669
|
return result.services[0];
|
|
523
670
|
}
|
|
671
|
+
async function getServicesByIds(ids) {
|
|
672
|
+
let services = [];
|
|
673
|
+
await Promise.all(
|
|
674
|
+
Object.entries(EndpointConfig).map(async ([account, _]) => {
|
|
675
|
+
services = await getSerivcesByIdsAndAccount(ids, account);
|
|
676
|
+
})
|
|
677
|
+
);
|
|
678
|
+
return services;
|
|
679
|
+
}
|
|
524
680
|
async function getAllServices() {
|
|
525
681
|
const allServices = [];
|
|
526
682
|
await Promise.all(
|
|
527
683
|
Object.entries(EndpointConfig).map(async ([account, _]) => {
|
|
528
684
|
let response;
|
|
529
685
|
const params = `time_zone=UTC&include[]=integrations&include[]=escalation_policies&include[]=teams&total=true`;
|
|
686
|
+
const options = {
|
|
687
|
+
method: "GET",
|
|
688
|
+
headers: await getDefaultHeaders(account)
|
|
689
|
+
};
|
|
690
|
+
const apiBaseUrl = getApiBaseUrl(account);
|
|
691
|
+
const baseUrl = `${apiBaseUrl}/services`;
|
|
692
|
+
let offset = 0;
|
|
693
|
+
const limit = 50;
|
|
694
|
+
let result;
|
|
695
|
+
try {
|
|
696
|
+
do {
|
|
697
|
+
const paginatedUrl = `${baseUrl}?${params}&offset=${offset}&limit=${limit}`;
|
|
698
|
+
response = await fetchWithRetries(paginatedUrl, options);
|
|
699
|
+
if (response.status >= 500) {
|
|
700
|
+
throw new backstagePluginCommon.HttpError(
|
|
701
|
+
`Failed to get services. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,
|
|
702
|
+
response.status
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
switch (response.status) {
|
|
706
|
+
case 400:
|
|
707
|
+
throw new backstagePluginCommon.HttpError(
|
|
708
|
+
"Failed to get services. Caller provided invalid arguments.",
|
|
709
|
+
400
|
|
710
|
+
);
|
|
711
|
+
case 401:
|
|
712
|
+
throw new backstagePluginCommon.HttpError(
|
|
713
|
+
"Failed to get services. Caller did not supply credentials or did not provide the correct credentials.",
|
|
714
|
+
401
|
|
715
|
+
);
|
|
716
|
+
case 403:
|
|
717
|
+
throw new backstagePluginCommon.HttpError(
|
|
718
|
+
"Failed to get services. Caller is not authorized to view the requested resource.",
|
|
719
|
+
403
|
|
720
|
+
);
|
|
721
|
+
default:
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
result = await response.json();
|
|
725
|
+
result.services.forEach((service) => {
|
|
726
|
+
service.account = account;
|
|
727
|
+
});
|
|
728
|
+
allServices.push(...result.services);
|
|
729
|
+
offset += limit;
|
|
730
|
+
} while (offset < result.total);
|
|
731
|
+
} catch (error) {
|
|
732
|
+
throw error;
|
|
733
|
+
}
|
|
734
|
+
})
|
|
735
|
+
);
|
|
736
|
+
return allServices;
|
|
737
|
+
}
|
|
738
|
+
async function getServicesByPartialName(partialName) {
|
|
739
|
+
const allServices = [];
|
|
740
|
+
await Promise.all(
|
|
741
|
+
Object.entries(EndpointConfig).map(async ([account, _]) => {
|
|
742
|
+
let response;
|
|
743
|
+
const params = `query=${encodeURIComponent(partialName)}&time_zone=UTC&include[]=integrations&include[]=escalation_policies&include[]=teams&total=true`;
|
|
530
744
|
const token = await auth.getAuthToken(account);
|
|
531
745
|
const options = {
|
|
532
746
|
method: "GET",
|
|
@@ -584,16 +798,77 @@ async function getAllServices() {
|
|
|
584
798
|
);
|
|
585
799
|
return allServices;
|
|
586
800
|
}
|
|
801
|
+
async function getFilteredServices(teamIds, query, maxLimit, account) {
|
|
802
|
+
const allServices = [];
|
|
803
|
+
const limit = maxLimit;
|
|
804
|
+
const accountsToFetch = account ? [account] : Object.keys(EndpointConfig);
|
|
805
|
+
await Promise.all(
|
|
806
|
+
accountsToFetch.map(async (acc) => {
|
|
807
|
+
let response;
|
|
808
|
+
let params = `time_zone=UTC&limit=${limit}`;
|
|
809
|
+
if (teamIds && teamIds.length > 0) {
|
|
810
|
+
const teamIdsParam = teamIds.map((id) => `team_ids[]=${id}`).join("&");
|
|
811
|
+
params += `&${teamIdsParam}`;
|
|
812
|
+
}
|
|
813
|
+
if (query && query.trim() !== "") {
|
|
814
|
+
params += `&query=${encodeURIComponent(query.trim())}`;
|
|
815
|
+
}
|
|
816
|
+
const token = await auth.getAuthToken(acc);
|
|
817
|
+
const options = {
|
|
818
|
+
method: "GET",
|
|
819
|
+
headers: {
|
|
820
|
+
Authorization: token,
|
|
821
|
+
Accept: "application/vnd.pagerduty+json;version=2",
|
|
822
|
+
"Content-Type": "application/json"
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const apiBaseUrl = getApiBaseUrl(acc);
|
|
826
|
+
const baseUrl = `${apiBaseUrl}/services`;
|
|
827
|
+
try {
|
|
828
|
+
response = await fetchWithRetries(`${baseUrl}?${params}`, options);
|
|
829
|
+
if (response.status >= 500) {
|
|
830
|
+
throw new backstagePluginCommon.HttpError(
|
|
831
|
+
`Failed to get services. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,
|
|
832
|
+
response.status
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
switch (response.status) {
|
|
836
|
+
case 400:
|
|
837
|
+
throw new backstagePluginCommon.HttpError(
|
|
838
|
+
"Failed to get services. Caller provided invalid arguments.",
|
|
839
|
+
400
|
|
840
|
+
);
|
|
841
|
+
case 401:
|
|
842
|
+
throw new backstagePluginCommon.HttpError(
|
|
843
|
+
"Failed to get services. Caller did not supply credentials or did not provide the correct credentials.",
|
|
844
|
+
401
|
|
845
|
+
);
|
|
846
|
+
case 403:
|
|
847
|
+
throw new backstagePluginCommon.HttpError(
|
|
848
|
+
"Failed to get services. Caller is not authorized to view the requested resource.",
|
|
849
|
+
403
|
|
850
|
+
);
|
|
851
|
+
default:
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
const result = await response.json();
|
|
855
|
+
result.services.forEach((service) => {
|
|
856
|
+
service.account = acc;
|
|
857
|
+
});
|
|
858
|
+
allServices.push(...result.services);
|
|
859
|
+
} catch (error) {
|
|
860
|
+
throw error;
|
|
861
|
+
}
|
|
862
|
+
})
|
|
863
|
+
);
|
|
864
|
+
return allServices;
|
|
865
|
+
}
|
|
587
866
|
async function getChangeEvents(serviceId, account) {
|
|
588
867
|
let response;
|
|
589
868
|
const params = `limit=5&time_zone=UTC&sort_by=timestamp`;
|
|
590
869
|
const options = {
|
|
591
870
|
method: "GET",
|
|
592
|
-
headers:
|
|
593
|
-
Authorization: await auth.getAuthToken(account),
|
|
594
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
595
|
-
"Content-Type": "application/json"
|
|
596
|
-
}
|
|
871
|
+
headers: await getDefaultHeaders(account)
|
|
597
872
|
};
|
|
598
873
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
599
874
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
@@ -649,11 +924,7 @@ async function getIncidents(serviceId, account) {
|
|
|
649
924
|
const params = `time_zone=UTC&sort_by=created_at&statuses[]=triggered&statuses[]=acknowledged&service_ids[]=${serviceId}`;
|
|
650
925
|
const options = {
|
|
651
926
|
method: "GET",
|
|
652
|
-
headers:
|
|
653
|
-
Authorization: await auth.getAuthToken(account),
|
|
654
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
655
|
-
"Content-Type": "application/json"
|
|
656
|
-
}
|
|
927
|
+
headers: await getDefaultHeaders(account)
|
|
657
928
|
};
|
|
658
929
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
659
930
|
const baseUrl = `${apiBaseUrl}/incidents`;
|
|
@@ -707,11 +978,7 @@ async function getServiceStandards(serviceId, account) {
|
|
|
707
978
|
let response;
|
|
708
979
|
const options = {
|
|
709
980
|
method: "GET",
|
|
710
|
-
headers:
|
|
711
|
-
Authorization: await auth.getAuthToken(account),
|
|
712
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
713
|
-
"Content-Type": "application/json"
|
|
714
|
-
}
|
|
981
|
+
headers: await getDefaultHeaders(account)
|
|
715
982
|
};
|
|
716
983
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
717
984
|
const baseUrl = `${apiBaseUrl}/standards/scores/technical_services/${serviceId}`;
|
|
@@ -768,11 +1035,7 @@ async function getServiceMetrics(serviceId, account) {
|
|
|
768
1035
|
});
|
|
769
1036
|
const options = {
|
|
770
1037
|
method: "POST",
|
|
771
|
-
headers:
|
|
772
|
-
Authorization: await auth.getAuthToken(account),
|
|
773
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
774
|
-
"Content-Type": "application/json"
|
|
775
|
-
},
|
|
1038
|
+
headers: await getDefaultHeaders(account),
|
|
776
1039
|
body
|
|
777
1040
|
};
|
|
778
1041
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
@@ -818,7 +1081,6 @@ async function createServiceIntegration({
|
|
|
818
1081
|
let response;
|
|
819
1082
|
const apiBaseUrl = getApiBaseUrl(account);
|
|
820
1083
|
const baseUrl = `${apiBaseUrl}/services`;
|
|
821
|
-
const token = await auth.getAuthToken(account);
|
|
822
1084
|
const options = {
|
|
823
1085
|
method: "POST",
|
|
824
1086
|
body: JSON.stringify({
|
|
@@ -834,11 +1096,7 @@ async function createServiceIntegration({
|
|
|
834
1096
|
}
|
|
835
1097
|
}
|
|
836
1098
|
}),
|
|
837
|
-
headers:
|
|
838
|
-
Authorization: token,
|
|
839
|
-
Accept: "application/vnd.pagerduty+json;version=2",
|
|
840
|
-
"Content-Type": "application/json"
|
|
841
|
-
}
|
|
1099
|
+
headers: await getDefaultHeaders(account)
|
|
842
1100
|
};
|
|
843
1101
|
try {
|
|
844
1102
|
response = await fetchWithRetries(
|
|
@@ -906,16 +1164,21 @@ exports.createServiceIntegration = createServiceIntegration;
|
|
|
906
1164
|
exports.fetchWithRetries = fetchWithRetries;
|
|
907
1165
|
exports.getAllEscalationPolicies = getAllEscalationPolicies;
|
|
908
1166
|
exports.getAllServices = getAllServices;
|
|
1167
|
+
exports.getAllTeams = getAllTeams;
|
|
909
1168
|
exports.getChangeEvents = getChangeEvents;
|
|
1169
|
+
exports.getFilteredServices = getFilteredServices;
|
|
910
1170
|
exports.getIncidents = getIncidents;
|
|
911
1171
|
exports.getOncallUsers = getOncallUsers;
|
|
1172
|
+
exports.getSerivcesByIdsAndAccount = getSerivcesByIdsAndAccount;
|
|
912
1173
|
exports.getServiceById = getServiceById;
|
|
913
1174
|
exports.getServiceByIntegrationKey = getServiceByIntegrationKey;
|
|
914
1175
|
exports.getServiceMetrics = getServiceMetrics;
|
|
915
1176
|
exports.getServiceRelationshipsById = getServiceRelationshipsById;
|
|
916
1177
|
exports.getServiceStandards = getServiceStandards;
|
|
917
|
-
exports.
|
|
1178
|
+
exports.getServicesByIds = getServicesByIds;
|
|
1179
|
+
exports.getServicesByPartialName = getServicesByPartialName;
|
|
1180
|
+
exports.insertAccountConfig = insertAccountConfig;
|
|
918
1181
|
exports.loadPagerDutyEndpointsFromConfig = loadPagerDutyEndpointsFromConfig;
|
|
919
1182
|
exports.removeServiceRelationsFromService = removeServiceRelationsFromService;
|
|
920
|
-
exports.
|
|
1183
|
+
exports.setFallbackAccountConfig = setFallbackAccountConfig;
|
|
921
1184
|
//# sourceMappingURL=pagerduty.cjs.js.map
|