@pagerduty/backstage-plugin-entity-processor 0.3.0-next.8 → 0.3.0-next.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -6,24 +6,114 @@ var backendPluginApi = require('@backstage/backend-plugin-api');
6
6
  var alpha = require('@backstage/plugin-catalog-node/alpha');
7
7
  var fetch = require('node-fetch');
8
8
 
9
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
10
10
 
11
- var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
11
+ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
12
12
 
13
- var __defProp$1 = Object.defineProperty;
14
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
- var __publicField$1 = (obj, key, value) => {
16
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
17
- return value;
18
- };
19
13
  class PagerDutyClient {
14
+ discovery;
15
+ logger;
16
+ baseUrl = "";
20
17
  constructor({ discovery, logger }) {
21
- __publicField$1(this, "discovery");
22
- __publicField$1(this, "logger");
23
- __publicField$1(this, "baseUrl", "");
24
18
  this.discovery = discovery;
25
19
  this.logger = logger;
26
20
  }
21
+ async addServiceRelationToService(serviceId, relations) {
22
+ let response;
23
+ if (this.baseUrl === "") {
24
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
25
+ }
26
+ const options = {
27
+ method: "POST",
28
+ headers: {
29
+ "Content-Type": "application/json; charset=UTF-8",
30
+ Accept: "application/json, text/plain, */*"
31
+ },
32
+ body: JSON.stringify(relations)
33
+ };
34
+ const url = `${await this.discovery.getBaseUrl(
35
+ "pagerduty"
36
+ )}/dependencies/service/${serviceId}`;
37
+ try {
38
+ response = await fetchWithRetries(url, options);
39
+ if (response.status >= 500) {
40
+ 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.`);
41
+ }
42
+ if (!response.ok) {
43
+ throw new Error(await response.text());
44
+ }
45
+ } catch (error) {
46
+ this.logger.error(`Failed to add dependencies: ${error}`);
47
+ throw new Error(`Failed to add dependencies: ${error}`);
48
+ }
49
+ }
50
+ async removeServiceRelationFromService(serviceId, relations) {
51
+ let response;
52
+ if (this.baseUrl === "") {
53
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
54
+ }
55
+ const options = {
56
+ method: "DELETE",
57
+ headers: {
58
+ "Content-Type": "application/json; charset=UTF-8",
59
+ Accept: "application/json, text/plain, */*"
60
+ },
61
+ body: JSON.stringify(relations)
62
+ };
63
+ const url = `${await this.discovery.getBaseUrl(
64
+ "pagerduty"
65
+ )}/dependencies/service/${serviceId}`;
66
+ try {
67
+ response = await fetchWithRetries(url, options);
68
+ if (response.status >= 500) {
69
+ 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.`);
70
+ }
71
+ if (!response.ok) {
72
+ throw new Error(await response.text());
73
+ }
74
+ } catch (error) {
75
+ this.logger.error(`Failed to remove dependencies: ${error}`);
76
+ throw new Error(`Failed to remove dependencies: ${error}`);
77
+ }
78
+ }
79
+ async getAllServiceMappings() {
80
+ let response;
81
+ const mappings = {};
82
+ if (this.baseUrl === "") {
83
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
84
+ }
85
+ const options = {
86
+ method: "GET",
87
+ headers: {
88
+ "Content-Type": "application/json; charset=UTF-8",
89
+ Accept: "application/json, text/plain, */*"
90
+ }
91
+ };
92
+ const url = `${await this.discovery.getBaseUrl(
93
+ "pagerduty"
94
+ )}/mapping/entity`;
95
+ try {
96
+ response = await fetchWithRetries(url, options);
97
+ if (response.status >= 500) {
98
+ throw new Error(`Failed to get all service mappings. API returned a server error. Retrying with the same arguments will not work.`);
99
+ }
100
+ const foundMappings = await response.json();
101
+ switch (response.status) {
102
+ case 400:
103
+ throw new Error(await response.text());
104
+ case 404:
105
+ return mappings;
106
+ default:
107
+ foundMappings.mappings.forEach((mapping) => {
108
+ mappings[mapping.serviceId] = mapping.entityRef;
109
+ });
110
+ return mappings;
111
+ }
112
+ } catch (error) {
113
+ this.logger.error(`Failed to retrieve mappings: ${error}`);
114
+ throw new Error(`Failed to retrieve mappings: ${error}`);
115
+ }
116
+ }
27
117
  async findServiceMapping({ type, namespace, name }) {
28
118
  let response;
29
119
  if (this.baseUrl === "") {
@@ -40,13 +130,16 @@ class PagerDutyClient {
40
130
  "pagerduty"
41
131
  )}/mapping/entity/${type}/${namespace}/${name}`;
42
132
  try {
43
- response = await fetch__default["default"](url, options);
133
+ response = await fetchWithRetries(url, options);
134
+ if (response.status >= 500) {
135
+ throw new Error(`Failed to find service mapping. API returned a server error. Retrying with the same arguments will not work.`);
136
+ }
44
137
  const foundMapping = await response.json();
45
138
  switch (response.status) {
46
139
  case 400:
47
140
  throw new Error(await response.text());
48
141
  case 404:
49
- return {};
142
+ return void 0;
50
143
  default:
51
144
  this.logger.debug(`Found mapping for ${type}:${namespace}/${name}: ${JSON.stringify(foundMapping.mapping)}`);
52
145
  return {
@@ -61,6 +154,75 @@ class PagerDutyClient {
61
154
  throw new Error(`Failed to retrieve mapping for ${type}:${namespace}/${name}: ${error}`);
62
155
  }
63
156
  }
157
+ async findServiceMappingById(serviceId) {
158
+ let response;
159
+ if (this.baseUrl === "") {
160
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
161
+ }
162
+ const options = {
163
+ method: "GET",
164
+ headers: {
165
+ "Content-Type": "application/json; charset=UTF-8",
166
+ Accept: "application/json, text/plain, */*"
167
+ }
168
+ };
169
+ const url = `${await this.discovery.getBaseUrl(
170
+ "pagerduty"
171
+ )}/mapping/entity/service/${serviceId}`;
172
+ try {
173
+ response = await fetchWithRetries(url, options);
174
+ if (response.status >= 500) {
175
+ throw new Error(`Failed to find service mapping by id. API returned a server error. Retrying with the same arguments will not work.`);
176
+ }
177
+ const foundMapping = await response.json();
178
+ switch (response.status) {
179
+ case 400:
180
+ throw new Error(await response.text());
181
+ case 404:
182
+ return void 0;
183
+ default:
184
+ this.logger.debug(`Found mapping for serviceId ${serviceId}: ${JSON.stringify(foundMapping.mapping)}`);
185
+ return {
186
+ serviceId: foundMapping.mapping.serviceId,
187
+ integrationKey: foundMapping.mapping.integrationKey,
188
+ entityRef: foundMapping.mapping.entityRef,
189
+ account: foundMapping.mapping.account
190
+ };
191
+ }
192
+ } catch (error) {
193
+ this.logger.error(`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`);
194
+ throw new Error(`Failed to retrieve mapping for serviceId ${serviceId}: ${error}`);
195
+ }
196
+ }
197
+ async insertServiceMapping(mapping) {
198
+ let response;
199
+ if (this.baseUrl === "") {
200
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
201
+ }
202
+ const options = {
203
+ method: "POST",
204
+ headers: {
205
+ "Content-Type": "application/json; charset=UTF-8",
206
+ Accept: "application/json, text/plain, */*"
207
+ },
208
+ body: JSON.stringify(mapping)
209
+ };
210
+ const url = `${await this.discovery.getBaseUrl(
211
+ "pagerduty"
212
+ )}/mapping/entity`;
213
+ try {
214
+ response = await fetchWithRetries(url, options);
215
+ if (response.status >= 500) {
216
+ throw new Error(`Failed to add service mapping. API returned a server error. Retrying with the same arguments will not work.`);
217
+ }
218
+ if (!response.ok) {
219
+ throw new Error(await response.text());
220
+ }
221
+ } catch (error) {
222
+ this.logger.error(`Failed to add mapping for ${mapping.entityRef}: ${error}`);
223
+ throw new Error(`Failed to add mapping for ${mapping.entityRef}: ${error}`);
224
+ }
225
+ }
64
226
  async getServiceDependencies(serviceId, account) {
65
227
  let response;
66
228
  if (this.baseUrl === "") {
@@ -80,7 +242,10 @@ class PagerDutyClient {
80
242
  url = url.concat(`?account=${account}`);
81
243
  }
82
244
  try {
83
- response = await fetch__default["default"](url, options);
245
+ response = await fetchWithRetries(url, options);
246
+ if (response.status >= 500) {
247
+ throw new Error(`Failed to get service depedencies. PagerDuty API returned a server error. Retrying with the same arguments will not work.`);
248
+ }
84
249
  const foundDependencies = await response.json();
85
250
  switch (response.status) {
86
251
  case 400:
@@ -88,7 +253,6 @@ class PagerDutyClient {
88
253
  case 404:
89
254
  return [];
90
255
  default:
91
- this.logger.info(`Found mapping for ${serviceId}: ${JSON.stringify(foundDependencies.relationships)}`);
92
256
  return foundDependencies.relationships;
93
257
  }
94
258
  } catch (error) {
@@ -114,7 +278,10 @@ class PagerDutyClient {
114
278
  "pagerduty"
115
279
  )}/catalog/entity/${type}/${namespace}/${name}`;
116
280
  try {
117
- response = await fetch__default["default"](url, options);
281
+ response = await fetchWithRetries(url, options);
282
+ if (response.status >= 500) {
283
+ throw new Error(`Failed to get service id annotation from catalog. API returned a server error. Retrying with the same arguments will not work.`);
284
+ }
118
285
  const foundServiceId = await response.json();
119
286
  switch (response.status) {
120
287
  case 400:
@@ -122,7 +289,6 @@ class PagerDutyClient {
122
289
  case 404:
123
290
  return "";
124
291
  default:
125
- this.logger.info(`Found serviceId for ${entityRef}: ${JSON.stringify(foundServiceId)}`);
126
292
  return foundServiceId;
127
293
  }
128
294
  } catch (error) {
@@ -130,22 +296,148 @@ class PagerDutyClient {
130
296
  throw new Error(`Failed to retrieve a PagerDuty service id for ${entityRef}: ${error}`);
131
297
  }
132
298
  }
299
+ async getServiceIdFromIntegrationKey(integrationKey, account) {
300
+ let response;
301
+ if (this.baseUrl === "") {
302
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
303
+ }
304
+ const options = {
305
+ method: "GET",
306
+ headers: {
307
+ "Content-Type": "application/json; charset=UTF-8",
308
+ Accept: "application/json, text/plain, */*"
309
+ }
310
+ };
311
+ let url = `${await this.discovery.getBaseUrl(
312
+ "pagerduty"
313
+ )}/services?integration_key=${integrationKey}`;
314
+ if (account) {
315
+ url = url.concat(`&account=${account}`);
316
+ }
317
+ try {
318
+ response = await fetchWithRetries(url, options);
319
+ if (response.status >= 500) {
320
+ 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.`);
321
+ }
322
+ const foundService = await response.json();
323
+ switch (response.status) {
324
+ case 400:
325
+ throw new Error(await response.text());
326
+ case 404:
327
+ return "";
328
+ default:
329
+ return foundService.service.id;
330
+ }
331
+ } catch (error) {
332
+ this.logger.error(`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`);
333
+ throw new Error(`Failed to retrieve a PagerDuty service id for integration key ${integrationKey}: ${error}`);
334
+ }
335
+ }
336
+ async getIntegrationKeyFromServiceId(serviceId, account) {
337
+ let response;
338
+ if (this.baseUrl === "") {
339
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
340
+ }
341
+ const options = {
342
+ method: "GET",
343
+ headers: {
344
+ "Content-Type": "application/json; charset=UTF-8",
345
+ Accept: "application/json, text/plain, */*"
346
+ }
347
+ };
348
+ let url = `${await this.discovery.getBaseUrl(
349
+ "pagerduty"
350
+ )}/services/${serviceId}`;
351
+ if (account) {
352
+ url = url.concat(`?account=${account}`);
353
+ }
354
+ try {
355
+ response = await fetchWithRetries(url, options);
356
+ if (response.status >= 500) {
357
+ 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.`);
358
+ }
359
+ const foundService = await response.json();
360
+ const backstageIntegration = foundService.service.integrations?.find((integration) => integration.vendor?.id === "PRO19CT");
361
+ switch (response.status) {
362
+ case 400:
363
+ throw new Error(await response.text());
364
+ case 404:
365
+ return "";
366
+ default:
367
+ if (!backstageIntegration) {
368
+ return void 0;
369
+ }
370
+ return backstageIntegration.integration_key;
371
+ }
372
+ } catch (error) {
373
+ this.logger.error(`No Backstage integration found for service id ${serviceId}: ${error}`);
374
+ throw new Error(`No Backstage integration found for service id ${serviceId}: ${error}`);
375
+ }
376
+ }
377
+ async getServiceDependencyStrategySetting() {
378
+ const SERVICE_DEPENDENCY_SYNC_STRATEGY = "settings::service-dependency-sync-strategy";
379
+ let response;
380
+ if (this.baseUrl === "") {
381
+ this.baseUrl = await this.discovery.getBaseUrl("pagerduty");
382
+ }
383
+ const options = {
384
+ method: "GET",
385
+ headers: {
386
+ "Content-Type": "application/json; charset=UTF-8",
387
+ Accept: "application/json, text/plain, */*"
388
+ }
389
+ };
390
+ const url = `${await this.discovery.getBaseUrl(
391
+ "pagerduty"
392
+ )}/settings/${SERVICE_DEPENDENCY_SYNC_STRATEGY}`;
393
+ try {
394
+ response = await fetchWithRetries(url, options);
395
+ if (response.status >= 500) {
396
+ throw new Error(`Failed to get service depedency strategy. API returned a server error. Retrying with the same arguments will not work.`);
397
+ }
398
+ const setting = await response.json();
399
+ switch (response.status) {
400
+ case 400:
401
+ throw new Error(await response.text());
402
+ case 404:
403
+ return "disabled";
404
+ default:
405
+ return setting.value;
406
+ }
407
+ } catch (error) {
408
+ this.logger.error(`Error getting value for setting: ${error}`);
409
+ throw new Error(`Error getting value for setting: ${error}`);
410
+ }
411
+ }
412
+ }
413
+ async function fetchWithRetries(url, options) {
414
+ let response;
415
+ let error = new Error();
416
+ const maxRetries = 5;
417
+ const delay = 1e3;
418
+ let factor = 2;
419
+ for (let i = 0; i < maxRetries; i++) {
420
+ try {
421
+ response = await fetch__default.default(url, options);
422
+ return response;
423
+ } catch (e) {
424
+ error = e;
425
+ }
426
+ const timeout = delay * factor;
427
+ await new Promise((resolve) => setTimeout(resolve, timeout));
428
+ factor *= 2;
429
+ }
430
+ throw new Error(`Failed to fetch data after ${maxRetries} retries. Last error: ${error}`);
133
431
  }
