@pagerduty/backstage-plugin-entity-processor 0.3.3 → 0.3.5
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/config.d.ts +32 -29
- package/dist/apis/client.cjs.js +132 -43
- package/dist/apis/client.cjs.js.map +1 -1
- package/dist/module.cjs.js +6 -3
- package/dist/module.cjs.js.map +1 -1
- package/dist/processor/PagerDutyEntityProcessor.cjs.js +144 -75
- package/dist/processor/PagerDutyEntityProcessor.cjs.js.map +1 -1
- package/package.json +3 -3
package/config.d.ts
CHANGED
|
@@ -14,39 +14,42 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
PagerDutyAccountConfig,
|
|
19
|
+
PagerDutyOAuthConfig,
|
|
20
|
+
} from '@pagerduty/backstage-plugin-common';
|
|
18
21
|
|
|
19
22
|
export interface Config {
|
|
23
|
+
/**
|
|
24
|
+
* Configuration for the PagerDuty plugin
|
|
25
|
+
* @visibility frontend
|
|
26
|
+
*/
|
|
27
|
+
pagerDuty?: {
|
|
20
28
|
/**
|
|
21
|
-
*
|
|
29
|
+
* Optional Events Base URL to override the default.
|
|
22
30
|
* @visibility frontend
|
|
23
31
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Optional PagerDuty Scoped OAuth Token used in API calls from the backend component.
|
|
42
|
-
* @deepVisibility secret
|
|
43
|
-
*/
|
|
44
|
-
oauth?: PagerDutyOAuthConfig;
|
|
32
|
+
eventsBaseUrl?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Optional API Base URL to override the default.
|
|
35
|
+
* @visibility frontend
|
|
36
|
+
*/
|
|
37
|
+
apiBaseUrl?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Optional PagerDuty API Token used in API calls from the backend component.
|
|
40
|
+
* @visibility secret
|
|
41
|
+
*/
|
|
42
|
+
apiToken?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Optional PagerDuty Scoped OAuth Token used in API calls from the backend component.
|
|
45
|
+
* @deepVisibility secret
|
|
46
|
+
*/
|
|
47
|
+
oauth?: PagerDutyOAuthConfig;
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Optional PagerDuty multi-account configuration
|
|
51
|
+
* @deepVisibility secret
|
|
52
|
+
*/
|
|
53
|
+
accounts?: PagerDutyAccountConfig[];
|
|
54
|
+
};
|
|
52
55
|
}
|
package/dist/apis/client.cjs.js
CHANGED
|
@@ -9,8 +9,10 @@ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
|
|
|
9
9
|
class PagerDutyClient {
|
|
10
10
|
discovery;
|
|
11
11
|
logger;
|
|
12
|
+
auth;
|
|
12
13
|
baseUrl = "";
|
|
13
|
-
constructor({ discovery, logger }) {
|
|
14
|
+
constructor({ auth, discovery, logger }) {
|
|
15
|
+
this.auth = auth;
|
|
14
16
|
this.discovery = discovery;
|
|
15
17
|
this.logger = logger;
|
|
16
18
|
}
|
|
@@ -23,7 +25,8 @@ class PagerDutyClient {
|
|
|
23
25
|
method: "POST",
|
|
24
26
|
headers: {
|
|
25
27
|
"Content-Type": "application/json; charset=UTF-8",
|
|
26
|
-
Accept: "application/json, text/plain, */*"
|
|
28
|
+
Accept: "application/json, text/plain, */*",
|
|
29
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
27
30
|
},
|
|
28
31
|
body: JSON.stringify(relations)
|
|
29
32
|
};
|
|
@@ -33,7 +36,9 @@ class PagerDutyClient {
|
|
|
33
36
|
try {
|
|
34
37
|
response = await fetchWithRetries(url, options);
|
|
35
38
|
if (response.status >= 500) {
|
|
36
|
-
throw new Error(
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Failed to add service relation to service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`
|
|
41
|
+
);
|
|
37
42
|
}
|
|
38
43
|
if (!response.ok) {
|
|
39
44
|
throw new Error(await response.text());
|
|
@@ -52,7 +57,8 @@ class PagerDutyClient {
|
|
|
52
57
|
method: "DELETE",
|
|
53
58
|
headers: {
|
|
54
59
|
"Content-Type": "application/json; charset=UTF-8",
|
|
55
|
-
Accept: "application/json, text/plain, */*"
|
|
60
|
+
Accept: "application/json, text/plain, */*",
|
|
61
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
56
62
|
},
|
|
57
63
|
body: JSON.stringify(relations)
|
|
58
64
|
};
|
|
@@ -62,7 +68,9 @@ class PagerDutyClient {
|
|
|
62
68
|
try {
|
|
63
69
|
response = await fetchWithRetries(url, options);
|
|
64
70
|
if (response.status >= 500) {
|
|
65
|
-
throw new Error(
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Failed to remove service relation from service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`
|
|
73
|
+
);
|
|
66
74
|
}
|
|
67
75
|
if (response.status === 404) {
|
|
68
76
|
throw new Error(`Service ${serviceId} or dependencies not found.`);
|
|
@@ -71,8 +79,12 @@ class PagerDutyClient {
|
|
|
71
79
|
throw new Error(await response.text());
|
|
72
80
|
}
|
|
73
81
|
} catch (error) {
|
|
74
|
-
this.logger.error(
|
|
75
|
-
|
|
82
|
+
this.logger.error(
|
|
83
|
+
`Failed to remove dependencies from ${serviceId}: ${error}`
|
|
84
|
+
);
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Failed to remove dependencies from ${serviceId}: ${error}`
|
|
87
|
+
);
|
|
76
88
|
}
|
|
77
89
|
}
|
|
78
90
|
async getAllServiceMappings() {
|
|
@@ -85,7 +97,8 @@ class PagerDutyClient {
|
|
|
85
97
|
method: "GET",
|
|
86
98
|
headers: {
|
|
87
99
|
"Content-Type": "application/json; charset=UTF-8",
|
|
88
|
-
Accept: "application/json, text/plain, */*"
|
|
100
|
+
Accept: "application/json, text/plain, */*",
|
|
101
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
89
102
|
}
|
|
90
103
|
};
|
|
91
104
|
const url = `${await this.discovery.getBaseUrl(
|
|
@@ -94,7 +107,9 @@ class PagerDutyClient {
|
|
|
94
107
|
try {
|
|
95
108
|
response = await fetchWithRetries(url, options);
|
|
96
109
|
if (response.status >= 500) {
|
|
97
|
-
throw new Error(
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Failed to get all service mappings. API returned a server error. Retrying with the same arguments will not work.`
|
|
112
|
+
);
|
|
98
113
|
}
|
|
99
114
|
const foundMappings = await response.json();
|
|
100
115
|
switch (response.status) {
|
|
@@ -113,7 +128,11 @@ class PagerDutyClient {
|
|
|
113
128
|
throw new Error(`Failed to retrieve mappings: ${error}`);
|
|
114
129
|
}
|
|
115
130
|
}
|
|
116
|
-
async findServiceMapping({
|
|
131
|
+
async findServiceMapping({
|
|
132
|
+
type,
|
|
133
|
+
namespace,
|
|
134
|
+
name
|
|
135
|
+
}) {
|
|
117
136
|
let response;
|
|
118
137
|
if (this.baseUrl === "") {
|
|
119
138
|
this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
|
|
@@ -122,7 +141,8 @@ class PagerDutyClient {
|
|
|
122
141
|
method: "GET",
|
|
123
142
|
headers: {
|
|
124
143
|
"Content-Type": "application/json; charset=UTF-8",
|
|
125
|
-
Accept: "application/json, text/plain, */*"
|
|
144
|
+
Accept: "application/json, text/plain, */*",
|
|
145
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
126
146
|
}
|
|
127
147
|
};
|
|
128
148
|
const url = `${await this.discovery.getBaseUrl(
|
|
@@ -131,7 +151,9 @@ class PagerDutyClient {
|
|
|
131
151
|
try {
|
|
132
152
|
response = await fetchWithRetries(url, options);
|
|
133
153
|
if (response.status >= 500) {
|
|
134
|
-
throw new Error(
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Failed to find service mapping. API returned a server error. Retrying with the same arguments will not work.`
|
|
156
|
+
);
|
|
135
157
|
}
|
|
136
158
|
const foundMapping = await response.json();
|
|
137
159
|
switch (response.status) {
|
|
@@ -140,7 +162,11 @@ class PagerDutyClient {
|
|
|
140
162
|
case 404:
|
|
141
163
|
return void 0;
|
|
142
164
|
default:
|
|
143
|
-
this.logger.debug(
|
|
165
|
+
this.logger.debug(
|
|
166
|
+
`Found mapping for ${type}:${namespace}/${name}: ${JSON.stringify(
|
|
167
|
+
foundMapping.mapping
|
|
168
|
+
)}`
|
|
169
|
+
);
|
|
144
170
|
return {
|
|
145
171
|
serviceId: foundMapping.mapping.serviceId,
|
|
146
172
|
integrationKey: foundMapping.mapping.integrationKey,
|
|
@@ -149,8 +175,12 @@ class PagerDutyClient {
|
|
|
149
175
|
};
|
|
150
176
|
}
|
|
151
177
|
} catch (error) {
|
|
152
|
-
this.logger.error(
|
|
153
|
-
|
|
178
|
+
this.logger.error(
|
|
179
|
+
`Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`
|
|
180
|
+
);
|
|
181
|
+
throw new Error(
|
|
182
|
+
`Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`
|
|
183
|
+
);
|
|
154
184
|
}
|
|
155
185
|
}
|
|
156
186
|
async findServiceMappingById(serviceId) {
|
|
@@ -162,7 +192,8 @@ class PagerDutyClient {
|
|
|
162
192
|
method: "GET",
|
|
163
193
|
headers: {
|
|
164
194
|
"Content-Type": "application/json; charset=UTF-8",
|
|
165
|
-
Accept: "application/json, text/plain, */*"
|
|
195
|
+
Accept: "application/json, text/plain, */*",
|
|
196
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
166
197
|
}
|
|
167
198
|
};
|
|
168
199
|
const url = `${await this.discovery.getBaseUrl(
|
|
@@ -171,7 +202,9 @@ class PagerDutyClient {
|
|
|
171
202
|
try {
|
|
172
203
|
response = await fetchWithRetries(url, options);
|
|
173
204
|
if (response.status >= 500) {
|
|
174
|
-
throw new Error(
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Failed to find service mapping by id. API returned a server error. Retrying with the same arguments will not work.`
|
|
207
|
+
);
|
|
175
208
|
}
|
|
176
209
|
const foundMapping = await response.json();
|
|
177
210
|
switch (response.status) {
|
|
@@ -180,7 +213,11 @@ class PagerDutyClient {
|
|
|
180
213
|
case 404:
|
|
181
214
|
return void 0;
|
|
182
215
|
default:
|
|
183
|
-
this.logger.debug(
|
|
216
|
+
this.logger.debug(
|
|
217
|
+
`Found mapping for serviceId ${serviceId}: ${JSON.stringify(
|
|
218
|
+
foundMapping.mapping
|
|
219
|
+
)}`
|
|
220
|
+
);
|
|
184
221
|
return {
|
|
185
222
|
serviceId: foundMapping.mapping.serviceId,
|
|
186
223
|
integrationKey: foundMapping.mapping.integrationKey,
|
|
@@ -189,8 +226,12 @@ class PagerDutyClient {
|
|
|
189
226
|
};
|
|
190
227
|
}
|
|
191
228
|
} catch (error) {
|
|
192
|
-
this.logger.error(
|
|
193
|
-
|
|
229
|
+
this.logger.error(
|
|
230
|
+
`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`
|
|
231
|
+
);
|
|
232
|
+
throw new Error(
|
|
233
|
+
`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`
|
|
234
|
+
);
|
|
194
235
|
}
|
|
195
236
|
}
|
|
196
237
|
async insertServiceMapping(mapping) {
|
|
@@ -202,7 +243,8 @@ class PagerDutyClient {
|
|
|
202
243
|
method: "POST",
|
|
203
244
|
headers: {
|
|
204
245
|
"Content-Type": "application/json; charset=UTF-8",
|
|
205
|
-
Accept: "application/json, text/plain, */*"
|
|
246
|
+
Accept: "application/json, text/plain, */*",
|
|
247
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
206
248
|
},
|
|
207
249
|
body: JSON.stringify(mapping)
|
|
208
250
|
};
|
|
@@ -212,14 +254,20 @@ class PagerDutyClient {
|
|
|
212
254
|
try {
|
|
213
255
|
response = await fetchWithRetries(url, options);
|
|
214
256
|
if (response.status >= 500) {
|
|
215
|
-
throw new Error(
|
|
257
|
+
throw new Error(
|
|
258
|
+
`Failed to add service mapping. API returned a server error. Retrying with the same arguments will not work.`
|
|
259
|
+
);
|
|
216
260
|
}
|
|
217
261
|
if (!response.ok) {
|
|
218
262
|
throw new Error(await response.text());
|
|
219
263
|
}
|
|
220
264
|
} catch (error) {
|
|
221
|
-
this.logger.error(
|
|
222
|
-
|
|
265
|
+
this.logger.error(
|
|
266
|
+
`Failed to add mapping for ${mapping.entityRef}: ${error}`
|
|
267
|
+
);
|
|
268
|
+
throw new Error(
|
|
269
|
+
`Failed to add mapping for ${mapping.entityRef}: ${error}`
|
|
270
|
+
);
|
|
223
271
|
}
|
|
224
272
|
}
|
|
225
273
|
async getServiceDependencies(serviceId, account) {
|
|
@@ -231,7 +279,8 @@ class PagerDutyClient {
|
|
|
231
279
|
method: "GET",
|
|
232
280
|
headers: {
|
|
233
281
|
"Content-Type": "application/json; charset=UTF-8",
|
|
234
|
-
Accept: "application/json, text/plain, */*"
|
|
282
|
+
Accept: "application/json, text/plain, */*",
|
|
283
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
235
284
|
}
|
|
236
285
|
};
|
|
237
286
|
let url = `${await this.discovery.getBaseUrl(
|
|
@@ -243,7 +292,9 @@ class PagerDutyClient {
|
|
|
243
292
|
try {
|
|
244
293
|
response = await fetchWithRetries(url, options);
|
|
245
294
|
if (response.status >= 500) {
|
|
246
|
-
throw new Error(
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Failed to get service depedencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`
|
|
297
|
+
);
|
|
247
298
|
}
|
|
248
299
|
const foundDependencies = await response.json();
|
|
249
300
|
switch (response.status) {
|
|
@@ -255,7 +306,9 @@ class PagerDutyClient {
|
|
|
255
306
|
return foundDependencies.relationships;
|
|
256
307
|
}
|
|
257
308
|
} catch (error) {
|
|
258
|
-
this.logger.error(
|
|
309
|
+
this.logger.error(
|
|
310
|
+
`Failed to retrieve mapping for ${serviceId}: ${error}`
|
|
311
|
+
);
|
|
259
312
|
throw new Error(`Failed to retrieve mapping for ${serviceId}: ${error}`);
|
|
260
313
|
}
|
|
261
314
|
}
|
|
@@ -268,7 +321,8 @@ class PagerDutyClient {
|
|
|
268
321
|
method: "GET",
|
|
269
322
|
headers: {
|
|
270
323
|
"Content-Type": "application/json; charset=UTF-8",
|
|
271
|
-
Accept: "application/json, text/plain, */*"
|
|
324
|
+
Accept: "application/json, text/plain, */*",
|
|
325
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
272
326
|
}
|
|
273
327
|
};
|
|
274
328
|
const [type, rest] = entityRef.split(":");
|
|
@@ -279,7 +333,9 @@ class PagerDutyClient {
|
|
|
279
333
|
try {
|
|
280
334
|
response = await fetchWithRetries(url, options);
|
|
281
335
|
if (response.status >= 500) {
|
|
282
|
-
throw new Error(
|
|
336
|
+
throw new Error(
|
|
337
|
+
`Failed to get service id annotation from catalog. API returned a server error. Retrying with the same arguments will not work.`
|
|
338
|
+
);
|
|
283
339
|
}
|
|
284
340
|
const foundServiceId = await response.json();
|
|
285
341
|
switch (response.status) {
|
|
@@ -291,8 +347,12 @@ class PagerDutyClient {
|
|
|
291
347
|
return foundServiceId;
|
|
292
348
|
}
|
|
293
349
|
} catch (error) {
|
|
294
|
-
this.logger.error(
|
|
295
|
-
|
|
350
|
+
this.logger.error(
|
|
351
|
+
`Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`
|
|
352
|
+
);
|
|
353
|
+
throw new Error(
|
|
354
|
+
`Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`
|
|
355
|
+
);
|
|
296
356
|
}
|
|
297
357
|
}
|
|
298
358
|
async getServiceIdFromIntegrationKey(integrationKey, account) {
|
|
@@ -304,7 +364,8 @@ class PagerDutyClient {
|
|
|
304
364
|
method: "GET",
|
|
305
365
|
headers: {
|
|
306
366
|
"Content-Type": "application/json; charset=UTF-8",
|
|
307
|
-
Accept: "application/json, text/plain, */*"
|
|
367
|
+
Accept: "application/json, text/plain, */*",
|
|
368
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
308
369
|
}
|
|
309
370
|
};
|
|
310
371
|
let url = `${await this.discovery.getBaseUrl(
|
|
@@ -316,7 +377,9 @@ class PagerDutyClient {
|
|
|
316
377
|
try {
|
|
317
378
|
response = await fetchWithRetries(url, options);
|
|
318
379
|
if (response.status >= 500) {
|
|
319
|
-
throw new Error(
|
|
380
|
+
throw new Error(
|
|
381
|
+
`Failed to get service id from integration key ${integrationKey}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`
|
|
382
|
+
);
|
|
320
383
|
}
|
|
321
384
|
const foundService = await response.json();
|
|
322
385
|
switch (response.status) {
|
|
@@ -328,8 +391,12 @@ class PagerDutyClient {
|
|
|
328
391
|
return foundService.service.id;
|
|
329
392
|
}
|
|
330
393
|
} catch (error) {
|
|
331
|
-
this.logger.error(
|
|
332
|
-
|
|
394
|
+
this.logger.error(
|
|
395
|
+
`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`
|
|
396
|
+
);
|
|
397
|
+
throw new Error(
|
|
398
|
+
`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`
|
|
399
|
+
);
|
|
333
400
|
}
|
|
334
401
|
}
|
|
335
402
|
async getIntegrationKeyFromServiceId(serviceId, account) {
|
|
@@ -341,7 +408,8 @@ class PagerDutyClient {
|
|
|
341
408
|
method: "GET",
|
|
342
409
|
headers: {
|
|
343
410
|
"Content-Type": "application/json; charset=UTF-8",
|
|
344
|
-
Accept: "application/json, text/plain, */*"
|
|
411
|
+
Accept: "application/json, text/plain, */*",
|
|
412
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
345
413
|
}
|
|
346
414
|
};
|
|
347
415
|
let url = `${await this.discovery.getBaseUrl(
|
|
@@ -353,10 +421,14 @@ class PagerDutyClient {
|
|
|
353
421
|
try {
|
|
354
422
|
response = await fetchWithRetries(url, options);
|
|
355
423
|
if (response.status >= 500) {
|
|
356
|
-
throw new Error(
|
|
424
|
+
throw new Error(
|
|
425
|
+
`Failed to get integration key from service id ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`
|
|
426
|
+
);
|
|
357
427
|
}
|
|
358
428
|
const foundService = await response.json();
|
|
359
|
-
const backstageIntegration = foundService.service.integrations?.find(
|
|
429
|
+
const backstageIntegration = foundService.service.integrations?.find(
|
|
430
|
+
(integration) => integration.vendor?.id === "PRO19CT"
|
|
431
|
+
);
|
|
360
432
|
switch (response.status) {
|
|
361
433
|
case 400:
|
|
362
434
|
throw new Error(await response.text());
|
|
@@ -369,8 +441,12 @@ class PagerDutyClient {
|
|
|
369
441
|
return backstageIntegration.integration_key;
|
|
370
442
|
}
|
|
371
443
|
} catch (error) {
|
|
372
|
-
this.logger.error(
|
|
373
|
-
|
|
444
|
+
this.logger.error(
|
|
445
|
+
`No Backstage integration found for service id ${serviceId}: ${error}`
|
|
446
|
+
);
|
|
447
|
+
throw new Error(
|
|
448
|
+
`No Backstage integration found for service id ${serviceId}: ${error}`
|
|
449
|
+
);
|
|
374
450
|
}
|
|
375
451
|
}
|
|
376
452
|
async getServiceDependencyStrategySetting() {
|
|
@@ -383,7 +459,8 @@ class PagerDutyClient {
|
|
|
383
459
|
method: "GET",
|
|
384
460
|
headers: {
|
|
385
461
|
"Content-Type": "application/json; charset=UTF-8",
|
|
386
|
-
Accept: "application/json, text/plain, */*"
|
|
462
|
+
Accept: "application/json, text/plain, */*",
|
|
463
|
+
Authorization: await this.generatePluginToPluginToken()
|
|
387
464
|
}
|
|
388
465
|
};
|
|
389
466
|
const url = `${await this.discovery.getBaseUrl(
|
|
@@ -392,7 +469,9 @@ class PagerDutyClient {
|
|
|
392
469
|
try {
|
|
393
470
|
response = await fetchWithRetries(url, options);
|
|
394
471
|
if (response.status >= 500) {
|
|
395
|
-
throw new Error(
|
|
472
|
+
throw new Error(
|
|
473
|
+
`Failed to get service depedency strategy. API returned a server error. Retrying with the same arguments will not work.`
|
|
474
|
+
);
|
|
396
475
|
}
|
|
397
476
|
const setting = await response.json();
|
|
398
477
|
switch (response.status) {
|
|
@@ -409,6 +488,14 @@ class PagerDutyClient {
|
|
|
409
488
|
throw new Error(`Error getting value for setting: ${error}`);
|
|
410
489
|
}
|
|
411
490
|
}
|
|
491
|
+
async generatePluginToPluginToken() {
|
|
492
|
+
this.logger.debug("Generating plugin to plugin token for pagerduty");
|
|
493
|
+
const { token } = await this.auth.getPluginRequestToken({
|
|
494
|
+
onBehalfOf: await this.auth.getOwnServiceCredentials(),
|
|
495
|
+
targetPluginId: "pagerduty"
|
|
496
|
+
});
|
|
497
|
+
return `Bearer ${token}`;
|
|
498
|
+
}
|
|
412
499
|
}
|
|
413
500
|
async function fetchWithRetries(url, options) {
|
|
414
501
|
let response;
|
|
@@ -427,7 +514,9 @@ async function fetchWithRetries(url, options) {
|
|
|
427
514
|
await new Promise((resolve) => setTimeout(resolve, timeout));
|
|
428
515
|
factor *= 2;
|
|
429
516
|
}
|
|
430
|
-
throw new Error(
|
|
517
|
+
throw new Error(
|
|
518
|
+
`Failed to fetch data after ${maxRetries} retries. Last error: ${error}`
|
|
519
|
+
);
|
|
431
520
|
}
|
|
432
521
|
|
|
433
522
|
exports.PagerDutyClient = PagerDutyClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs.js","sources":["../../src/apis/client.ts"],"sourcesContent":["import fetch from 'node-fetch';\nimport type {\n RequestInit,\n Response\n} from 'node-fetch';\nimport type { EntityMapping } from '../types';\nimport {\n DiscoveryService,\n LoggerService\n} from '@backstage/backend-plugin-api';\nimport {\n PagerDutyEntityMapping,\n PagerDutyEntityMappingResponse,\n PagerDutyServiceResponse,\n PagerDutyServiceDependency,\n PagerDutyServiceDependencyResponse,\n PagerDutySetting,\n PagerDutyEntityMappingsResponse,\n} from '@pagerduty/backstage-plugin-common';\n\nexport interface PagerDutyClientOptions {\n discovery: DiscoveryService;\n logger: LoggerService;\n};\n\nexport type BackstageEntityRef = {\n type: string;\n namespace: string;\n name: string;\n}\n\nexport class PagerDutyClient {\n private discovery: DiscoveryService;\n private logger: LoggerService;\n private baseUrl: string = \"\";\n\n constructor({ discovery, logger }: PagerDutyClientOptions) {\n this.discovery = discovery;\n this.logger = logger;\n }\n\n async addServiceRelationToService(serviceId: string, relations: string[]) : Promise<void> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n body: JSON.stringify(relations),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to add service relation to service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(`Failed to add dependencies: ${error}`);\n throw new Error(`Failed to add dependencies: ${error}`);\n }\n }\n\n async removeServiceRelationFromService(serviceId: string, relations: string[]): Promise<void> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n body: JSON.stringify(relations),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to remove service relation from service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n if (response.status === 404) {\n throw new Error(`Service ${serviceId} or dependencies not found.`);\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(`Failed to remove dependencies from ${serviceId}: ${error}`);\n throw new Error(`Failed to remove dependencies from ${serviceId}: ${error}`);\n }\n }\n\n async getAllServiceMappings(): Promise<Record<string, string>> {\n let response: Response;\n const mappings: Record<string, string> = {};\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to get all service mappings. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundMappings: PagerDutyEntityMappingsResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return mappings;\n default: // 200\n foundMappings.mappings.forEach(mapping => {\n mappings[mapping.serviceId] = mapping.entityRef;\n });\n\n return mappings;\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve mappings: ${error}`);\n throw new Error(`Failed to retrieve mappings: ${error}`);\n }\n }\n\n async findServiceMapping({ type, namespace, name }: BackstageEntityRef): Promise<EntityMapping | undefined> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity/${type}/${namespace}/${name}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to find service mapping. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundMapping: PagerDutyEntityMappingResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return undefined;\n default: // 200\n this.logger.debug(`Found mapping for ${type}:${namespace}/${name}: ${JSON.stringify(foundMapping.mapping)}`);\n\n return {\n serviceId: foundMapping.mapping.serviceId,\n integrationKey: foundMapping.mapping.integrationKey,\n entityRef: foundMapping.mapping.entityRef,\n account: foundMapping.mapping.account,\n }\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`);\n throw new Error(`Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`);\n }\n }\n\n async findServiceMappingById(serviceId: string): Promise<EntityMapping | undefined> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to find service mapping by id. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundMapping: PagerDutyEntityMappingResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return undefined;\n default: // 200\n this.logger.debug(`Found mapping for serviceId ${serviceId}: ${JSON.stringify(foundMapping.mapping)}`);\n\n return {\n serviceId: foundMapping.mapping.serviceId,\n integrationKey: foundMapping.mapping.integrationKey,\n entityRef: foundMapping.mapping.entityRef,\n account: foundMapping.mapping.account,\n };\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`);\n throw new Error(`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`);\n }\n }\n\n async insertServiceMapping(mapping: PagerDutyEntityMapping): Promise<void> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n body: JSON.stringify(mapping),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to add service mapping. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(`Failed to add mapping for ${mapping.entityRef}: ${error}`);\n throw new Error(`Failed to add mapping for ${mapping.entityRef}: ${error}`);\n }\n }\n\n async getServiceDependencies(serviceId: string, account?: string): Promise<PagerDutyServiceDependency[]> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n if (account) {\n url = url.concat(`?account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to get service depedencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundDependencies: PagerDutyServiceDependencyResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return [];\n default: // 200\n return foundDependencies.relationships;\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve mapping for ${serviceId}: ${error}`);\n throw new Error(`Failed to retrieve mapping for ${serviceId}: ${error}`);\n }\n }\n\n async getServiceIdAnnotationFromCatalog(entityRef: string): Promise<string> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n // extract type, namespace and name from type:namespace/name\n const [type, rest] = entityRef.split(':');\n const [namespace, name] = rest.split('/');\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/catalog/entity/${type}/${namespace}/${name}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to get service id annotation from catalog. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundServiceId: string = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return \"\";\n default: // 200\n return foundServiceId;\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`);\n throw new Error(`Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`);\n }\n }\n\n async getServiceIdFromIntegrationKey(integrationKey: string, account?: string): Promise<string> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/services?integration_key=${integrationKey}`;\n\n if (account) {\n url = url.concat(`&account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to get service id from integration key ${integrationKey}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundService: PagerDutyServiceResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return \"\";\n default: // 200\n return foundService.service.id;\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`);\n throw new Error(`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`);\n }\n }\n\n async getIntegrationKeyFromServiceId(serviceId: string, account?: string): Promise<string | undefined> {\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/services/${serviceId}`;\n\n if (account) {\n url = url.concat(`?account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(`Failed to get integration key from service id ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const foundService: PagerDutyServiceResponse = await response.json();\n const backstageIntegration = foundService.service.integrations?.find(integration => integration.vendor?.id === \"PRO19CT\");\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return \"\";\n default: // 200\n\n if (!backstageIntegration) {\n return undefined;\n }\n\n return backstageIntegration.integration_key;\n }\n } catch (error) {\n this.logger.error(`No Backstage integration found for service id ${serviceId}: ${error}`);\n throw new Error(`No Backstage integration found for service id ${serviceId}: ${error}`);\n }\n }\n\n async getServiceDependencyStrategySetting(): Promise<string> {\n const SERVICE_DEPENDENCY_SYNC_STRATEGY = \"settings::service-dependency-sync-strategy\";\n\n let response: Response;\n\n if (this.baseUrl === \"\") {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/settings/${SERVICE_DEPENDENCY_SYNC_STRATEGY}`;\n\n try {\n response = await fetchWithRetries(url, options); \n\n if (response.status >= 500) {\n throw new Error(`Failed to get service depedency strategy. API returned a server error. Retrying with the same arguments will not work.`);\n }\n\n const setting: PagerDutySetting = await response.json(); \n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return \"disabled\"; // if setting does not exist in the database, default to disabled\n default: // 200\n return setting.value;\n }\n } catch (error) {\n this.logger.error(`Error getting value for setting: ${error}`);\n throw new Error(`Error getting value for setting: ${error}`);\n }\n }\n}\n\nexport async function fetchWithRetries(url: string, options: RequestInit): Promise<Response> {\n let response: Response;\n let error: Error = new Error();\n\n // set retry parameters\n const maxRetries = 5;\n const delay = 1000;\n let factor = 2;\n\n for (let i = 0; i < maxRetries; i++) {\n try {\n response = await fetch(url, options);\n return response;\n } catch (e) {\n error = e as Error;\n }\n\n const timeout = delay * factor;\n await new Promise(resolve => setTimeout(resolve, timeout));\n factor *= 2;\n }\n\n throw new Error(`Failed to fetch data after ${maxRetries} retries. Last error: ${error}`);\n}"],"names":["fetch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.cjs.js","sources":["../../src/apis/client.ts"],"sourcesContent":["import fetch from 'node-fetch';\nimport type { RequestInit, Response } from 'node-fetch';\nimport type { EntityMapping } from '../types';\nimport { AuthService, DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';\nimport {\n PagerDutyEntityMapping,\n PagerDutyEntityMappingResponse,\n PagerDutyServiceResponse,\n PagerDutyServiceDependency,\n PagerDutyServiceDependencyResponse,\n PagerDutySetting,\n PagerDutyEntityMappingsResponse,\n} from '@pagerduty/backstage-plugin-common';\n\nexport interface PagerDutyClientOptions {\n auth: AuthService;\n discovery: DiscoveryService;\n logger: LoggerService;\n}\n\nexport type BackstageEntityRef = {\n type: string;\n namespace: string;\n name: string;\n};\n\nexport class PagerDutyClient {\n private discovery: DiscoveryService;\n private logger: LoggerService;\n private auth: AuthService;\n private baseUrl: string = '';\n\n constructor({ auth, discovery, logger }: PagerDutyClientOptions) {\n this.auth = auth;\n this.discovery = discovery;\n this.logger = logger;\n }\n\n async addServiceRelationToService(\n serviceId: string,\n relations: string[],\n ): Promise<void> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n body: JSON.stringify(relations),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to add service relation to service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(`Failed to add dependencies: ${error}`);\n throw new Error(`Failed to add dependencies: ${error}`);\n }\n }\n\n async removeServiceRelationFromService(\n serviceId: string,\n relations: string[],\n ): Promise<void> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n body: JSON.stringify(relations),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to remove service relation from service ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n if (response.status === 404) {\n throw new Error(`Service ${serviceId} or dependencies not found.`);\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(\n `Failed to remove dependencies from ${serviceId}: ${error}`,\n );\n throw new Error(\n `Failed to remove dependencies from ${serviceId}: ${error}`,\n );\n }\n }\n\n async getAllServiceMappings(): Promise<Record<string, string>> {\n let response: Response;\n const mappings: Record<string, string> = {};\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get all service mappings. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundMappings: PagerDutyEntityMappingsResponse =\n await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return mappings;\n default: // 200\n foundMappings.mappings.forEach(mapping => {\n mappings[mapping.serviceId] = mapping.entityRef;\n });\n\n return mappings;\n }\n } catch (error) {\n this.logger.error(`Failed to retrieve mappings: ${error}`);\n throw new Error(`Failed to retrieve mappings: ${error}`);\n }\n }\n\n async findServiceMapping({\n type,\n namespace,\n name,\n }: BackstageEntityRef): Promise<EntityMapping | undefined> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity/${type}/${namespace}/${name}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to find service mapping. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundMapping: PagerDutyEntityMappingResponse =\n await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return undefined;\n default: // 200\n this.logger.debug(\n `Found mapping for ${type}:${namespace}/${name}: ${JSON.stringify(\n foundMapping.mapping,\n )}`,\n );\n\n return {\n serviceId: foundMapping.mapping.serviceId,\n integrationKey: foundMapping.mapping.integrationKey,\n entityRef: foundMapping.mapping.entityRef,\n account: foundMapping.mapping.account,\n };\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`,\n );\n throw new Error(\n `Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`,\n );\n }\n }\n\n async findServiceMappingById(\n serviceId: string,\n ): Promise<EntityMapping | undefined> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity/service/${serviceId}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to find service mapping by id. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundMapping: PagerDutyEntityMappingResponse =\n await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return undefined;\n default: // 200\n this.logger.debug(\n `Found mapping for serviceId ${serviceId}: ${JSON.stringify(\n foundMapping.mapping,\n )}`,\n );\n\n return {\n serviceId: foundMapping.mapping.serviceId,\n integrationKey: foundMapping.mapping.integrationKey,\n entityRef: foundMapping.mapping.entityRef,\n account: foundMapping.mapping.account,\n };\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve mapping for serviceId ${serviceId}: ${error}`,\n );\n throw new Error(\n `Failed to retrieve mapping for serviceId ${serviceId}: ${error}`,\n );\n }\n }\n\n async insertServiceMapping(mapping: PagerDutyEntityMapping): Promise<void> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n body: JSON.stringify(mapping),\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/mapping/entity`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to add service mapping. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(\n `Failed to add mapping for ${mapping.entityRef}: ${error}`,\n );\n throw new Error(\n `Failed to add mapping for ${mapping.entityRef}: ${error}`,\n );\n }\n }\n\n async getServiceDependencies(\n serviceId: string,\n account?: string,\n ): Promise<PagerDutyServiceDependency[]> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/dependencies/service/${serviceId}`;\n\n if (account) {\n url = url.concat(`?account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get service depedencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundDependencies: PagerDutyServiceDependencyResponse =\n await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return [];\n default: // 200\n return foundDependencies.relationships;\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve mapping for ${serviceId}: ${error}`,\n );\n throw new Error(`Failed to retrieve mapping for ${serviceId}: ${error}`);\n }\n }\n\n async getServiceIdAnnotationFromCatalog(entityRef: string): Promise<string> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n // extract type, namespace and name from type:namespace/name\n const [type, rest] = entityRef.split(':');\n const [namespace, name] = rest.split('/');\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/catalog/entity/${type}/${namespace}/${name}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get service id annotation from catalog. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundServiceId: string = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return '';\n default: // 200\n return foundServiceId;\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`,\n );\n throw new Error(\n `Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`,\n );\n }\n }\n\n async getServiceIdFromIntegrationKey(\n integrationKey: string,\n account?: string,\n ): Promise<string> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/services?integration_key=${integrationKey}`;\n\n if (account) {\n url = url.concat(`&account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get service id from integration key ${integrationKey}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundService: PagerDutyServiceResponse = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return '';\n default: // 200\n return foundService.service.id;\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`,\n );\n throw new Error(\n `Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`,\n );\n }\n }\n\n async getIntegrationKeyFromServiceId(\n serviceId: string,\n account?: string,\n ): Promise<string | undefined> {\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n let url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/services/${serviceId}`;\n\n if (account) {\n url = url.concat(`?account=${account}`);\n }\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get integration key from service id ${serviceId}. PagerDuty API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const foundService: PagerDutyServiceResponse = await response.json();\n const backstageIntegration = foundService.service.integrations?.find(\n integration => integration.vendor?.id === 'PRO19CT',\n );\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return '';\n default: // 200\n if (!backstageIntegration) {\n return undefined;\n }\n\n return backstageIntegration.integration_key;\n }\n } catch (error) {\n this.logger.error(\n `No Backstage integration found for service id ${serviceId}: ${error}`,\n );\n throw new Error(\n `No Backstage integration found for service id ${serviceId}: ${error}`,\n );\n }\n }\n\n async getServiceDependencyStrategySetting(): Promise<string> {\n const SERVICE_DEPENDENCY_SYNC_STRATEGY =\n 'settings::service-dependency-sync-strategy';\n\n let response: Response;\n\n if (this.baseUrl === '') {\n this.baseUrl = await this.discovery.getBaseUrl('pagerduty');\n }\n\n const options: RequestInit = {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json; charset=UTF-8',\n Accept: 'application/json, text/plain, */*',\n Authorization: await this.generatePluginToPluginToken(),\n },\n };\n\n const url = `${await this.discovery.getBaseUrl(\n 'pagerduty',\n )}/settings/${SERVICE_DEPENDENCY_SYNC_STRATEGY}`;\n\n try {\n response = await fetchWithRetries(url, options);\n\n if (response.status >= 500) {\n throw new Error(\n `Failed to get service depedency strategy. API returned a server error. Retrying with the same arguments will not work.`,\n );\n }\n\n const setting: PagerDutySetting = await response.json();\n\n switch (response.status) {\n case 400:\n throw new Error(await response.text());\n case 404:\n return 'disabled'; // if setting does not exist in the database, default to disabled\n default: // 200\n return setting.value;\n }\n } catch (error) {\n this.logger.error(`Error getting value for setting: ${error}`);\n throw new Error(`Error getting value for setting: ${error}`);\n }\n }\n\n private async generatePluginToPluginToken(): Promise<string> {\n this.logger.debug('Generating plugin to plugin token for pagerduty')\n\n const { token } = await this.auth.getPluginRequestToken({\n onBehalfOf: await this.auth.getOwnServiceCredentials(),\n targetPluginId: 'pagerduty',\n });\n\n return `Bearer ${token}`;\n }\n}\n\nexport async function fetchWithRetries(\n url: string,\n options: RequestInit,\n): Promise<Response> {\n let response: Response;\n let error: Error = new Error();\n\n // set retry parameters\n const maxRetries = 5;\n const delay = 1000;\n let factor = 2;\n\n for (let i = 0; i < maxRetries; i++) {\n try {\n response = await fetch(url, options);\n return response;\n } catch (e) {\n error = e as Error;\n }\n\n const timeout = delay * factor;\n await new Promise(resolve => setTimeout(resolve, timeout));\n factor *= 2;\n }\n\n throw new Error(\n `Failed to fetch data after ${maxRetries} retries. Last error: ${error}`,\n );\n}\n"],"names":["fetch"],"mappings":";;;;;;;;AA0BO,MAAM,eAAA,CAAgB;AAAA,EACnB,SAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA,GAAkB,EAAA;AAAA,EAE1B,WAAA,CAAY,EAAE,IAAA,EAAM,SAAA,EAAW,QAAO,EAA2B;AAC/D,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA,EAEA,MAAM,2BAAA,CACJ,SAAA,EACA,SAAA,EACe;AACf,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B,OACxD;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,SAAS;AAAA,KAChC;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,yBAAyB,SAAS,CAAA,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,6CAA6C,SAAS,CAAA,wFAAA;AAAA,SACxD;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,MACvC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,4BAAA,EAA+B,KAAK,CAAA,CAAE,CAAA;AACxD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,KAAK,CAAA,CAAE,CAAA;AAAA,IACxD;AAAA,EACF;AAAA,EAEA,MAAM,gCAAA,CACJ,SAAA,EACA,SAAA,EACe;AACf,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,QAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B,OACxD;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,SAAS;AAAA,KAChC;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,yBAAyB,SAAS,CAAA,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,kDAAkD,SAAS,CAAA,wFAAA;AAAA,SAC7D;AAAA,MACF;AAEA,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,SAAS,CAAA,2BAAA,CAA6B,CAAA;AAAA,MACnE;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,MACvC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,mCAAA,EAAsC,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC3D;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,mCAAA,EAAsC,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC3D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBAAA,GAAyD;AAC7D,IAAA,IAAI,QAAA;AACJ,IAAA,MAAM,WAAmC,EAAC;AAE1C,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,CAAA,eAAA,CAAA;AAED,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,gHAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,aAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,QAAA;AAAA,QACT;AACE,UAAA,aAAA,CAAc,QAAA,CAAS,QAAQ,CAAA,OAAA,KAAW;AACxC,YAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,GAAI,OAAA,CAAQ,SAAA;AAAA,UACxC,CAAC,CAAA;AAED,UAAA,OAAO,QAAA;AAAA;AACX,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,6BAAA,EAAgC,KAAK,CAAA,CAAE,CAAA;AACzD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,KAAK,CAAA,CAAE,CAAA;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,kBAAA,CAAmB;AAAA,IACvB,IAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF,EAA2D;AACzD,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,CAAA,gBAAA,EAAmB,IAAI,CAAA,CAAA,EAAI,SAAS,IAAI,IAAI,CAAA,CAAA;AAE7C,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,4GAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,KAAA,CAAA;AAAA,QACT;AACE,UAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,YACV,qBAAqB,IAAI,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,IAAI,KAAK,IAAA,CAAK,SAAA;AAAA,cACtD,YAAA,CAAa;AAAA,aACd,CAAA;AAAA,WACH;AAEA,UAAA,OAAO;AAAA,YACL,SAAA,EAAW,aAAa,OAAA,CAAQ,SAAA;AAAA,YAChC,cAAA,EAAgB,aAAa,OAAA,CAAQ,cAAA;AAAA,YACrC,SAAA,EAAW,aAAa,OAAA,CAAQ,SAAA;AAAA,YAChC,OAAA,EAAS,aAAa,OAAA,CAAQ;AAAA,WAChC;AAAA;AACJ,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,kCAAkC,IAAI,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,IAAI,KAAK,KAAK,CAAA;AAAA,OACvE;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,kCAAkC,IAAI,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,IAAI,KAAK,KAAK,CAAA;AAAA,OACvE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,uBACJ,SAAA,EACoC;AACpC,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,2BAA2B,SAAS,CAAA,CAAA;AAErC,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,kHAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,KAAA,CAAA;AAAA,QACT;AACE,UAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,YACV,CAAA,4BAAA,EAA+B,SAAS,CAAA,EAAA,EAAK,IAAA,CAAK,SAAA;AAAA,cAChD,YAAA,CAAa;AAAA,aACd,CAAA;AAAA,WACH;AAEA,UAAA,OAAO;AAAA,YACL,SAAA,EAAW,aAAa,OAAA,CAAQ,SAAA;AAAA,YAChC,cAAA,EAAgB,aAAa,OAAA,CAAQ,cAAA;AAAA,YACrC,SAAA,EAAW,aAAa,OAAA,CAAQ,SAAA;AAAA,YAChC,OAAA,EAAS,aAAa,OAAA,CAAQ;AAAA,WAChC;AAAA;AACJ,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,yCAAA,EAA4C,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACjE;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,yCAAA,EAA4C,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACjE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,OAAA,EAAgD;AACzE,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B,OACxD;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,OAAO;AAAA,KAC9B;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,CAAA,eAAA,CAAA;AAED,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,2GAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,MACvC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,0BAAA,EAA6B,OAAA,CAAQ,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC1D;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,0BAAA,EAA6B,OAAA,CAAQ,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC1D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,sBAAA,CACJ,SAAA,EACA,OAAA,EACuC;AACvC,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAChC;AAAA,KACD,yBAAyB,SAAS,CAAA,CAAA;AAEnC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,CAAA,SAAA,EAAY,OAAO,CAAA,CAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,yHAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,iBAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,EAAC;AAAA,QACV;AACE,UAAA,OAAO,iBAAA,CAAkB,aAAA;AAAA;AAC7B,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,+BAAA,EAAkC,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACvD;AACA,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkC,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAA;AAAA,IACzE;AAAA,EACF;AAAA,EAEA,MAAM,kCAAkC,SAAA,EAAoC;AAC1E,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAGA,IAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,SAAA,CAAU,MAAM,GAAG,CAAA;AACxC,IAAA,MAAM,CAAC,SAAA,EAAW,IAAI,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAExC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,CAAA,gBAAA,EAAmB,IAAI,CAAA,CAAA,EAAI,SAAS,IAAI,IAAI,CAAA,CAAA;AAE7C,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,8HAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,cAAA,GAAyB,MAAM,QAAA,CAAS,IAAA,EAAK;AAEnD,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,EAAA;AAAA,QACT;AACE,UAAA,OAAO,cAAA;AAAA;AACX,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,8CAAA,EAAiD,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACtE;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,8CAAA,EAAiD,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACtE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,8BAAA,CACJ,cAAA,EACA,OAAA,EACiB;AACjB,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAChC;AAAA,KACD,6BAA6B,cAAc,CAAA,CAAA;AAE5C,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,CAAA,SAAA,EAAY,OAAO,CAAA,CAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,iDAAiD,cAAc,CAAA,wFAAA;AAAA,SACjE;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GAAyC,MAAM,QAAA,CAAS,IAAA,EAAK;AAEnE,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,EAAA;AAAA,QACT;AACE,UAAA,OAAO,aAAa,OAAA,CAAQ,EAAA;AAAA;AAChC,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,8DAAA,EAAiE,cAAc,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC3F;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,8DAAA,EAAiE,cAAc,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC3F;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,8BAAA,CACJ,SAAA,EACA,OAAA,EAC6B;AAC7B,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAChC;AAAA,KACD,aAAa,SAAS,CAAA,CAAA;AAEvB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,GAAA,GAAM,GAAA,CAAI,MAAA,CAAO,CAAA,SAAA,EAAY,OAAO,CAAA,CAAE,CAAA;AAAA,IACxC;AAEA,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,iDAAiD,SAAS,CAAA,wFAAA;AAAA,SAC5D;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GAAyC,MAAM,QAAA,CAAS,IAAA,EAAK;AACnE,MAAA,MAAM,oBAAA,GAAuB,YAAA,CAAa,OAAA,CAAQ,YAAA,EAAc,IAAA;AAAA,QAC9D,CAAA,WAAA,KAAe,WAAA,CAAY,MAAA,EAAQ,EAAA,KAAO;AAAA,OAC5C;AAEA,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,EAAA;AAAA,QACT;AACE,UAAA,IAAI,CAAC,oBAAA,EAAsB;AACzB,YAAA,OAAO,KAAA,CAAA;AAAA,UACT;AAEA,UAAA,OAAO,oBAAA,CAAqB,eAAA;AAAA;AAChC,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,8CAAA,EAAiD,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACtE;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,8CAAA,EAAiD,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OACtE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mCAAA,GAAuD;AAC3D,IAAA,MAAM,gCAAA,GACJ,4CAAA;AAEF,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,YAAY,EAAA,EAAI;AACvB,MAAA,IAAA,CAAK,OAAA,GAAU,MAAM,IAAA,CAAK,SAAA,CAAU,WAAW,WAAW,CAAA;AAAA,IAC5D;AAEA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,iCAAA;AAAA,QAChB,MAAA,EAAQ,mCAAA;AAAA,QACR,aAAA,EAAe,MAAM,IAAA,CAAK,2BAAA;AAA4B;AACxD,KACF;AAEA,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,IAAA,CAAK,SAAA,CAAU,UAAA;AAAA,MAClC;AAAA,KACD,aAAa,gCAAgC,CAAA,CAAA;AAE9C,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAA,EAAK,OAAO,CAAA;AAE9C,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,sHAAA;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAA4B,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtD,MAAA,QAAQ,SAAS,MAAA;AAAQ,QACvB,KAAK,GAAA;AACH,UAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA,QACvC,KAAK,GAAA;AACH,UAAA,OAAO,UAAA;AAAA;AAAA,QACT;AACE,UAAA,OAAO,OAAA,CAAQ,KAAA;AAAA;AACnB,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,iCAAA,EAAoC,KAAK,CAAA,CAAE,CAAA;AAC7D,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,KAAK,CAAA,CAAE,CAAA;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,MAAc,2BAAA,GAA+C;AAC3D,IAAA,IAAA,CAAK,MAAA,CAAO,MAAM,iDAAiD,CAAA;AAEnE,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,KAAK,qBAAA,CAAsB;AAAA,MACtD,UAAA,EAAY,MAAM,IAAA,CAAK,IAAA,CAAK,wBAAA,EAAyB;AAAA,MACrD,cAAA,EAAgB;AAAA,KACjB,CAAA;AAED,IAAA,OAAO,UAAU,KAAK,CAAA,CAAA;AAAA,EACxB;AACF;AAEA,eAAsB,gBAAA,CACpB,KACA,OAAA,EACmB;AACnB,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,KAAA,GAAe,IAAI,KAAA,EAAM;AAG7B,EAAA,MAAM,UAAA,GAAa,CAAA;AACnB,EAAA,MAAM,KAAA,GAAQ,GAAA;AACd,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,EAAY,CAAA,EAAA,EAAK;AACnC,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAMA,sBAAA,CAAM,GAAA,EAAK,OAAO,CAAA;AACnC,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,CAAA,EAAG;AACV,MAAA,KAAA,GAAQ,CAAA;AAAA,IACV;AAEA,IAAA,MAAM,UAAU,KAAA,GAAQ,MAAA;AACxB,IAAA,MAAM,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,UAAA,CAAW,OAAA,EAAS,OAAO,CAAC,CAAA;AACzD,IAAA,MAAA,IAAU,CAAA;AAAA,EACZ;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,2BAAA,EAA8B,UAAU,CAAA,sBAAA,EAAyB,KAAK,CAAA;AAAA,GACxE;AACF;;;;;"}
|
package/dist/module.cjs.js
CHANGED
|
@@ -12,10 +12,13 @@ const pagerDutyEntityProcessor = backendPluginApi.createBackendModule({
|
|
|
12
12
|
deps: {
|
|
13
13
|
logger: backendPluginApi.coreServices.logger,
|
|
14
14
|
catalog: alpha.catalogProcessingExtensionPoint,
|
|
15
|
-
discovery: backendPluginApi.coreServices.discovery
|
|
15
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
16
|
+
auth: backendPluginApi.coreServices.auth
|
|
16
17
|
},
|
|
17
|
-
async init({ logger, discovery, catalog }) {
|
|
18
|
-
catalog.addProcessor(
|
|
18
|
+
async init({ auth, logger, discovery, catalog }) {
|
|
19
|
+
catalog.addProcessor(
|
|
20
|
+
new PagerDutyEntityProcessor.PagerDutyEntityProcessor({ auth, logger, discovery })
|
|
21
|
+
);
|
|
19
22
|
}
|
|
20
23
|
});
|
|
21
24
|
}
|
package/dist/module.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["import {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { PagerDutyEntityProcessor } from './processor';\n\n/** @public */\nexport const pagerDutyEntityProcessor = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'pagerduty-entity-processor',\n register(env) {\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n catalog: catalogProcessingExtensionPoint,\n discovery: coreServices.discovery,\n auth: coreServices.auth,\n },\n async init({ auth, logger, discovery, catalog }) {\n catalog.addProcessor(\n new PagerDutyEntityProcessor({ auth, logger, discovery }),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","coreServices","catalogProcessingExtensionPoint","PagerDutyEntityProcessor"],"mappings":";;;;;;AAQO,MAAM,2BAA2BA,oCAAA,CAAoB;AAAA,EAC1D,QAAA,EAAU,SAAA;AAAA,EACV,QAAA,EAAU,4BAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,QAAQC,6BAAA,CAAa,MAAA;AAAA,QACrB,OAAA,EAASC,qCAAA;AAAA,QACT,WAAWD,6BAAA,CAAa,SAAA;AAAA,QACxB,MAAMA,6BAAA,CAAa;AAAA,OACrB;AAAA,MACA,MAAM,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,SAAA,EAAW,SAAQ,EAAG;AAC/C,QAAA,OAAA,CAAQ,YAAA;AAAA,UACN,IAAIE,iDAAA,CAAyB,EAAE,IAAA,EAAM,MAAA,EAAQ,WAAW;AAAA,SAC1D;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
|
|
@@ -8,13 +8,19 @@ let client;
|
|
|
8
8
|
class PagerDutyEntityProcessor {
|
|
9
9
|
logger;
|
|
10
10
|
discovery;
|
|
11
|
+
auth;
|
|
11
12
|
shouldProcessEntity = (entity) => {
|
|
12
13
|
return entity.kind === "Component";
|
|
13
14
|
};
|
|
14
|
-
constructor({ logger, discovery }) {
|
|
15
|
+
constructor({ auth, logger, discovery }) {
|
|
15
16
|
this.logger = logger;
|
|
16
17
|
this.discovery = discovery;
|
|
17
|
-
|
|
18
|
+
this.auth = auth;
|
|
19
|
+
client = new client$1.PagerDutyClient({
|
|
20
|
+
auth: this.auth,
|
|
21
|
+
discovery: this.discovery,
|
|
22
|
+
logger: this.logger
|
|
23
|
+
});
|
|
18
24
|
}
|
|
19
25
|
getProcessorName() {
|
|
20
26
|
return "PagerDutyEntityProcessor";
|
|
@@ -39,17 +45,18 @@ class PagerDutyEntityProcessor {
|
|
|
39
45
|
name: entity.metadata.name.toLowerCase()
|
|
40
46
|
});
|
|
41
47
|
if (mapping) {
|
|
42
|
-
updateAnnotations(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
48
|
+
updateAnnotations(entity, {
|
|
49
|
+
serviceId: mapping.serviceId,
|
|
50
|
+
integrationKey: mapping.integrationKey,
|
|
51
|
+
account: mapping.account
|
|
52
|
+
});
|
|
53
|
+
this.logger.debug(
|
|
54
|
+
`Added annotations to entity ${entity.metadata.name} with service id: ${mapping.serviceId}, integration key: ${mapping.integrationKey} and account: ${mapping.account}`
|
|
49
55
|
);
|
|
50
|
-
this.logger.debug(`Added annotations to entity ${entity.metadata.name} with service id: ${mapping.serviceId}, integration key: ${mapping.integrationKey} and account: ${mapping.account}`);
|
|
51
56
|
} else {
|
|
52
|
-
this.logger.debug(
|
|
57
|
+
this.logger.debug(
|
|
58
|
+
`No mapping found for entity: ${entity.metadata.name}. Adding annotations to the database.`
|
|
59
|
+
);
|
|
53
60
|
let serviceId2 = entity.metadata.annotations?.["pagerduty.com/service-id"];
|
|
54
61
|
let integrationKey = entity.metadata.annotations?.["pagerduty.com/integration-key"];
|
|
55
62
|
const account = entity.metadata.annotations?.["pagerduty.com/account"];
|
|
@@ -58,51 +65,59 @@ class PagerDutyEntityProcessor {
|
|
|
58
65
|
const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId2);
|
|
59
66
|
if (!serviceMappingOverrideFound) {
|
|
60
67
|
if (!integrationKey) {
|
|
61
|
-
const foundIntegrationKey = await client.getIntegrationKeyFromServiceId(
|
|
68
|
+
const foundIntegrationKey = await client.getIntegrationKeyFromServiceId(
|
|
69
|
+
serviceId2,
|
|
70
|
+
account
|
|
71
|
+
);
|
|
62
72
|
if (foundIntegrationKey) {
|
|
63
73
|
integrationKey = foundIntegrationKey;
|
|
64
74
|
}
|
|
65
75
|
}
|
|
66
|
-
this.logger.debug(
|
|
76
|
+
this.logger.debug(
|
|
77
|
+
`Inserting mapping for entity: ${entityRef} with service id: ${serviceId2}, integration key: ${integrationKey} and account: ${account}`
|
|
78
|
+
);
|
|
67
79
|
await client.insertServiceMapping({
|
|
68
80
|
entityRef,
|
|
69
81
|
serviceId: serviceId2,
|
|
70
82
|
integrationKey,
|
|
71
83
|
account
|
|
72
84
|
});
|
|
73
|
-
updateAnnotations(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
account
|
|
79
|
-
}
|
|
80
|
-
);
|
|
85
|
+
updateAnnotations(entity, {
|
|
86
|
+
serviceId: serviceId2,
|
|
87
|
+
integrationKey,
|
|
88
|
+
account
|
|
89
|
+
});
|
|
81
90
|
} else {
|
|
82
|
-
this.logger.debug(
|
|
91
|
+
this.logger.debug(
|
|
92
|
+
`Service mapping override found for service id: ${serviceId2}.`
|
|
93
|
+
);
|
|
83
94
|
updateAnnotations(entity, {});
|
|
84
95
|
}
|
|
85
96
|
} else if (integrationKey) {
|
|
86
|
-
serviceId2 = await client.getServiceIdFromIntegrationKey(
|
|
97
|
+
serviceId2 = await client.getServiceIdFromIntegrationKey(
|
|
98
|
+
integrationKey,
|
|
99
|
+
account
|
|
100
|
+
);
|
|
87
101
|
const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId2);
|
|
88
102
|
if (!serviceMappingOverrideFound) {
|
|
89
|
-
this.logger.debug(
|
|
103
|
+
this.logger.debug(
|
|
104
|
+
`Inserting mapping for entity: ${entityRef} with new service id: ${serviceId2}, integration key: ${integrationKey} and account: ${account}`
|
|
105
|
+
);
|
|
90
106
|
await client.insertServiceMapping({
|
|
91
107
|
entityRef,
|
|
92
108
|
serviceId: serviceId2,
|
|
93
109
|
integrationKey,
|
|
94
110
|
account
|
|
95
111
|
});
|
|
96
|
-
updateAnnotations(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
account
|
|
102
|
-
}
|
|
103
|
-
);
|
|
112
|
+
updateAnnotations(entity, {
|
|
113
|
+
serviceId: serviceId2,
|
|
114
|
+
integrationKey,
|
|
115
|
+
account
|
|
116
|
+
});
|
|
104
117
|
} else {
|
|
105
|
-
this.logger.debug(
|
|
118
|
+
this.logger.debug(
|
|
119
|
+
`Service mapping override found for service id: ${serviceId2}. Skipping adding to the database.`
|
|
120
|
+
);
|
|
106
121
|
updateAnnotations(entity, {});
|
|
107
122
|
}
|
|
108
123
|
}
|
|
@@ -113,36 +128,82 @@ class PagerDutyEntityProcessor {
|
|
|
113
128
|
if (strategySetting && strategySetting !== "disabled") {
|
|
114
129
|
let dependencyAnnotations = [];
|
|
115
130
|
if (entity.spec?.dependsOn) {
|
|
116
|
-
dependencyAnnotations = JSON.parse(
|
|
131
|
+
dependencyAnnotations = JSON.parse(
|
|
132
|
+
JSON.stringify(entity.spec?.dependsOn)
|
|
133
|
+
);
|
|
117
134
|
}
|
|
118
135
|
const mappings = await client.getAllServiceMappings();
|
|
119
136
|
const entityDependencies = await buildExistingDependencies(dependencyAnnotations);
|
|
120
137
|
const account = entity.metadata.annotations?.["pagerduty.com/account"];
|
|
121
|
-
const dependencies = await client.getServiceDependencies(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
138
|
+
const dependencies = await client.getServiceDependencies(
|
|
139
|
+
serviceId,
|
|
140
|
+
account
|
|
141
|
+
);
|
|
142
|
+
const filteredDependencies = dependencies.filter(
|
|
143
|
+
(x) => x.dependent_service.id === serviceId
|
|
144
|
+
);
|
|
145
|
+
const dependencyIds = filteredDependencies.map(
|
|
146
|
+
(x) => x.supporting_service.id
|
|
147
|
+
);
|
|
148
|
+
const dependenciesMissingInBackstage = dependencyIds.filter(
|
|
149
|
+
(x) => !entityDependencies.includes(x)
|
|
150
|
+
);
|
|
151
|
+
const dependenciesMissingInPagerDuty = entityDependencies.filter(
|
|
152
|
+
(x) => !dependencyIds.includes(x)
|
|
153
|
+
);
|
|
126
154
|
switch (strategySetting) {
|
|
127
155
|
case "backstage":
|
|
128
156
|
if (dependenciesMissingInPagerDuty.length > 0) {
|
|
129
|
-
this.logger.debug(
|
|
130
|
-
|
|
157
|
+
this.logger.debug(
|
|
158
|
+
`Updating dependencies on PagerDuty with: ${JSON.stringify(
|
|
159
|
+
dependenciesMissingInPagerDuty
|
|
160
|
+
)}`
|
|
161
|
+
);
|
|
162
|
+
await client.addServiceRelationToService(
|
|
163
|
+
serviceId,
|
|
164
|
+
dependenciesMissingInPagerDuty
|
|
165
|
+
);
|
|
131
166
|
}
|
|
132
167
|
if (dependenciesMissingInBackstage.length > 0) {
|
|
133
|
-
this.logger.debug(
|
|
134
|
-
|
|
168
|
+
this.logger.debug(
|
|
169
|
+
`Removing dependencies on PagerDuty with: ${JSON.stringify(
|
|
170
|
+
dependenciesMissingInBackstage
|
|
171
|
+
)}`
|
|
172
|
+
);
|
|
173
|
+
await client.removeServiceRelationFromService(
|
|
174
|
+
serviceId,
|
|
175
|
+
dependenciesMissingInBackstage
|
|
176
|
+
);
|
|
135
177
|
}
|
|
136
178
|
break;
|
|
137
179
|
case "pagerduty":
|
|
138
|
-
entity.spec.dependsOn = refreshServiceDependencyAnnotations(
|
|
180
|
+
entity.spec.dependsOn = refreshServiceDependencyAnnotations(
|
|
181
|
+
entity,
|
|
182
|
+
mappings,
|
|
183
|
+
dependencyIds,
|
|
184
|
+
emit
|
|
185
|
+
);
|
|
139
186
|
break;
|
|
140
187
|
case "both":
|
|
141
|
-
this.logger.debug(
|
|
188
|
+
this.logger.debug(
|
|
189
|
+
`Updating dependencies on PagerDuty with: ${JSON.stringify(
|
|
190
|
+
dependenciesMissingInPagerDuty
|
|
191
|
+
)} and Backstage with: ${JSON.stringify(
|
|
192
|
+
dependenciesMissingInBackstage
|
|
193
|
+
)}`
|
|
194
|
+
);
|
|
142
195
|
if (dependenciesMissingInPagerDuty.length > 0) {
|
|
143
|
-
await client.addServiceRelationToService(
|
|
196
|
+
await client.addServiceRelationToService(
|
|
197
|
+
serviceId,
|
|
198
|
+
dependenciesMissingInPagerDuty
|
|
199
|
+
);
|
|
144
200
|
}
|
|
145
|
-
entity.spec.dependsOn = refreshServiceDependencyAnnotations(
|
|
201
|
+
entity.spec.dependsOn = refreshServiceDependencyAnnotations(
|
|
202
|
+
entity,
|
|
203
|
+
mappings,
|
|
204
|
+
dependencyIds,
|
|
205
|
+
emit
|
|
206
|
+
);
|
|
146
207
|
break;
|
|
147
208
|
default:
|
|
148
209
|
break;
|
|
@@ -150,7 +211,9 @@ class PagerDutyEntityProcessor {
|
|
|
150
211
|
}
|
|
151
212
|
}
|
|
152
213
|
} catch (error) {
|
|
153
|
-
this.logger.error(
|
|
214
|
+
this.logger.error(
|
|
215
|
+
`Error processing entity ${entity.metadata.name}: ${error}`
|
|
216
|
+
);
|
|
154
217
|
}
|
|
155
218
|
}
|
|
156
219
|
return entity;
|
|
@@ -167,32 +230,36 @@ function refreshServiceDependencyAnnotations(entity, mappingsDic, dependencies,
|
|
|
167
230
|
const namespaceName = entityRefParts[1].split("/");
|
|
168
231
|
const namespace = namespaceName[0];
|
|
169
232
|
const name = namespaceName[1];
|
|
170
|
-
emit(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
233
|
+
emit(
|
|
234
|
+
pluginCatalogNode.processingResult.relation({
|
|
235
|
+
source: {
|
|
236
|
+
kind: entity.kind,
|
|
237
|
+
namespace: entity.metadata.namespace,
|
|
238
|
+
name: entity.metadata.name
|
|
239
|
+
},
|
|
240
|
+
target: {
|
|
241
|
+
kind,
|
|
242
|
+
namespace,
|
|
243
|
+
name
|
|
244
|
+
},
|
|
245
|
+
type: catalogModel.RELATION_DEPENDS_ON
|
|
246
|
+
})
|
|
247
|
+
);
|
|
248
|
+
emit(
|
|
249
|
+
pluginCatalogNode.processingResult.relation({
|
|
250
|
+
source: {
|
|
251
|
+
kind,
|
|
252
|
+
namespace,
|
|
253
|
+
name
|
|
254
|
+
},
|
|
255
|
+
target: {
|
|
256
|
+
kind: entity.kind,
|
|
257
|
+
namespace: entity.metadata.namespace,
|
|
258
|
+
name: entity.metadata.name
|
|
259
|
+
},
|
|
260
|
+
type: catalogModel.RELATION_DEPENDENCY_OF
|
|
261
|
+
})
|
|
262
|
+
);
|
|
196
263
|
}
|
|
197
264
|
});
|
|
198
265
|
return dependencyList;
|
|
@@ -219,7 +286,9 @@ async function buildExistingDependencies(dependencyAnnotations) {
|
|
|
219
286
|
if (dependencyAnnotations.length > 0) {
|
|
220
287
|
await Promise.all(
|
|
221
288
|
dependencyAnnotations.map(async (dependency) => {
|
|
222
|
-
const foundServiceId = await client.getServiceIdAnnotationFromCatalog(
|
|
289
|
+
const foundServiceId = await client.getServiceIdAnnotationFromCatalog(
|
|
290
|
+
dependency
|
|
291
|
+
);
|
|
223
292
|
if (foundServiceId !== "") {
|
|
224
293
|
dependencies.push(foundServiceId);
|
|
225
294
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PagerDutyEntityProcessor.cjs.js","sources":["../../src/processor/PagerDutyEntityProcessor.ts"],"sourcesContent":["import { DiscoveryService, LoggerService } from \"@backstage/backend-plugin-api\";\nimport { Entity, RELATION_DEPENDS_ON, RELATION_DEPENDENCY_OF } from \"@backstage/catalog-model\";\nimport { CatalogProcessor, CatalogProcessorEmit, processingResult } from \"@backstage/plugin-catalog-node\";\nimport { LocationSpec } from \"@backstage/plugin-catalog-common\";\nimport { PagerDutyClient } from \"../apis/client\";\n\n/**\n * A function which given an entity, determines if it should be processed for linguist tags.\n * @public\n */\nexport type ShouldProcessEntity = (entity: Entity) => boolean;\n\nexport interface PagerDutyEntityProcessorOptions {\n logger: LoggerService;\n discovery: DiscoveryService;\n};\n\nlet client: PagerDutyClient;\n\nexport class PagerDutyEntityProcessor implements CatalogProcessor {\n private logger: LoggerService;\n private discovery: DiscoveryService;\n\n private shouldProcessEntity: ShouldProcessEntity = (entity: Entity) => {\n return entity.kind === 'Component';\n }\n\n constructor({ logger, discovery }: PagerDutyEntityProcessorOptions) {\n this.logger = logger;\n this.discovery = discovery;\n\n client = new PagerDutyClient({ discovery: this.discovery, logger: this.logger });\n }\n\n getProcessorName(): string {\n return \"PagerDutyEntityProcessor\";\n }\n\n async preProcessEntity(entity: Entity): Promise<Entity> {\n if (this.shouldProcessEntity(entity)) {\n const strategySetting = await client.getServiceDependencyStrategySetting();\n\n if (strategySetting && strategySetting === \"pagerduty\") {\n if (entity.spec?.dependsOn){\n // empty the dependsOn array\n entity.spec.dependsOn = [];\n }\n }\n }\n\n return entity;\n }\n\n async postProcessEntity(entity: Entity, _location: LocationSpec, emit: CatalogProcessorEmit): Promise<Entity> {\n if (this.shouldProcessEntity(entity)) {\n try {\n // Process service mapping overrides\n // Find the service mapping for the entity in database\n const mapping = await client.findServiceMapping({\n type: entity.kind.toLowerCase(),\n namespace: entity.metadata.namespace!.toLowerCase(),\n name: entity.metadata.name.toLowerCase(),\n });\n\n // If mapping exists add the annotations to the entity\n if (mapping) {\n updateAnnotations(entity,\n {\n serviceId: mapping.serviceId,\n integrationKey: mapping.integrationKey,\n account: mapping.account\n }\n );\n\n this.logger.debug(`Added annotations to entity ${entity.metadata.name} with service id: ${mapping.serviceId}, integration key: ${mapping.integrationKey} and account: ${mapping.account}`);\n } else {\n this.logger.debug(`No mapping found for entity: ${entity.metadata.name}. Adding annotations to the database.`);\n\n // Add the mapping to the database based on entity annotations\n let serviceId = entity.metadata.annotations?.[\"pagerduty.com/service-id\"];\n let integrationKey = entity.metadata.annotations?.[\"pagerduty.com/integration-key\"];\n const account = entity.metadata.annotations?.[\"pagerduty.com/account\"];\n\n // Build the entityRef string\n const entityRef = `${entity.kind.toLowerCase()}:${entity.metadata.namespace?.toLowerCase()}/${entity.metadata.name.toLowerCase()}`;\n\n if (serviceId) {\n // Check for mapping override by user\n const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId);\n\n // If service mapping override is not found\n // insert the mapping into the database\n if (!serviceMappingOverrideFound) {\n // if integrationKey annotation does not exist\n // try to retrieve it from PagerDuty\n if (!integrationKey) {\n const foundIntegrationKey = await client.getIntegrationKeyFromServiceId(serviceId, account);\n\n if (foundIntegrationKey) {\n integrationKey = foundIntegrationKey;\n }\n }\n\n // Insert the mapping into the database\n this.logger.debug(`Inserting mapping for entity: ${entityRef} with service id: ${serviceId}, integration key: ${integrationKey} and account: ${account}`);\n await client.insertServiceMapping({\n entityRef,\n serviceId,\n integrationKey,\n account,\n });\n\n // Add the annotations to the entity\n updateAnnotations(entity,\n {\n serviceId,\n integrationKey,\n account\n }\n );\n }\n else {\n this.logger.debug(`Service mapping override found for service id: ${serviceId}.`);\n updateAnnotations(entity, {}); // delete annotations because user unmapped the service\n }\n }\n else if (integrationKey) {\n serviceId = await client.getServiceIdFromIntegrationKey(integrationKey, account);\n\n // Check for mapping override by user\n const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId);\n\n // If service mapping override is not found\n // insert the mapping into the database\n if (!serviceMappingOverrideFound) {\n // Insert the mapping into the database\n this.logger.debug(`Inserting mapping for entity: ${entityRef} with new service id: ${serviceId}, integration key: ${integrationKey} and account: ${account}`);\n await client.insertServiceMapping({\n entityRef,\n serviceId,\n integrationKey,\n account,\n });\n\n updateAnnotations(entity,\n {\n serviceId,\n integrationKey,\n account\n }\n );\n }\n else {\n this.logger.debug(`Service mapping override found for service id: ${serviceId}. Skipping adding to the database.`);\n updateAnnotations(entity, {}); // delete annotations because user unmapped the service\n }\n }\n }\n\n // Process service dependencies\n // if (entity.spec?.dependsOn) {\n // Check if ServiceId exists get service dependencies from PagerDuty \n const serviceId = entity.metadata.annotations?.[\"pagerduty.com/service-id\"];\n\n if (serviceId) {\n const strategySetting = await client.getServiceDependencyStrategySetting();\n\n if (strategySetting && strategySetting !== \"disabled\") {\n // Check if service has dependencies configured\n let dependencyAnnotations: string[] = [];\n\n if (entity.spec?.dependsOn) {\n dependencyAnnotations = JSON.parse(JSON.stringify(entity.spec?.dependsOn));\n }\n\n const mappings = await client.getAllServiceMappings();\n\n const entityDependencies: string[] = await buildExistingDependencies(dependencyAnnotations);\n\n // Get dependencies from PagerDuty for the service\n const account = entity.metadata.annotations?.[\"pagerduty.com/account\"];\n const dependencies = await client.getServiceDependencies(serviceId, account);\n const filteredDependencies = dependencies.filter(x => x.dependent_service.id === serviceId);\n const dependencyIds = filteredDependencies.map(x => x.supporting_service.id);\n\n // compare dependencies with existing dependencies defined on the entity\n const dependenciesMissingInBackstage = dependencyIds.filter(x => !entityDependencies.includes(x));\n const dependenciesMissingInPagerDuty = entityDependencies.filter(x => !dependencyIds.includes(x));\n\n switch (strategySetting) {\n case \"backstage\":\n // Update dependencies on PagerDuty with dependenciesMissinginPagerDuty\n // Add dependency associations in PagerDuty\n if (dependenciesMissingInPagerDuty.length > 0) {\n this.logger.debug(`Updating dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInPagerDuty)}`);\n await client.addServiceRelationToService(serviceId, dependenciesMissingInPagerDuty);\n }\n\n // Remove dependency associations in PagerDuty\n if (dependenciesMissingInBackstage.length > 0) {\n this.logger.debug(`Removing dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInBackstage)}`);\n await client.removeServiceRelationFromService(serviceId, dependenciesMissingInBackstage);\n }\n\n break;\n case \"pagerduty\":\n // Update dependencies on Backstage with dependenciesMissingInBackstage\n \n // !!!\n // This is not supported yet due to a limitation on Backstage side\n // that prevents a full override of the dependencies once they are\n // set on the entity configuration file\n // !!!\n\n entity.spec!.dependsOn = refreshServiceDependencyAnnotations(entity, mappings, dependencyIds, emit);\n\n break;\n case \"both\":\n // Update dependencies in both PagerDuty and Backstage\n this.logger.debug(`Updating dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInPagerDuty)} and Backstage with: ${JSON.stringify(dependenciesMissingInBackstage)}`);\n\n // Add missing dependencies to PagerDuty\n if (dependenciesMissingInPagerDuty.length > 0) {\n await client.addServiceRelationToService(serviceId, dependenciesMissingInPagerDuty);\n }\n\n // Add missing dependencies to Backstage\n entity.spec!.dependsOn = refreshServiceDependencyAnnotations(entity, mappings, dependencyIds, emit);\n\n break;\n default:\n // Do nothing. Strategy not defined or set to disabled\n break;\n }\n }\n }\n\n } catch (error) {\n this.logger.error(`Error processing entity ${entity.metadata.name}: ${error}`);\n }\n }\n\n return entity;\n }\n}\n\nexport function refreshServiceDependencyAnnotations(entity: Entity, mappingsDic: Record<string, string>, dependencies: string[], emit: CatalogProcessorEmit): string[] {\n const dependencyList: string[] = [];\n dependencies.forEach((dependencyId) => {\n const foundEntityRef = mappingsDic[dependencyId];\n\n if (foundEntityRef && foundEntityRef !== \"\") {\n dependencyList.push(foundEntityRef);\n\n const entityRefParts = foundEntityRef.split(\":\");\n const kind = entityRefParts[0];\n const namespaceName = entityRefParts[1].split(\"/\");\n const namespace = namespaceName[0];\n const name = namespaceName[1];\n\n emit(processingResult.relation({\n source: {\n kind: entity.kind,\n namespace: entity.metadata.namespace!,\n name: entity.metadata.name,\n },\n target: {\n kind: kind,\n namespace: namespace,\n name: name,\n },\n type: RELATION_DEPENDS_ON,\n }));\n \n emit(processingResult.relation({\n source: {\n kind: kind,\n namespace: namespace,\n name: name,\n },\n target: {\n kind: entity.kind,\n namespace: entity.metadata.namespace!,\n name: entity.metadata.name,\n },\n type: RELATION_DEPENDENCY_OF,\n }));\n }\n });\n\n return dependencyList;\n}\n\nexport type AnnotationUpdateProps = {\n serviceId?: string;\n integrationKey?: string;\n account?: string;\n};\n\nfunction updateAnnotations(entity: Entity, annotations: AnnotationUpdateProps): void {\n // If serviceId is present, add the annotations to the entity\n if (annotations.serviceId && annotations.serviceId !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/service-id\"] = annotations.serviceId;\n }\n else {\n delete entity.metadata.annotations![\"pagerduty.com/service-id\"];\n }\n\n // If integrationKey is present, add the annotations to the entity\n if (annotations.integrationKey && annotations.integrationKey !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/integration-key\"] = annotations.integrationKey;\n }\n else {\n delete entity.metadata.annotations![\"pagerduty.com/integration-key\"];\n }\n\n // If account is present, add the annotations to the entity\n if (annotations.account && annotations.account !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/account\"] = annotations.account;\n }\n else {\n delete entity.metadata.annotations![\"pagerduty.com/account\"];\n }\n}\n\nasync function buildExistingDependencies(dependencyAnnotations: string[]): Promise<string[]> {\n const dependencies: string[] = [];\n\n // Get all service ids matching the dependency annotations\n if (dependencyAnnotations.length > 0) {\n await Promise.all(\n dependencyAnnotations.map(async (dependency) => {\n const foundServiceId = await client.getServiceIdAnnotationFromCatalog(dependency);\n\n if (foundServiceId !== \"\") {\n dependencies.push(foundServiceId);\n }\n })\n );\n }\n\n return dependencies;\n\n}"],"names":["PagerDutyClient","serviceId","processingResult","RELATION_DEPENDS_ON","RELATION_DEPENDENCY_OF"],"mappings":";;;;;;AAiBA,IAAI,MAAA;AAEG,MAAM,wBAAA,CAAqD;AAAA,EACtD,MAAA;AAAA,EACA,SAAA;AAAA,EAEA,mBAAA,GAA2C,CAAC,MAAA,KAAmB;AACnE,IAAA,OAAO,OAAO,IAAA,KAAS,WAAA;AAAA,EAC3B,CAAA;AAAA,EAEA,WAAA,CAAY,EAAE,MAAA,EAAQ,SAAA,EAAU,EAAoC;AAChE,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAEjB,IAAA,MAAA,GAAS,IAAIA,yBAAgB,EAAE,SAAA,EAAW,KAAK,SAAA,EAAW,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,EACnF;AAAA,EAEA,gBAAA,GAA2B;AACvB,IAAA,OAAO,0BAAA;AAAA,EACX;AAAA,EAEA,MAAM,iBAAiB,MAAA,EAAiC;AACpD,IAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,MAAM,CAAA,EAAG;AAClC,MAAA,MAAM,eAAA,GAAkB,MAAM,MAAA,CAAO,mCAAA,EAAoC;AAEzE,MAAA,IAAI,eAAA,IAAmB,oBAAoB,WAAA,EAAa;AACpD,QAAA,IAAI,MAAA,CAAO,MAAM,SAAA,EAAU;AAEvB,UAAA,MAAA,CAAO,IAAA,CAAK,YAAY,EAAC;AAAA,QAC7B;AAAA,MACJ;AAAA,IACJ;AAEA,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEA,MAAM,iBAAA,CAAkB,MAAA,EAAgB,SAAA,EAAyB,IAAA,EAA6C;AAC1G,IAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,MAAM,CAAA,EAAG;AAClC,MAAA,IAAI;AAGA,QAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,kBAAA,CAAmB;AAAA,UAC5C,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,WAAA,EAAY;AAAA,UAC9B,SAAA,EAAW,MAAA,CAAO,QAAA,CAAS,SAAA,CAAW,WAAA,EAAY;AAAA,UAClD,IAAA,EAAM,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,WAAA;AAAY,SAC1C,CAAA;AAGD,QAAA,IAAI,OAAA,EAAS;AACT,UAAA,iBAAA;AAAA,YAAkB,MAAA;AAAA,YACd;AAAA,cACI,WAAW,OAAA,CAAQ,SAAA;AAAA,cACnB,gBAAgB,OAAA,CAAQ,cAAA;AAAA,cACxB,SAAS,OAAA,CAAQ;AAAA;AACrB,WACJ;AAEA,UAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,4BAAA,EAA+B,MAAA,CAAO,SAAS,IAAI,CAAA,kBAAA,EAAqB,OAAA,CAAQ,SAAS,sBAAsB,OAAA,CAAQ,cAAc,CAAA,cAAA,EAAiB,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AAAA,QAC7L,CAAA,MAAO;AACH,UAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,6BAAA,EAAgC,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,qCAAA,CAAuC,CAAA;AAG7G,UAAA,IAAIC,UAAAA,GAAY,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,0BAA0B,CAAA;AACxE,UAAA,IAAI,cAAA,GAAiB,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,+BAA+B,CAAA;AAClF,UAAA,MAAM,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,uBAAuB,CAAA;AAGrE,UAAA,MAAM,YAAY,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,WAAA,EAAa,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,CAAS,SAAA,EAAW,aAAa,CAAA,CAAA,EAAI,OAAO,QAAA,CAAS,IAAA,CAAK,aAAa,CAAA,CAAA;AAEhI,UAAA,IAAIA,UAAAA,EAAW;AAEX,YAAA,MAAM,2BAAA,GAA8B,MAAM,MAAA,CAAO,sBAAA,CAAuBA,UAAS,CAAA;AAIjF,YAAA,IAAI,CAAC,2BAAA,EAA6B;AAG9B,cAAA,IAAI,CAAC,cAAA,EAAgB;AACjB,gBAAA,MAAM,mBAAA,GAAsB,MAAM,MAAA,CAAO,8BAAA,CAA+BA,YAAW,OAAO,CAAA;AAE1F,gBAAA,IAAI,mBAAA,EAAqB;AACrB,kBAAA,cAAA,GAAiB,mBAAA;AAAA,gBACrB;AAAA,cACJ;AAGA,cAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,8BAAA,EAAiC,SAAS,CAAA,kBAAA,EAAqBA,UAAS,CAAA,mBAAA,EAAsB,cAAc,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAE,CAAA;AACxJ,cAAA,MAAM,OAAO,oBAAA,CAAqB;AAAA,gBAC9B,SAAA;AAAA,gBACA,SAAA,EAAAA,UAAAA;AAAA,gBACA,cAAA;AAAA,gBACA;AAAA,eACH,CAAA;AAGD,cAAA,iBAAA;AAAA,gBAAkB,MAAA;AAAA,gBACd;AAAA,kBACI,SAAA,EAAAA,UAAAA;AAAA,kBACA,cAAA;AAAA,kBACA;AAAA;AACJ,eACJ;AAAA,YACJ,CAAA,MACK;AACD,cAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,+CAAA,EAAkDA,UAAS,CAAA,CAAA,CAAG,CAAA;AAChF,cAAA,iBAAA,CAAkB,MAAA,EAAQ,EAAE,CAAA;AAAA,YAChC;AAAA,UACJ,WACS,cAAA,EAAgB;AACrB,YAAAA,UAAAA,GAAY,MAAM,MAAA,CAAO,8BAAA,CAA+B,gBAAgB,OAAO,CAAA;AAG/E,YAAA,MAAM,2BAAA,GAA8B,MAAM,MAAA,CAAO,sBAAA,CAAuBA,UAAS,CAAA;AAIjF,YAAA,IAAI,CAAC,2BAAA,EAA6B;AAE9B,cAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,8BAAA,EAAiC,SAAS,CAAA,sBAAA,EAAyBA,UAAS,CAAA,mBAAA,EAAsB,cAAc,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAE,CAAA;AAC5J,cAAA,MAAM,OAAO,oBAAA,CAAqB;AAAA,gBAC9B,SAAA;AAAA,gBACA,SAAA,EAAAA,UAAAA;AAAA,gBACA,cAAA;AAAA,gBACA;AAAA,eACH,CAAA;AAED,cAAA,iBAAA;AAAA,gBAAkB,MAAA;AAAA,gBACd;AAAA,kBACI,SAAA,EAAAA,UAAAA;AAAA,kBACA,cAAA;AAAA,kBACA;AAAA;AACJ,eACJ;AAAA,YACJ,CAAA,MACK;AACD,cAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,+CAAA,EAAkDA,UAAS,CAAA,kCAAA,CAAoC,CAAA;AACjH,cAAA,iBAAA,CAAkB,MAAA,EAAQ,EAAE,CAAA;AAAA,YAChC;AAAA,UACJ;AAAA,QACJ;AAKA,QAAA,MAAM,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,0BAA0B,CAAA;AAE1E,QAAA,IAAI,SAAA,EAAW;AACX,UAAA,MAAM,eAAA,GAAkB,MAAM,MAAA,CAAO,mCAAA,EAAoC;AAEzE,UAAA,IAAI,eAAA,IAAmB,oBAAoB,UAAA,EAAY;AAEnD,YAAA,IAAI,wBAAkC,EAAC;AAEvC,YAAA,IAAI,MAAA,CAAO,MAAM,SAAA,EAAW;AACxB,cAAA,qBAAA,GAAwB,KAAK,KAAA,CAAM,IAAA,CAAK,UAAU,MAAA,CAAO,IAAA,EAAM,SAAS,CAAC,CAAA;AAAA,YAC7E;AAEA,YAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,qBAAA,EAAsB;AAEpD,YAAA,MAAM,kBAAA,GAA+B,MAAM,yBAAA,CAA0B,qBAAqB,CAAA;AAG1F,YAAA,MAAM,OAAA,GAAU,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,uBAAuB,CAAA;AACrE,YAAA,MAAM,YAAA,GAAe,MAAM,MAAA,CAAO,sBAAA,CAAuB,WAAW,OAAO,CAAA;AAC3E,YAAA,MAAM,uBAAuB,YAAA,CAAa,MAAA,CAAO,OAAK,CAAA,CAAE,iBAAA,CAAkB,OAAO,SAAS,CAAA;AAC1F,YAAA,MAAM,gBAAgB,oBAAA,CAAqB,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,mBAAmB,EAAE,CAAA;AAG3E,YAAA,MAAM,8BAAA,GAAiC,cAAc,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,kBAAA,CAAmB,QAAA,CAAS,CAAC,CAAC,CAAA;AAChG,YAAA,MAAM,8BAAA,GAAiC,mBAAmB,MAAA,CAAO,CAAA,CAAA,KAAK,CAAC,aAAA,CAAc,QAAA,CAAS,CAAC,CAAC,CAAA;AAEhG,YAAA,QAAQ,eAAA;AAAiB,cACrB,KAAK,WAAA;AAGD,gBAAA,IAAI,8BAAA,CAA+B,SAAS,CAAA,EAAG;AAC3C,kBAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,yCAAA,EAA4C,KAAK,SAAA,CAAU,8BAA8B,CAAC,CAAA,CAAE,CAAA;AAC9G,kBAAA,MAAM,MAAA,CAAO,2BAAA,CAA4B,SAAA,EAAW,8BAA8B,CAAA;AAAA,gBACtF;AAGA,gBAAA,IAAI,8BAAA,CAA+B,SAAS,CAAA,EAAG;AAC3C,kBAAA,IAAA,CAAK,OAAO,KAAA,CAAM,CAAA,yCAAA,EAA4C,KAAK,SAAA,CAAU,8BAA8B,CAAC,CAAA,CAAE,CAAA;AAC9G,kBAAA,MAAM,MAAA,CAAO,gCAAA,CAAiC,SAAA,EAAW,8BAA8B,CAAA;AAAA,gBAC3F;AAEA,gBAAA;AAAA,cACJ,KAAK,WAAA;AASD,gBAAA,MAAA,CAAO,KAAM,SAAA,GAAY,mCAAA,CAAoC,MAAA,EAAQ,QAAA,EAAU,eAAe,IAAI,CAAA;AAElG,gBAAA;AAAA,cACJ,KAAK,MAAA;AAED,gBAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,CAAA,yCAAA,EAA4C,IAAA,CAAK,SAAA,CAAU,8BAA8B,CAAC,CAAA,qBAAA,EAAwB,IAAA,CAAK,SAAA,CAAU,8BAA8B,CAAC,CAAA,CAAE,CAAA;AAGpL,gBAAA,IAAI,8BAAA,CAA+B,SAAS,CAAA,EAAG;AAC3C,kBAAA,MAAM,MAAA,CAAO,2BAAA,CAA4B,SAAA,EAAW,8BAA8B,CAAA;AAAA,gBACtF;AAGA,gBAAA,MAAA,CAAO,KAAM,SAAA,GAAY,mCAAA,CAAoC,MAAA,EAAQ,QAAA,EAAU,eAAe,IAAI,CAAA;AAElG,gBAAA;AAAA,cACJ;AAEI,gBAAA;AAAA;AACR,UACJ;AAAA,QACJ;AAAA,MAEJ,SAAS,KAAA,EAAO;AACZ,QAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,wBAAA,EAA2B,MAAA,CAAO,SAAS,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAA;AAAA,MACjF;AAAA,IACJ;AAEA,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEO,SAAS,mCAAA,CAAoC,MAAA,EAAgB,WAAA,EAAqC,YAAA,EAAwB,IAAA,EAAsC;AACnK,EAAA,MAAM,iBAA2B,EAAC;AAClC,EAAA,YAAA,CAAa,OAAA,CAAQ,CAAC,YAAA,KAAiB;AACnC,IAAA,MAAM,cAAA,GAAiB,YAAY,YAAY,CAAA;AAE/C,IAAA,IAAI,cAAA,IAAkB,mBAAmB,EAAA,EAAI;AACzC,MAAA,cAAA,CAAe,KAAK,cAAc,CAAA;AAElC,MAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,KAAA,CAAM,GAAG,CAAA;AAC/C,MAAA,MAAM,IAAA,GAAO,eAAe,CAAC,CAAA;AAC7B,MAAA,MAAM,aAAA,GAAgB,cAAA,CAAe,CAAC,CAAA,CAAE,MAAM,GAAG,CAAA;AACjD,MAAA,MAAM,SAAA,GAAY,cAAc,CAAC,CAAA;AACjC,MAAA,MAAM,IAAA,GAAO,cAAc,CAAC,CAAA;AAE5B,MAAA,IAAA,CAAKC,mCAAiB,QAAA,CAAS;AAAA,QAC3B,MAAA,EAAQ;AAAA,UACJ,MAAM,MAAA,CAAO,IAAA;AAAA,UACb,SAAA,EAAW,OAAO,QAAA,CAAS,SAAA;AAAA,UAC3B,IAAA,EAAM,OAAO,QAAA,CAAS;AAAA,SAC1B;AAAA,QACA,MAAA,EAAQ;AAAA,UACJ,IAAA;AAAA,UACA,SAAA;AAAA,UACA;AAAA,SACJ;AAAA,QACA,IAAA,EAAMC;AAAA,OACT,CAAC,CAAA;AAEF,MAAA,IAAA,CAAKD,mCAAiB,QAAA,CAAS;AAAA,QAC3B,MAAA,EAAQ;AAAA,UACJ,IAAA;AAAA,UACA,SAAA;AAAA,UACA;AAAA,SACJ;AAAA,QACA,MAAA,EAAQ;AAAA,UACJ,MAAM,MAAA,CAAO,IAAA;AAAA,UACb,SAAA,EAAW,OAAO,QAAA,CAAS,SAAA;AAAA,UAC3B,IAAA,EAAM,OAAO,QAAA,CAAS;AAAA,SAC1B;AAAA,QACA,IAAA,EAAME;AAAA,OACT,CAAC,CAAA;AAAA,IACN;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,OAAO,cAAA;AACX;AAQA,SAAS,iBAAA,CAAkB,QAAgB,WAAA,EAA0C;AAEjF,EAAA,IAAI,WAAA,CAAY,SAAA,IAAa,WAAA,CAAY,SAAA,KAAc,EAAA,EAAI;AACvD,IAAA,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,0BAA0B,CAAA,GAAI,WAAA,CAAY,SAAA;AAAA,EAC3E,CAAA,MACK;AACD,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,0BAA0B,CAAA;AAAA,EAClE;AAGA,EAAA,IAAI,WAAA,CAAY,cAAA,IAAkB,WAAA,CAAY,cAAA,KAAmB,EAAA,EAAI;AACjE,IAAA,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,+BAA+B,CAAA,GAAI,WAAA,CAAY,cAAA;AAAA,EAChF,CAAA,MACK;AACD,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,+BAA+B,CAAA;AAAA,EACvE;AAGA,EAAA,IAAI,WAAA,CAAY,OAAA,IAAW,WAAA,CAAY,OAAA,KAAY,EAAA,EAAI;AACnD,IAAA,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,uBAAuB,CAAA,GAAI,WAAA,CAAY,OAAA;AAAA,EACxE,CAAA,MACK;AACD,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,WAAA,CAAa,uBAAuB,CAAA;AAAA,EAC/D;AACJ;AAEA,eAAe,0BAA0B,qBAAA,EAAoD;AACzF,EAAA,MAAM,eAAyB,EAAC;AAGhC,EAAA,IAAI,qBAAA,CAAsB,SAAS,CAAA,EAAG;AAClC,IAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,MACV,qBAAA,CAAsB,GAAA,CAAI,OAAO,UAAA,KAAe;AAC5C,QAAA,MAAM,cAAA,GAAiB,MAAM,MAAA,CAAO,iCAAA,CAAkC,UAAU,CAAA;AAEhF,QAAA,IAAI,mBAAmB,EAAA,EAAI;AACvB,UAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAAA,QACpC;AAAA,MACJ,CAAC;AAAA,KACL;AAAA,EACJ;AAEA,EAAA,OAAO,YAAA;AAEX;;;;;"}
|
|
1
|
+
{"version":3,"file":"PagerDutyEntityProcessor.cjs.js","sources":["../../src/processor/PagerDutyEntityProcessor.ts"],"sourcesContent":["import { AuthService, DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';\nimport {\n Entity,\n RELATION_DEPENDS_ON,\n RELATION_DEPENDENCY_OF,\n} from '@backstage/catalog-model';\nimport {\n CatalogProcessor,\n CatalogProcessorEmit,\n processingResult,\n} from '@backstage/plugin-catalog-node';\nimport { LocationSpec } from '@backstage/plugin-catalog-common';\nimport { PagerDutyClient } from '../apis/client';\n\n/**\n * A function which given an entity, determines if it should be processed for linguist tags.\n * @public\n */\nexport type ShouldProcessEntity = (entity: Entity) => boolean;\n\nexport interface PagerDutyEntityProcessorOptions {\n logger: LoggerService;\n discovery: DiscoveryService;\n auth: AuthService,\n}\n\nlet client: PagerDutyClient;\n\nexport class PagerDutyEntityProcessor implements CatalogProcessor {\n private logger: LoggerService;\n private discovery: DiscoveryService;\n private auth: AuthService;\n\n private shouldProcessEntity: ShouldProcessEntity = (entity: Entity) => {\n return entity.kind === 'Component';\n };\n\n constructor({ auth, logger, discovery }: PagerDutyEntityProcessorOptions) {\n this.logger = logger;\n this.discovery = discovery;\n this.auth = auth;\n\n client = new PagerDutyClient({\n auth: this.auth,\n discovery: this.discovery,\n logger: this.logger,\n });\n }\n\n getProcessorName(): string {\n return 'PagerDutyEntityProcessor';\n }\n\n async preProcessEntity(entity: Entity): Promise<Entity> {\n if (this.shouldProcessEntity(entity)) {\n const strategySetting =\n await client.getServiceDependencyStrategySetting();\n\n if (strategySetting && strategySetting === 'pagerduty') {\n if (entity.spec?.dependsOn) {\n // empty the dependsOn array\n entity.spec.dependsOn = [];\n }\n }\n }\n\n return entity;\n }\n\n async postProcessEntity(\n entity: Entity,\n _location: LocationSpec,\n emit: CatalogProcessorEmit,\n ): Promise<Entity> {\n if (this.shouldProcessEntity(entity)) {\n try {\n // Process service mapping overrides\n // Find the service mapping for the entity in database\n const mapping = await client.findServiceMapping({\n type: entity.kind.toLowerCase(),\n namespace: entity.metadata.namespace!.toLowerCase(),\n name: entity.metadata.name.toLowerCase(),\n });\n\n // If mapping exists add the annotations to the entity\n if (mapping) {\n updateAnnotations(entity, {\n serviceId: mapping.serviceId,\n integrationKey: mapping.integrationKey,\n account: mapping.account,\n });\n\n this.logger.debug(\n `Added annotations to entity ${entity.metadata.name} with service id: ${mapping.serviceId}, integration key: ${mapping.integrationKey} and account: ${mapping.account}`,\n );\n } else {\n this.logger.debug(\n `No mapping found for entity: ${entity.metadata.name}. Adding annotations to the database.`,\n );\n\n // Add the mapping to the database based on entity annotations\n let serviceId =\n entity.metadata.annotations?.['pagerduty.com/service-id'];\n let integrationKey =\n entity.metadata.annotations?.['pagerduty.com/integration-key'];\n const account =\n entity.metadata.annotations?.['pagerduty.com/account'];\n\n // Build the entityRef string\n const entityRef = `${entity.kind.toLowerCase()}:${entity.metadata.namespace?.toLowerCase()}/${entity.metadata.name.toLowerCase()}`;\n\n if (serviceId) {\n // Check for mapping override by user\n const serviceMappingOverrideFound =\n await client.findServiceMappingById(serviceId);\n\n // If service mapping override is not found\n // insert the mapping into the database\n if (!serviceMappingOverrideFound) {\n // if integrationKey annotation does not exist\n // try to retrieve it from PagerDuty\n if (!integrationKey) {\n const foundIntegrationKey =\n await client.getIntegrationKeyFromServiceId(\n serviceId,\n account,\n );\n\n if (foundIntegrationKey) {\n integrationKey = foundIntegrationKey;\n }\n }\n\n // Insert the mapping into the database\n this.logger.debug(\n `Inserting mapping for entity: ${entityRef} with service id: ${serviceId}, integration key: ${integrationKey} and account: ${account}`,\n );\n await client.insertServiceMapping({\n entityRef,\n serviceId,\n integrationKey,\n account,\n });\n\n // Add the annotations to the entity\n updateAnnotations(entity, {\n serviceId,\n integrationKey,\n account,\n });\n } else {\n this.logger.debug(\n `Service mapping override found for service id: ${serviceId}.`,\n );\n updateAnnotations(entity, {}); // delete annotations because user unmapped the service\n }\n } else if (integrationKey) {\n serviceId = await client.getServiceIdFromIntegrationKey(\n integrationKey,\n account,\n );\n\n // Check for mapping override by user\n const serviceMappingOverrideFound =\n await client.findServiceMappingById(serviceId);\n\n // If service mapping override is not found\n // insert the mapping into the database\n if (!serviceMappingOverrideFound) {\n // Insert the mapping into the database\n this.logger.debug(\n `Inserting mapping for entity: ${entityRef} with new service id: ${serviceId}, integration key: ${integrationKey} and account: ${account}`,\n );\n await client.insertServiceMapping({\n entityRef,\n serviceId,\n integrationKey,\n account,\n });\n\n updateAnnotations(entity, {\n serviceId,\n integrationKey,\n account,\n });\n } else {\n this.logger.debug(\n `Service mapping override found for service id: ${serviceId}. Skipping adding to the database.`,\n );\n updateAnnotations(entity, {}); // delete annotations because user unmapped the service\n }\n }\n }\n\n // Process service dependencies\n // if (entity.spec?.dependsOn) {\n // Check if ServiceId exists get service dependencies from PagerDuty\n const serviceId =\n entity.metadata.annotations?.['pagerduty.com/service-id'];\n\n if (serviceId) {\n const strategySetting =\n await client.getServiceDependencyStrategySetting();\n\n if (strategySetting && strategySetting !== 'disabled') {\n // Check if service has dependencies configured\n let dependencyAnnotations: string[] = [];\n\n if (entity.spec?.dependsOn) {\n dependencyAnnotations = JSON.parse(\n JSON.stringify(entity.spec?.dependsOn),\n );\n }\n\n const mappings = await client.getAllServiceMappings();\n\n const entityDependencies: string[] =\n await buildExistingDependencies(dependencyAnnotations);\n\n // Get dependencies from PagerDuty for the service\n const account =\n entity.metadata.annotations?.['pagerduty.com/account'];\n const dependencies = await client.getServiceDependencies(\n serviceId,\n account,\n );\n const filteredDependencies = dependencies.filter(\n x => x.dependent_service.id === serviceId,\n );\n const dependencyIds = filteredDependencies.map(\n x => x.supporting_service.id,\n );\n\n // compare dependencies with existing dependencies defined on the entity\n const dependenciesMissingInBackstage = dependencyIds.filter(\n x => !entityDependencies.includes(x),\n );\n const dependenciesMissingInPagerDuty = entityDependencies.filter(\n x => !dependencyIds.includes(x),\n );\n\n switch (strategySetting) {\n case 'backstage':\n // Update dependencies on PagerDuty with dependenciesMissinginPagerDuty\n // Add dependency associations in PagerDuty\n if (dependenciesMissingInPagerDuty.length > 0) {\n this.logger.debug(\n `Updating dependencies on PagerDuty with: ${JSON.stringify(\n dependenciesMissingInPagerDuty,\n )}`,\n );\n await client.addServiceRelationToService(\n serviceId,\n dependenciesMissingInPagerDuty,\n );\n }\n\n // Remove dependency associations in PagerDuty\n if (dependenciesMissingInBackstage.length > 0) {\n this.logger.debug(\n `Removing dependencies on PagerDuty with: ${JSON.stringify(\n dependenciesMissingInBackstage,\n )}`,\n );\n await client.removeServiceRelationFromService(\n serviceId,\n dependenciesMissingInBackstage,\n );\n }\n\n break;\n case 'pagerduty':\n // Update dependencies on Backstage with dependenciesMissingInBackstage\n\n // !!!\n // This is not supported yet due to a limitation on Backstage side\n // that prevents a full override of the dependencies once they are\n // set on the entity configuration file\n // !!!\n\n entity.spec!.dependsOn = refreshServiceDependencyAnnotations(\n entity,\n mappings,\n dependencyIds,\n emit,\n );\n\n break;\n case 'both':\n // Update dependencies in both PagerDuty and Backstage\n this.logger.debug(\n `Updating dependencies on PagerDuty with: ${JSON.stringify(\n dependenciesMissingInPagerDuty,\n )} and Backstage with: ${JSON.stringify(\n dependenciesMissingInBackstage,\n )}`,\n );\n\n // Add missing dependencies to PagerDuty\n if (dependenciesMissingInPagerDuty.length > 0) {\n await client.addServiceRelationToService(\n serviceId,\n dependenciesMissingInPagerDuty,\n );\n }\n\n // Add missing dependencies to Backstage\n entity.spec!.dependsOn = refreshServiceDependencyAnnotations(\n entity,\n mappings,\n dependencyIds,\n emit,\n );\n\n break;\n default:\n // Do nothing. Strategy not defined or set to disabled\n break;\n }\n }\n }\n } catch (error) {\n this.logger.error(\n `Error processing entity ${entity.metadata.name}: ${error}`,\n );\n }\n }\n\n return entity;\n }\n}\n\nexport function refreshServiceDependencyAnnotations(\n entity: Entity,\n mappingsDic: Record<string, string>,\n dependencies: string[],\n emit: CatalogProcessorEmit,\n): string[] {\n const dependencyList: string[] = [];\n dependencies.forEach(dependencyId => {\n const foundEntityRef = mappingsDic[dependencyId];\n\n if (foundEntityRef && foundEntityRef !== '') {\n dependencyList.push(foundEntityRef);\n\n const entityRefParts = foundEntityRef.split(':');\n const kind = entityRefParts[0];\n const namespaceName = entityRefParts[1].split('/');\n const namespace = namespaceName[0];\n const name = namespaceName[1];\n\n emit(\n processingResult.relation({\n source: {\n kind: entity.kind,\n namespace: entity.metadata.namespace!,\n name: entity.metadata.name,\n },\n target: {\n kind: kind,\n namespace: namespace,\n name: name,\n },\n type: RELATION_DEPENDS_ON,\n }),\n );\n\n emit(\n processingResult.relation({\n source: {\n kind: kind,\n namespace: namespace,\n name: name,\n },\n target: {\n kind: entity.kind,\n namespace: entity.metadata.namespace!,\n name: entity.metadata.name,\n },\n type: RELATION_DEPENDENCY_OF,\n }),\n );\n }\n });\n\n return dependencyList;\n}\n\nexport type AnnotationUpdateProps = {\n serviceId?: string;\n integrationKey?: string;\n account?: string;\n};\n\nfunction updateAnnotations(\n entity: Entity,\n annotations: AnnotationUpdateProps,\n): void {\n // If serviceId is present, add the annotations to the entity\n if (annotations.serviceId && annotations.serviceId !== '') {\n entity.metadata.annotations!['pagerduty.com/service-id'] =\n annotations.serviceId;\n } else {\n delete entity.metadata.annotations!['pagerduty.com/service-id'];\n }\n\n // If integrationKey is present, add the annotations to the entity\n if (annotations.integrationKey && annotations.integrationKey !== '') {\n entity.metadata.annotations!['pagerduty.com/integration-key'] =\n annotations.integrationKey;\n } else {\n delete entity.metadata.annotations!['pagerduty.com/integration-key'];\n }\n\n // If account is present, add the annotations to the entity\n if (annotations.account && annotations.account !== '') {\n entity.metadata.annotations!['pagerduty.com/account'] = annotations.account;\n } else {\n delete entity.metadata.annotations!['pagerduty.com/account'];\n }\n}\n\nasync function buildExistingDependencies(\n dependencyAnnotations: string[],\n): Promise<string[]> {\n const dependencies: string[] = [];\n\n // Get all service ids matching the dependency annotations\n if (dependencyAnnotations.length > 0) {\n await Promise.all(\n dependencyAnnotations.map(async dependency => {\n const foundServiceId = await client.getServiceIdAnnotationFromCatalog(\n dependency,\n );\n\n if (foundServiceId !== '') {\n dependencies.push(foundServiceId);\n }\n }),\n );\n }\n\n return dependencies;\n}\n"],"names":["PagerDutyClient","serviceId","processingResult","RELATION_DEPENDS_ON","RELATION_DEPENDENCY_OF"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagerduty/backstage-plugin-entity-processor",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
"types": "dist/index.d.ts"
|
|
11
11
|
},
|
|
12
12
|
"backstage": {
|
|
13
|
-
"role": "backend-plugin-module",
|
|
14
13
|
"pluginId": "catalog",
|
|
15
|
-
"
|
|
14
|
+
"role": "backend-plugin-module",
|
|
15
|
+
"pluginPackage": "@backstage/plugin-catalog-backend",
|
|
16
16
|
"features": {
|
|
17
17
|
".": "@backstage/BackendFeature"
|
|
18
18
|
}
|