134
432
 
135
- var __defProp = Object.defineProperty;
136
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
137
- var __publicField = (obj, key, value) => {
138
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
139
- return value;
140
- };
141
433
  let client;
142
434
  class PagerDutyEntityProcessor {
435
+ logger;
436
+ discovery;
437
+ shouldProcessEntity = (entity) => {
438
+ return entity.kind === "Component";
439
+ };
143
440
  constructor({ logger, discovery }) {
144
- __publicField(this, "logger");
145
- __publicField(this, "discovery");
146
- __publicField(this, "shouldProcessEntity", (entity) => {
147
- return entity.kind === "Component";
148
- });
149
441
  this.logger = logger;
150
442
  this.discovery = discovery;
151
443
  client = new PagerDutyClient({ discovery: this.discovery, logger: this.logger });
@@ -153,8 +445,7 @@ class PagerDutyEntityProcessor {
153
445
  getProcessorName() {
154
446
  return "PagerDutyEntityProcessor";
155
447
  }
156
- async postProcessEntity(entity) {
157
- var _a, _b, _c;
448
+ async postProcessEntity(entity, _location, emit) {
158
449
  if (this.shouldProcessEntity(entity)) {
159
450
  try {
160
451
  const mapping = await client.findServiceMapping({
@@ -162,66 +453,206 @@ class PagerDutyEntityProcessor {
162
453
  namespace: entity.metadata.namespace.toLowerCase(),
163
454
  name: entity.metadata.name.toLowerCase()
164
455
  });
165
- if (mapping.serviceId) {
166
- if (mapping.serviceId && mapping.serviceId !== "") {
167
- entity.metadata.annotations["pagerduty.com/service-id"] = mapping.serviceId;
168
- } else {
169
- delete entity.metadata.annotations["pagerduty.com/service-id"];
170
- }
171
- if (mapping.integrationKey && mapping.integrationKey !== "") {
172
- entity.metadata.annotations["pagerduty.com/integration-key"] = mapping.integrationKey;
173
- } else {
174
- delete entity.metadata.annotations["pagerduty.com/integration-key"];
175
- }
176
- if (mapping.account && mapping.account !== "") {
177
- entity.metadata.annotations["pagerduty.com/account"] = mapping.account;
178
- } else {
179
- delete entity.metadata.annotations["pagerduty.com/account"];
180
- }
456
+ if (mapping) {
457
+ updateAnnotations(
458
+ entity,
459
+ {
460
+ serviceId: mapping.serviceId,
461
+ integrationKey: mapping.integrationKey,
462
+ account: mapping.account
463
+ }
464
+ );
181
465
  this.logger.debug(`Added annotations to entity ${entity.metadata.name} with service id: ${mapping.serviceId}, integration key: ${mapping.integrationKey} and account: ${mapping.account}`);
182
466
  } else {
183
- this.logger.debug(`No mapping found for entity: ${entity.metadata.name}`);
467
+ this.logger.debug(`No mapping found for entity: ${entity.metadata.name}. Adding annotations to the database.`);
468
+ let serviceId2 = entity.metadata.annotations?.["pagerduty.com/service-id"];
469
+ let integrationKey = entity.metadata.annotations?.["pagerduty.com/integration-key"];
470
+ const account = entity.metadata.annotations?.["pagerduty.com/account"];
471
+ const entityRef = `${entity.kind.toLowerCase()}:${entity.metadata.namespace?.toLowerCase()}/${entity.metadata.name.toLowerCase()}`;
472
+ if (serviceId2) {
473
+ const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId2);
474
+ if (!serviceMappingOverrideFound) {
475
+ if (!integrationKey) {
476
+ const foundIntegrationKey = await client.getIntegrationKeyFromServiceId(serviceId2, account);
477
+ if (foundIntegrationKey) {
478
+ integrationKey = foundIntegrationKey;
479
+ }
480
+ }
481
+ this.logger.debug(`Inserting mapping for entity: ${entityRef} with service id: ${serviceId2}, integration key: ${integrationKey} and account: ${account}`);
482
+ await client.insertServiceMapping({
483
+ entityRef,
484
+ serviceId: serviceId2,
485
+ integrationKey,
486
+ account
487
+ });
488
+ updateAnnotations(
489
+ entity,
490
+ {
491
+ serviceId: serviceId2,
492
+ integrationKey,
493
+ account
494
+ }
495
+ );
496
+ } else {
497
+ this.logger.debug(`Service mapping override found for service id: ${serviceId2}.`);
498
+ updateAnnotations(entity, {});
499
+ }
500
+ } else if (integrationKey) {
501
+ serviceId2 = await client.getServiceIdFromIntegrationKey(integrationKey, account);
502
+ const serviceMappingOverrideFound = await client.findServiceMappingById(serviceId2);
503
+ if (!serviceMappingOverrideFound) {
504
+ this.logger.debug(`Inserting mapping for entity: ${entityRef} with new service id: ${serviceId2}, integration key: ${integrationKey} and account: ${account}`);
505
+ await client.insertServiceMapping({
506
+ entityRef,
507
+ serviceId: serviceId2,
508
+ integrationKey,
509
+ account
510
+ });
511
+ updateAnnotations(
512
+ entity,
513
+ {
514
+ serviceId: serviceId2,
515
+ integrationKey,
516
+ account
517
+ }
518
+ );
519
+ } else {
520
+ this.logger.debug(`Service mapping override found for service id: ${serviceId2}. Skipping adding to the database.`);
521
+ updateAnnotations(entity, {});
522
+ }
523
+ }
184
524
  }
185
- if ((_a = entity.spec) == null ? void 0 : _a.dependsOn) {
186
- const serviceId = entity.metadata.annotations["pagerduty.com/service-id"];
187
- const dependencyAnnotations = JSON.parse(JSON.stringify((_b = entity.spec) == null ? void 0 : _b.dependsOn));
188
- this.logger.info(`Existing dependencies for entity: ${entity.metadata.name}. Dependencies: ${JSON.stringify(dependencyAnnotations)}`);
189
- if (serviceId && (dependencyAnnotations == null ? void 0 : dependencyAnnotations.length) > 0) {
190
- const existingDependencies = await buildExistingDependencies(dependencyAnnotations);
191
- const account = entity.metadata.annotations["pagerduty.com/account"];
525
+ const serviceId = entity.metadata.annotations?.["pagerduty.com/service-id"];
526
+ if (serviceId) {
527
+ const strategySetting = await client.getServiceDependencyStrategySetting();
528
+ if (strategySetting && strategySetting !== "disabled") {
529
+ let dependencyAnnotations = [];
530
+ if (entity.spec?.dependsOn) {
531
+ dependencyAnnotations = JSON.parse(JSON.stringify(entity.spec?.dependsOn));
532
+ }
533
+ const mappings = await client.getAllServiceMappings();
534
+ const entityDependencies = await buildExistingDependencies(dependencyAnnotations);
535
+ const account = entity.metadata.annotations?.["pagerduty.com/account"];
192
536
  const dependencies = await client.getServiceDependencies(serviceId, account);
193
- const dependencyIds = dependencies.map((x) => x.dependent_service.id);
194
- this.logger.info(`Dependencies from PagerDuty service: ${serviceId}. Dependencies: ${JSON.stringify(dependencies)}`);
195
- const res1 = dependencyIds.filter((x) => !existingDependencies.includes(x));
196
- const res2 = existingDependencies.filter((x) => dependencyIds.includes(x));
197
- const newDependencies = [...res1, ...res2];
198
- this.logger.info(`Updated dependencies for service: ${serviceId}. New dependencies: ${JSON.stringify(newDependencies)}`);
199
- if (newDependencies.length > 0) {
200
- this.logger.info(`Updated dependencies for service: ${serviceId}. New dependencies: ${JSON.stringify(newDependencies)}`);
537
+ const filteredDependencies = dependencies.filter((x) => x.dependent_service.id === serviceId);
538
+ const dependencyIds = filteredDependencies.map((x) => x.supporting_service.id);
539
+ const dependenciesMissingInBackstage = dependencyIds.filter((x) => !entityDependencies.includes(x));
540
+ const dependenciesMissingInPagerDuty = entityDependencies.filter((x) => !dependencyIds.includes(x));
541
+ switch (strategySetting) {
542
+ case "backstage":
543
+ if (dependenciesMissingInPagerDuty.length > 0) {
544
+ this.logger.debug(`Updating dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInPagerDuty)}`);
545
+ await client.addServiceRelationToService(serviceId, dependenciesMissingInPagerDuty);
546
+ }
547
+ if (dependenciesMissingInBackstage.length > 0) {
548
+ this.logger.debug(`Removing dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInBackstage)}`);
549
+ await client.removeServiceRelationFromService(serviceId, dependenciesMissingInBackstage);
550
+ }
551
+ break;
552
+ case "pagerduty":
553
+ this.logger.info(`Overwriting dependencies on Backstage with: ${JSON.stringify(dependencyIds)}`);
554
+ entity.spec.dependsOn = refreshServiceDependencyAnnotations(entity, mappings, dependencyIds, emit, true);
555
+ break;
556
+ case "both":
557
+ this.logger.debug(`Updating dependencies on PagerDuty with: ${JSON.stringify(dependenciesMissingInPagerDuty)} and Backstage with: ${JSON.stringify(dependenciesMissingInBackstage)}`);
558
+ if (dependenciesMissingInPagerDuty.length > 0) {
559
+ await client.addServiceRelationToService(serviceId, dependenciesMissingInPagerDuty);
560
+ }
561
+ entity.spec.dependsOn = refreshServiceDependencyAnnotations(entity, mappings, dependencyIds, emit);
562
+ break;
563
+ default:
564
+ break;
201
565
  }
202
566
  }
203
- } else {
204
- this.logger.info(`No dependencies found for entity: ${entity.metadata.name}`);
205
- }
206
- if ((_c = entity.spec) == null ? void 0 : _c.dependencyOf) {
207
- this.logger.info(`Processing dependents for entity: ${entity.metadata.name}. Dependents: ${JSON.stringify(entity.spec.dependencyOf)}`);
208
567
  }
209
568
  } catch (error) {
210
- this.logger.error(`Error processing entity: ${entity.metadata.name}`);
211
- this.logger.error(`${error}`);
569
+ this.logger.error(`Error processing entity ${entity.metadata.name}: ${error}`);
212
570
  }
213
571
  }
214
572
  return entity;
215
573
  }
216
574
  }
217
- async function buildExistingDependencies(dependencyAnnotations) {
218
- const dependencies = [];
219
- dependencyAnnotations.map(async (dependency) => {
220
- const foundServiceId = await client.getServiceIdAnnotationFromCatalog(dependency);
221
- if (foundServiceId !== "") {
222
- dependencies.push(foundServiceId);
575
+ function refreshServiceDependencyAnnotations(entity, mappingsDic, dependencies, emit, replace = false) {
576
+ const dependencyList = [];
577
+ if (replace === true) {
578
+ entity.relations = void 0;
579
+ }
580
+ dependencies.forEach((dependencyId) => {
581
+ const foundEntityRef = mappingsDic[dependencyId];
582
+ if (foundEntityRef && foundEntityRef !== "") {
583
+ console.log(`DEBUG: Found entity ref: ${foundEntityRef}`);
584
+ dependencyList.push(foundEntityRef);
585
+ const entityRefParts = foundEntityRef.split(":");
586
+ const kind = entityRefParts[0];
587
+ const namespaceName = entityRefParts[1].split("/");
588
+ const namespace = namespaceName[0];
589
+ const name = namespaceName[1];
590
+ emit({
591
+ relation: {
592
+ source: {
593
+ kind: entity.kind,
594
+ namespace: entity.metadata.namespace,
595
+ name: entity.metadata.name
596
+ },
597
+ target: {
598
+ kind,
599
+ namespace,
600
+ name
601
+ },
602
+ type: "dependsOn"
603
+ },
604
+ type: "relation"
605
+ });
606
+ emit({
607
+ relation: {
608
+ source: {
609
+ kind,
610
+ namespace,
611
+ name
612
+ },
613
+ target: {
614
+ kind: entity.kind,
615
+ namespace: entity.metadata.namespace,
616
+ name: entity.metadata.name
617
+ },
618
+ type: "dependencyOf"
619
+ },
620
+ type: "relation"
621
+ });
223
622
  }
224
623
  });
624
+ console.log(`Updated dependencies for entity ${entity.metadata.name}: ${JSON.stringify(dependencyList)}`);
625
+ return dependencyList;
626
+ }
627
+ function updateAnnotations(entity, annotations) {
628
+ if (annotations.serviceId && annotations.serviceId !== "") {
629
+ entity.metadata.annotations["pagerduty.com/service-id"] = annotations.serviceId;
630
+ } else {
631
+ delete entity.metadata.annotations["pagerduty.com/service-id"];
632
+ }
633
+ if (annotations.integrationKey && annotations.integrationKey !== "") {
634
+ entity.metadata.annotations["pagerduty.com/integration-key"] = annotations.integrationKey;
635
+ } else {
636
+ delete entity.metadata.annotations["pagerduty.com/integration-key"];
637
+ }
638
+ if (annotations.account && annotations.account !== "") {
639
+ entity.metadata.annotations["pagerduty.com/account"] = annotations.account;
640
+ } else {
641
+ delete entity.metadata.annotations["pagerduty.com/account"];
642
+ }
643
+ }
644
+ async function buildExistingDependencies(dependencyAnnotations) {
645
+ const dependencies = [];
646
+ if (dependencyAnnotations.length > 0) {
647
+ await Promise.all(
648
+ dependencyAnnotations.map(async (dependency) => {
649
+ const foundServiceId = await client.getServiceIdAnnotationFromCatalog(dependency);
650
+ if (foundServiceId !== "") {
651
+ dependencies.push(foundServiceId);
652
+ }
653
+ })
654
+ );
655
+ }
225
656
  return dependencies;
226
657
  }
227
658
 
@@ -242,5 +673,5 @@ const pagerDutyEntityProcessor = backendPluginApi.createBackendModule({
242
673
  }
243
674
  });
244
675
 
245
- exports["default"] = pagerDutyEntityProcessor;
676
+ exports.default = pagerDutyEntityProcessor;
246
677
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/apis/client.ts","../src/processor/PagerDutyEntityProcessor.ts","../src/module.ts"],"sourcesContent":["import fetch from 'node-fetch';\nimport type { RequestInit, Response } from 'node-fetch';\nimport type { EntityMapping } from '../types';\nimport { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';\nimport { PagerDutyEntityMappingResponse, PagerDutyServiceDependency, PagerDutyServiceDependencyResponse } 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 findServiceMapping({ type, namespace, name }: BackstageEntityRef): Promise<EntityMapping> {\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 fetch(url, options);\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 {};\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 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 fetch(url, options);\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 this.logger.info(`Found mapping for ${serviceId}: ${JSON.stringify(foundDependencies.relationships)}`);\n\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 fetch(url, options);\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 this.logger.info(`Found serviceId for ${entityRef}: ${JSON.stringify(foundServiceId)}`);\n\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}","import { DiscoveryService, LoggerService } from \"@backstage/backend-plugin-api\";\nimport { Entity } from \"@backstage/catalog-model\";\nimport { CatalogProcessor } from \"@backstage/plugin-catalog-node\";\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 postProcessEntity(entity: Entity): 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.serviceId) { \n \n // If serviceId is present, add the annotations to the entity\n if (mapping.serviceId && mapping.serviceId !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/service-id\"] = mapping.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 (mapping.integrationKey && mapping.integrationKey !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/integration-key\"] = mapping.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 (mapping.account && mapping.account !== \"\") {\n entity.metadata.annotations![\"pagerduty.com/account\"] = mapping.account;\n }\n else {\n delete entity.metadata.annotations![\"pagerduty.com/account\"];\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}`);\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 // Check if service has dependencies configured\n const dependencyAnnotations: string[] = JSON.parse(JSON.stringify(entity.spec?.dependsOn));\n this.logger.info(`Existing dependencies for entity: ${entity.metadata.name}. Dependencies: ${JSON.stringify(dependencyAnnotations)}`);\n\n if (serviceId && dependencyAnnotations?.length > 0) {\n const existingDependencies: 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 dependencyIds = dependencies.map(x => x.dependent_service.id);\n\n this.logger.info(`Dependencies from PagerDuty service: ${serviceId}. Dependencies: ${JSON.stringify(dependencies)}`);\n\n // compare dependencies with existing dependencies defined on the entity\n // const newDependencies = dependencies.filter((dependency) => existingDependencies.includes(dependency.dependent_service.id) && !existingDependencies.includes(dependency.dependent_service.id) && dependency.dependent_service.id !== serviceId);\n const res1 = dependencyIds.filter(x => !existingDependencies.includes(x));\n const res2 = existingDependencies.filter(x => dependencyIds.includes(x));\n\n const newDependencies = [...res1, ...res2];\n \n this.logger.info(`Updated dependencies for service: ${serviceId}. New dependencies: ${JSON.stringify(newDependencies)}`);\n\n // Update dependencies on PagerDuty\n if (newDependencies.length > 0){\n // await client.updateServiceDependencies(serviceId, newDependencies);\n this.logger.info(`Updated dependencies for service: ${serviceId}. New dependencies: ${JSON.stringify(newDependencies)}`);\n }\n }\n }\n else {\n this.logger.info(`No dependencies found for entity: ${entity.metadata.name}`);\n }\n\n if(entity.spec?.dependencyOf){\n this.logger.info(`Processing dependents for entity: ${entity.metadata.name}. Dependents: ${JSON.stringify(entity.spec.dependencyOf)}`);\n }\n\n } catch (error) {\n this.logger.error(`Error processing entity: ${entity.metadata.name}`);\n this.logger.error(`${error}`);\n }\n }\n\n return entity;\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 dependencyAnnotations.map(async (dependency) => {\n const foundServiceId = await client.getServiceIdAnnotationFromCatalog(dependency);\n\n if (foundServiceId !== \"\") {\n dependencies.push(foundServiceId);\n }\n });\n\n return dependencies;\n\n}","import { coreServices, createBackendModule } 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 },\n async init({ logger, discovery, catalog }) {\n catalog.addProcessor(new PagerDutyEntityProcessor({ logger, discovery}));\n },\n });\n },\n});\n"],"names":["__publicField","fetch","createBackendModule","coreServices","catalogProcessingExtensionPoint"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/apis/client.ts","../src/processor/PagerDutyEntityProcessor.ts","../src/module.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.ok) {\n throw new Error(await response.text());\n }\n } catch (error) {\n this.logger.error(`Failed to remove dependencies: ${error}`);\n throw new Error(`Failed to remove dependencies: ${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}","import { DiscoveryService, LoggerService } from \"@backstage/backend-plugin-api\";\nimport { Entity } from \"@backstage/catalog-model\";\nimport { CatalogProcessor, CatalogProcessorEmit } 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 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 this.logger.info(`Overwriting dependencies on Backstage with: ${JSON.stringify(dependencyIds)}`);\n\n entity.spec!.dependsOn = refreshServiceDependencyAnnotations(entity, mappings, dependencyIds, emit, true);\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, replace = false): string[] {\n const dependencyList: string[] = [];\n\n if(replace === true){\n entity.relations = undefined;\n }\n \n dependencies.forEach((dependencyId) => {\n const foundEntityRef = mappingsDic[dependencyId];\n\n if (foundEntityRef && foundEntityRef !== \"\") {\n console.log(`DEBUG: Found entity ref: ${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 \n emit({\n 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: \"dependsOn\",\n },\n type: \"relation\"\n });\n\n emit({\n 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: \"dependencyOf\",\n },\n type: \"relation\"\n });\n }\n });\n\n console.log(`Updated dependencies for entity ${entity.metadata.name}: ${JSON.stringify(dependencyList)}`);\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}","import { coreServices, createBackendModule } 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 },\n async init({ logger, discovery, catalog }) {\n catalog.addProcessor(new PagerDutyEntityProcessor({ logger, discovery}));\n },\n });\n },\n});\n"],"names":["fetch","serviceId","createBackendModule","coreServices","catalogProcessingExtensionPoint"],"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.0-next.8",
3
+ "version": "0.3.0-next.81",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -10,7 +10,9 @@
10
10
  "types": "dist/index.d.ts"
11
11
  },
12
12
  "backstage": {
13
- "role": "backend-plugin-module"
13
+ "role": "backend-plugin-module",
14
+ "pluginId": "catalog",
15
+ "pluginPackage": "pagerduty-entity-processor"
14
16
  },
15
17
  "homepage": "https://pagerduty.github.io/backstage-plugin-docs/index.html",
16
18
  "repository": {
@@ -31,13 +33,14 @@
31
33
  "postpack": "backstage-cli package postpack"
32
34
  },
33
35
  "dependencies": {
34
- "@backstage/backend-common": "^0.21.6",
35
- "@backstage/backend-defaults": "^0.2.16",
36
- "@backstage/backend-plugin-api": "^0.6.20",
36
+ "@backstage/backend-common": "^0.23.3",
37
+ "@backstage/backend-defaults": "^0.4.1",
38
+ "@backstage/backend-plugin-api": "^0.7.0",
37
39
  "@backstage/catalog-model": "^1.5.0",
38
40
  "@backstage/config": "^1.2.0",
39
- "@backstage/plugin-catalog-node": "^1.12.2",
40
- "@pagerduty/backstage-plugin-common": "0.2.1-next.0",
41
+ "@backstage/plugin-catalog-common": "^1.0.25",
42
+ "@backstage/plugin-catalog-node": "^1.12.4",
43
+ "@pagerduty/backstage-plugin-common": "0.2.1",
41
44
  "@rjsf/core": "^5.14.3",
42
45
  "node-fetch": "^2.6.7",
43
46
  "winston": "^3.2.1",
@@ -45,7 +48,7 @@
45
48
  "zod": "^3.22.4"
46
49
  },
47
50
  "devDependencies": {
48
- "@backstage/cli": "^0.24.0",
51
+ "@backstage/cli": "^0.26.11",
49
52
  "@types/node": "^20.9.2",
50
53
  "@types/node-fetch": "2.6.11",
51
54
  "@types/supertest": "^2.0.12",