@pagerduty/backstage-plugin-backend 0.9.6 → 0.9.8
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/apis/pagerduty.cjs.js +698 -0
- package/dist/apis/pagerduty.cjs.js.map +1 -0
- package/dist/auth/auth.cjs.js +170 -0
- package/dist/auth/auth.cjs.js.map +1 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js +68 -0
- package/dist/db/PagerDutyBackendDatabase.cjs.js.map +1 -0
- package/dist/index.cjs.js +6 -1640
- package/dist/index.cjs.js.map +1 -1
- package/dist/plugin.cjs.js +64 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +694 -0
- package/dist/service/router.cjs.js.map +1 -0
- package/migrations/20240527_init.js +1 -1
- package/package.json +9 -18
- package/LICENSE +0 -201
- package/README.md +0 -49
- package/dist/index.d.ts +0 -52
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendCommon = require('@backstage/backend-common');
|
|
4
|
+
var pagerduty = require('../apis/pagerduty.cjs.js');
|
|
5
|
+
var backstagePluginCommon = require('@pagerduty/backstage-plugin-common');
|
|
6
|
+
var auth = require('../auth/auth.cjs.js');
|
|
7
|
+
var express = require('express');
|
|
8
|
+
var Router = require('express-promise-router');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
function _interopNamespaceCompat(e) {
|
|
13
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var express__namespace = /*#__PURE__*/_interopNamespaceCompat(express);
|
|
31
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
32
|
+
|
|
33
|
+
async function createComponentEntitiesReferenceDict({ items: componentEntities }) {
|
|
34
|
+
const componentEntitiesDict = {};
|
|
35
|
+
await Promise.all(componentEntities.map(async (entity) => {
|
|
36
|
+
const serviceId = entity.metadata.annotations?.["pagerduty.com/service-id"];
|
|
37
|
+
const integrationKey = entity.metadata.annotations?.["pagerduty.com/integration-key"];
|
|
38
|
+
const account = entity.metadata.annotations?.["pagerduty.com/account"];
|
|
39
|
+
if (serviceId !== void 0 && serviceId !== "") {
|
|
40
|
+
componentEntitiesDict[serviceId] = {
|
|
41
|
+
ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),
|
|
42
|
+
name: entity.metadata.name
|
|
43
|
+
};
|
|
44
|
+
} else if (integrationKey !== void 0 && integrationKey !== "") {
|
|
45
|
+
const service = await pagerduty.getServiceByIntegrationKey(integrationKey, account).catch(() => void 0);
|
|
46
|
+
if (service !== void 0) {
|
|
47
|
+
componentEntitiesDict[service.id] = {
|
|
48
|
+
ref: `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase(),
|
|
49
|
+
name: entity.metadata.name
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
return componentEntitiesDict;
|
|
55
|
+
}
|
|
56
|
+
async function buildEntityMappingsResponse(entityMappings, componentEntitiesDict, componentEntities, pagerDutyServices) {
|
|
57
|
+
const result = {
|
|
58
|
+
mappings: []
|
|
59
|
+
};
|
|
60
|
+
pagerDutyServices.forEach((service) => {
|
|
61
|
+
const entityRef = componentEntitiesDict[service.id]?.ref;
|
|
62
|
+
const entityName = componentEntitiesDict[service.id]?.name;
|
|
63
|
+
const entityMapping = entityMappings.find((mapping) => mapping.serviceId === service.id);
|
|
64
|
+
if (entityMapping) {
|
|
65
|
+
if (entityRef === void 0) {
|
|
66
|
+
if (entityMapping.entityRef === "" || entityMapping.entityRef === void 0) {
|
|
67
|
+
result.mappings.push({
|
|
68
|
+
entityRef: "",
|
|
69
|
+
entityName: "",
|
|
70
|
+
integrationKey: entityMapping.integrationKey,
|
|
71
|
+
serviceId: entityMapping.serviceId,
|
|
72
|
+
status: "NotMapped",
|
|
73
|
+
serviceName: service.name,
|
|
74
|
+
team: service.teams?.[0]?.name ?? "",
|
|
75
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
76
|
+
serviceUrl: service.html_url,
|
|
77
|
+
account: service.account
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? "";
|
|
81
|
+
result.mappings.push({
|
|
82
|
+
entityRef: entityMapping.entityRef,
|
|
83
|
+
entityName: entityRefName,
|
|
84
|
+
serviceId: entityMapping.serviceId,
|
|
85
|
+
integrationKey: entityMapping.integrationKey,
|
|
86
|
+
status: "OutOfSync",
|
|
87
|
+
serviceName: service.name,
|
|
88
|
+
team: service.teams?.[0]?.name ?? "",
|
|
89
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
90
|
+
serviceUrl: service.html_url,
|
|
91
|
+
account: service.account
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
} else if (entityRef !== entityMapping.entityRef) {
|
|
95
|
+
const entityRefName = componentEntities.items.find((entity) => `${entity.kind}:${entity.metadata.namespace}/${entity.metadata.name}`.toLowerCase() === entityMapping.entityRef)?.metadata.name ?? "";
|
|
96
|
+
result.mappings.push({
|
|
97
|
+
entityRef: entityMapping.entityRef !== "" ? entityMapping.entityRef : "",
|
|
98
|
+
entityName: entityMapping.entityRef !== "" ? entityRefName : "",
|
|
99
|
+
serviceId: entityMapping.serviceId,
|
|
100
|
+
integrationKey: entityMapping.integrationKey,
|
|
101
|
+
status: "OutOfSync",
|
|
102
|
+
serviceName: service.name,
|
|
103
|
+
team: service.teams?.[0]?.name ?? "",
|
|
104
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
105
|
+
serviceUrl: service.html_url,
|
|
106
|
+
account: service.account
|
|
107
|
+
});
|
|
108
|
+
} else if (entityRef === entityMapping.entityRef) {
|
|
109
|
+
result.mappings.push({
|
|
110
|
+
entityRef: entityMapping.entityRef !== "" ? entityMapping.entityRef : "",
|
|
111
|
+
entityName: entityMapping.entityRef !== "" ? entityName : "",
|
|
112
|
+
serviceId: entityMapping.serviceId,
|
|
113
|
+
integrationKey: entityMapping.integrationKey,
|
|
114
|
+
status: "InSync",
|
|
115
|
+
serviceName: service.name,
|
|
116
|
+
team: service.teams?.[0]?.name ?? "",
|
|
117
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
118
|
+
serviceUrl: service.html_url,
|
|
119
|
+
account: service.account
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
const backstageVendorId = "PRO19CT";
|
|
124
|
+
const backstageIntegrationKey = service.integrations?.find((integration) => integration.vendor?.id === backstageVendorId)?.integration_key ?? "";
|
|
125
|
+
if (entityRef !== void 0) {
|
|
126
|
+
result.mappings.push({
|
|
127
|
+
entityRef,
|
|
128
|
+
entityName,
|
|
129
|
+
serviceId: service.id,
|
|
130
|
+
integrationKey: backstageIntegrationKey,
|
|
131
|
+
status: "InSync",
|
|
132
|
+
serviceName: service.name,
|
|
133
|
+
team: service.teams?.[0]?.name ?? "",
|
|
134
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
135
|
+
serviceUrl: service.html_url,
|
|
136
|
+
account: service.account
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
result.mappings.push({
|
|
140
|
+
entityRef: "",
|
|
141
|
+
entityName: "",
|
|
142
|
+
serviceId: service.id,
|
|
143
|
+
integrationKey: backstageIntegrationKey,
|
|
144
|
+
status: "NotMapped",
|
|
145
|
+
serviceName: service.name,
|
|
146
|
+
team: service.teams?.[0]?.name ?? "",
|
|
147
|
+
escalationPolicy: service.escalation_policy !== void 0 ? service.escalation_policy.name : "",
|
|
148
|
+
serviceUrl: service.html_url,
|
|
149
|
+
account: service.account
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
const sortedResult = result.mappings.sort((a, b) => {
|
|
155
|
+
if (a.serviceName < b.serviceName) {
|
|
156
|
+
return -1;
|
|
157
|
+
} else if (a.serviceName > b.serviceName) {
|
|
158
|
+
return 1;
|
|
159
|
+
}
|
|
160
|
+
return 0;
|
|
161
|
+
});
|
|
162
|
+
result.mappings = sortedResult;
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
async function createRouter(options) {
|
|
166
|
+
const { logger, config, store, catalogApi } = options;
|
|
167
|
+
let { auth: auth$1 } = options;
|
|
168
|
+
if (!auth$1) {
|
|
169
|
+
auth$1 = backendCommon.createLegacyAuthAdapters(options).auth;
|
|
170
|
+
}
|
|
171
|
+
await auth.loadAuthConfig(config, logger);
|
|
172
|
+
pagerduty.loadPagerDutyEndpointsFromConfig(config, logger);
|
|
173
|
+
const router = Router__default.default();
|
|
174
|
+
router.use(express__namespace.json());
|
|
175
|
+
router.delete("/dependencies/service/:serviceId", async (request, response) => {
|
|
176
|
+
try {
|
|
177
|
+
const serviceId = request.params.serviceId || "";
|
|
178
|
+
const account = request.query.account || "";
|
|
179
|
+
if (serviceId === "") {
|
|
180
|
+
response.status(400).json("Bad Request: ':serviceId' must be provided as part of the path");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const dependencies = Object.keys(request.body).length === 0 ? [] : request.body;
|
|
184
|
+
if (!dependencies || dependencies.length === 0) {
|
|
185
|
+
response.status(400).json("Bad Request: 'dependencies' must be provided as part of the request body");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const serviceRelations = [];
|
|
189
|
+
dependencies.forEach(async (dependency) => {
|
|
190
|
+
serviceRelations.push({
|
|
191
|
+
supporting_service: {
|
|
192
|
+
id: dependency,
|
|
193
|
+
type: "service"
|
|
194
|
+
},
|
|
195
|
+
dependent_service: {
|
|
196
|
+
id: serviceId,
|
|
197
|
+
type: "service"
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
await pagerduty.removeServiceRelationsFromService(serviceRelations, account);
|
|
202
|
+
response.sendStatus(200);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
205
|
+
logger.error(`Error occurred while processing request: ${error.message}`);
|
|
206
|
+
response.status(error.status).json({
|
|
207
|
+
errors: [
|
|
208
|
+
`${error.message}`
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
router.post("/dependencies/service/:serviceId", async (request, response) => {
|
|
215
|
+
try {
|
|
216
|
+
const serviceId = request.params.serviceId || "";
|
|
217
|
+
const account = request.query.account || "";
|
|
218
|
+
if (serviceId === "") {
|
|
219
|
+
response.status(400).json("Bad Request: ':serviceId' must be provided as part of the path");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const dependencies = Object.keys(request.body).length === 0 ? [] : request.body;
|
|
223
|
+
if (!dependencies || dependencies.length === 0) {
|
|
224
|
+
response.status(400).json("Bad Request: 'dependencies' must be provided as part of the request body");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const serviceRelations = [];
|
|
228
|
+
dependencies.forEach(async (dependency) => {
|
|
229
|
+
serviceRelations.push({
|
|
230
|
+
supporting_service: {
|
|
231
|
+
id: dependency,
|
|
232
|
+
type: "service"
|
|
233
|
+
},
|
|
234
|
+
dependent_service: {
|
|
235
|
+
id: serviceId,
|
|
236
|
+
type: "service"
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
await pagerduty.addServiceRelationsToService(serviceRelations, account);
|
|
241
|
+
response.sendStatus(200);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
244
|
+
logger.error(`Error occurred while processing request: ${error.message}`);
|
|
245
|
+
response.status(error.status).json({
|
|
246
|
+
errors: [
|
|
247
|
+
`${error.message}`
|
|
248
|
+
]
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
router.get("/dependencies/service/:serviceId", async (request, response) => {
|
|
254
|
+
try {
|
|
255
|
+
const serviceId = request.params.serviceId;
|
|
256
|
+
const account = request.query.account || "";
|
|
257
|
+
if (serviceId) {
|
|
258
|
+
const serviceRelationships = await pagerduty.getServiceRelationshipsById(serviceId, account);
|
|
259
|
+
if (serviceRelationships) {
|
|
260
|
+
response.json({
|
|
261
|
+
relationships: serviceRelationships
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
response.status(400).json("Bad Request: ':serviceId' must be provided as part of the path");
|
|
266
|
+
}
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
269
|
+
response.status(error.status).json({
|
|
270
|
+
errors: [
|
|
271
|
+
`${error.message}`
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
router.get("/catalog/entity/:type/:namespace/:name", async (request, response) => {
|
|
278
|
+
const type = request.params.type;
|
|
279
|
+
const namespace = request.params.namespace;
|
|
280
|
+
const name = request.params.name;
|
|
281
|
+
try {
|
|
282
|
+
if (type && namespace && name) {
|
|
283
|
+
const entityRef = `${type}:${namespace}/${name}`.toLowerCase();
|
|
284
|
+
const foundEntity = await catalogApi?.getEntityByRef(entityRef);
|
|
285
|
+
if (foundEntity) {
|
|
286
|
+
response.json(foundEntity.metadata.annotations?.["pagerduty.com/service-id"]);
|
|
287
|
+
} else {
|
|
288
|
+
response.status(404);
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
response.status(400).json("Bad Request: ':entityRef' must be provided as part of the path");
|
|
292
|
+
}
|
|
293
|
+
} catch (error) {
|
|
294
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
295
|
+
response.status(error.status).json({
|
|
296
|
+
errors: [
|
|
297
|
+
`${error.message}`
|
|
298
|
+
]
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
router.post("/settings", async (request, response) => {
|
|
304
|
+
try {
|
|
305
|
+
const settings = request.body;
|
|
306
|
+
await Promise.all(settings.map(async (setting) => {
|
|
307
|
+
if (setting.id === void 0 || setting.value === void 0) {
|
|
308
|
+
response.status(400).json("Bad Request: 'id' and 'value' are required");
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (!isValidSetting(setting.value)) {
|
|
312
|
+
response.status(400).json("Bad Request: 'value' is invalid. Valid options are 'backstage', 'pagerduty', 'both' or 'disabled'");
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
await store.updateSetting(setting);
|
|
316
|
+
}));
|
|
317
|
+
response.sendStatus(200);
|
|
318
|
+
} catch (error) {
|
|
319
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
320
|
+
logger.error(`Error occurred while processing request: ${error.message}`);
|
|
321
|
+
response.status(error.status).json({
|
|
322
|
+
errors: [
|
|
323
|
+
`${error.message}`
|
|
324
|
+
]
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
router.get("/settings/:settingId", async (request, response) => {
|
|
330
|
+
try {
|
|
331
|
+
const settingId = request.params.settingId;
|
|
332
|
+
const setting = await store.findSetting(settingId);
|
|
333
|
+
if (!setting) {
|
|
334
|
+
response.status(404).json({});
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
response.json(setting);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
340
|
+
response.status(error.status).json({
|
|
341
|
+
errors: [
|
|
342
|
+
`${error.message}`
|
|
343
|
+
]
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
function isValidSetting(value) {
|
|
349
|
+
if (value === "backstage" || value === "pagerduty" || value === "both" || value === "disabled") {
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
router.post("/mapping/entity", async (request, response) => {
|
|
355
|
+
try {
|
|
356
|
+
const entity = request.body;
|
|
357
|
+
if (!entity.serviceId) {
|
|
358
|
+
response.status(400).json("Bad Request: 'serviceId' must be provided as part of the request body");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const entityMappings = await store.getAllEntityMappings();
|
|
362
|
+
const oldMapping = entityMappings.find((mapping) => mapping.serviceId === entity.serviceId);
|
|
363
|
+
if (entity.entityRef !== "" && (entity.integrationKey === "" || entity.integrationKey === void 0)) {
|
|
364
|
+
const backstageVendorId = "PRO19CT";
|
|
365
|
+
const service = await pagerduty.getServiceById(entity.serviceId, entity.account);
|
|
366
|
+
const backstageIntegration = service.integrations?.find((integration) => integration.vendor?.id === backstageVendorId);
|
|
367
|
+
if (!backstageIntegration) {
|
|
368
|
+
const integrationKey = await pagerduty.createServiceIntegration({
|
|
369
|
+
serviceId: entity.serviceId,
|
|
370
|
+
vendorId: backstageVendorId,
|
|
371
|
+
account: entity.account
|
|
372
|
+
});
|
|
373
|
+
entity.integrationKey = integrationKey;
|
|
374
|
+
} else {
|
|
375
|
+
entity.integrationKey = backstageIntegration.integration_key;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const entityMappingId = await store.insertEntityMapping(entity);
|
|
379
|
+
if (entity.entityRef !== "") {
|
|
380
|
+
await catalogApi?.refreshEntity(entity.entityRef);
|
|
381
|
+
}
|
|
382
|
+
if (oldMapping && oldMapping.entityRef !== "") {
|
|
383
|
+
await catalogApi?.refreshEntity(oldMapping.entityRef);
|
|
384
|
+
}
|
|
385
|
+
response.json({
|
|
386
|
+
id: entityMappingId,
|
|
387
|
+
entityRef: entity.entityRef,
|
|
388
|
+
integrationKey: entity.integrationKey,
|
|
389
|
+
serviceId: entity.serviceId,
|
|
390
|
+
status: entity.status,
|
|
391
|
+
account: entity.account
|
|
392
|
+
});
|
|
393
|
+
} catch (error) {
|
|
394
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
395
|
+
logger.error(`Error occurred while processing request: ${error.message}`);
|
|
396
|
+
response.status(error.status).json({
|
|
397
|
+
errors: [
|
|
398
|
+
`${error.message}`
|
|
399
|
+
]
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
router.get("/mapping/entity", async (_, response) => {
|
|
405
|
+
try {
|
|
406
|
+
const entityMappings = await store.getAllEntityMappings();
|
|
407
|
+
const componentEntities = await catalogApi.getEntities({
|
|
408
|
+
filter: {
|
|
409
|
+
kind: "Component"
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
const componentEntitiesDict = await createComponentEntitiesReferenceDict(componentEntities);
|
|
413
|
+
const pagerDutyServices = await pagerduty.getAllServices();
|
|
414
|
+
const result = await buildEntityMappingsResponse(entityMappings, componentEntitiesDict, componentEntities, pagerDutyServices);
|
|
415
|
+
response.json(result);
|
|
416
|
+
} catch (error) {
|
|
417
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
418
|
+
response.status(error.status).json({
|
|
419
|
+
errors: [
|
|
420
|
+
`${error.message}`
|
|
421
|
+
]
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
router.get("/mapping/entity/:type/:namespace/:name", async (request, response) => {
|
|
427
|
+
try {
|
|
428
|
+
const entityType = request.params.type || "";
|
|
429
|
+
const entityNamespace = request.params.namespace || "";
|
|
430
|
+
const entityName = request.params.name || "";
|
|
431
|
+
if (entityType === "" || entityNamespace === "" || entityName === "") {
|
|
432
|
+
response.status(400).json("Required params not specified.");
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
const entityRef = `${entityType}:${entityNamespace}/${entityName}`.toLowerCase();
|
|
436
|
+
const entityMapping = await store.findEntityMappingByEntityRef(entityRef);
|
|
437
|
+
if (!entityMapping) {
|
|
438
|
+
response.status(404).json(`Mapping for entityRef ${entityRef} not found.`);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
response.json({
|
|
442
|
+
mapping: entityMapping
|
|
443
|
+
});
|
|
444
|
+
} catch (error) {
|
|
445
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
446
|
+
response.status(error.status).json({
|
|
447
|
+
errors: [
|
|
448
|
+
`${error.message}`
|
|
449
|
+
]
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
router.get("/mapping/entity/service/:serviceId", async (request, response) => {
|
|
455
|
+
try {
|
|
456
|
+
const serviceId = request.params.serviceId ?? "";
|
|
457
|
+
if (serviceId === "") {
|
|
458
|
+
response.status(400).json("Required params not specified.");
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const entityMapping = await store.findEntityMappingByServiceId(serviceId);
|
|
462
|
+
if (!entityMapping) {
|
|
463
|
+
response.status(404).json(`Mapping for serviceId ${serviceId} not found.`);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
response.json({
|
|
467
|
+
mapping: entityMapping
|
|
468
|
+
});
|
|
469
|
+
} catch (error) {
|
|
470
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
471
|
+
response.status(error.status).json({
|
|
472
|
+
errors: [
|
|
473
|
+
`${error.message}`
|
|
474
|
+
]
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
router.get("/escalation_policies", async (_, response) => {
|
|
480
|
+
try {
|
|
481
|
+
let escalationPolicyList = await pagerduty.getAllEscalationPolicies();
|
|
482
|
+
escalationPolicyList = escalationPolicyList.sort((a, b) => {
|
|
483
|
+
if (a.account === b.account) {
|
|
484
|
+
return a.name.localeCompare(b.name);
|
|
485
|
+
}
|
|
486
|
+
return a.account.localeCompare(b.account);
|
|
487
|
+
});
|
|
488
|
+
const escalationPolicyDropDownOptions = escalationPolicyList.map((policy) => {
|
|
489
|
+
let policyLabel = policy.name;
|
|
490
|
+
if (policy.account && policy.account !== "default") {
|
|
491
|
+
policyLabel = `(${policy.account}) ${policy.name}`;
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
label: policyLabel,
|
|
495
|
+
value: policy.id
|
|
496
|
+
};
|
|
497
|
+
});
|
|
498
|
+
response.json(escalationPolicyDropDownOptions);
|
|
499
|
+
} catch (error) {
|
|
500
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
501
|
+
response.status(error.status).json({
|
|
502
|
+
errors: [
|
|
503
|
+
`${error.message}`
|
|
504
|
+
]
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
router.get("/oncall-users", async (request, response) => {
|
|
510
|
+
try {
|
|
511
|
+
const escalationPolicyId = request.query.escalation_policy_ids || "";
|
|
512
|
+
const account = request.query.account || "";
|
|
513
|
+
if (escalationPolicyId === "") {
|
|
514
|
+
response.status(400).json("Bad Request: 'escalation_policy_ids[]' is required");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const oncallUsers = await pagerduty.getOncallUsers(escalationPolicyId, account);
|
|
518
|
+
const onCallUsersResponse = {
|
|
519
|
+
users: oncallUsers
|
|
520
|
+
};
|
|
521
|
+
response.json(onCallUsersResponse);
|
|
522
|
+
} catch (error) {
|
|
523
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
524
|
+
response.status(error.status).json({
|
|
525
|
+
errors: [
|
|
526
|
+
`${error.message}`
|
|
527
|
+
]
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
router.get("/services/:serviceId", async (request, response) => {
|
|
533
|
+
try {
|
|
534
|
+
const serviceId = request.params.serviceId || "";
|
|
535
|
+
const account = request.query.account || "";
|
|
536
|
+
if (serviceId === "") {
|
|
537
|
+
response.status(400).json("Bad Request: ':serviceId' must be provided as part of the path or 'integration_key' as a query parameter");
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const service = await pagerduty.getServiceById(serviceId, account);
|
|
541
|
+
const serviceResponse = {
|
|
542
|
+
service
|
|
543
|
+
};
|
|
544
|
+
response.json(serviceResponse);
|
|
545
|
+
} catch (error) {
|
|
546
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
547
|
+
response.status(error.status).json({
|
|
548
|
+
errors: [
|
|
549
|
+
`${error.message}`
|
|
550
|
+
]
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
router.get("/services", async (request, response) => {
|
|
556
|
+
try {
|
|
557
|
+
const integrationKey = request.query.integration_key || "";
|
|
558
|
+
const account = request.query.account || "";
|
|
559
|
+
if (integrationKey !== "") {
|
|
560
|
+
const service = await pagerduty.getServiceByIntegrationKey(integrationKey, account);
|
|
561
|
+
const serviceResponse = {
|
|
562
|
+
service
|
|
563
|
+
};
|
|
564
|
+
response.json(serviceResponse);
|
|
565
|
+
} else {
|
|
566
|
+
const services = await pagerduty.getAllServices();
|
|
567
|
+
const servicesResponse = {
|
|
568
|
+
services
|
|
569
|
+
};
|
|
570
|
+
response.json(servicesResponse);
|
|
571
|
+
}
|
|
572
|
+
} catch (error) {
|
|
573
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
574
|
+
response.status(error.status).json({
|
|
575
|
+
errors: [
|
|
576
|
+
`${error.message}`
|
|
577
|
+
]
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
router.post("/services/:serviceId/integration/:vendorId", async (request, response) => {
|
|
583
|
+
try {
|
|
584
|
+
const serviceId = request.params.serviceId || "";
|
|
585
|
+
const vendorId = request.params.vendorId || "";
|
|
586
|
+
const account = request.query.account || "";
|
|
587
|
+
if (serviceId === "" || vendorId === "") {
|
|
588
|
+
response.status(400).json("Bad Request: ':serviceId' and ':vendorId' must be provided as part of the path");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const integrationKey = await pagerduty.createServiceIntegration({
|
|
592
|
+
serviceId,
|
|
593
|
+
vendorId,
|
|
594
|
+
account
|
|
595
|
+
});
|
|
596
|
+
response.json(integrationKey);
|
|
597
|
+
} catch (error) {
|
|
598
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
599
|
+
logger.error(`Error occurred while processing request: ${error.message}`);
|
|
600
|
+
response.status(error.status).json({
|
|
601
|
+
errors: [
|
|
602
|
+
`${error.message}`
|
|
603
|
+
]
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
router.get("/services/:serviceId/change-events", async (request, response) => {
|
|
609
|
+
try {
|
|
610
|
+
const serviceId = request.params.serviceId || "";
|
|
611
|
+
const account = request.query.account || "";
|
|
612
|
+
const changeEvents = await pagerduty.getChangeEvents(serviceId, account);
|
|
613
|
+
const changeEventsResponse = {
|
|
614
|
+
change_events: changeEvents
|
|
615
|
+
};
|
|
616
|
+
response.json(changeEventsResponse);
|
|
617
|
+
} catch (error) {
|
|
618
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
619
|
+
response.status(error.status).json({
|
|
620
|
+
errors: [
|
|
621
|
+
`${error.message}`
|
|
622
|
+
]
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
router.get("/services/:serviceId/incidents", async (request, response) => {
|
|
628
|
+
try {
|
|
629
|
+
const serviceId = request.params.serviceId || "";
|
|
630
|
+
const account = request.query.account || "";
|
|
631
|
+
const incidents = await pagerduty.getIncidents(serviceId, account);
|
|
632
|
+
const incidentsResponse = {
|
|
633
|
+
incidents
|
|
634
|
+
};
|
|
635
|
+
response.json(incidentsResponse);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
638
|
+
response.status(error.status).json({
|
|
639
|
+
errors: [
|
|
640
|
+
`${error.message}`
|
|
641
|
+
]
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
router.get("/services/:serviceId/standards", async (request, response) => {
|
|
647
|
+
try {
|
|
648
|
+
const serviceId = request.params.serviceId || "";
|
|
649
|
+
const account = request.query.account || "";
|
|
650
|
+
const serviceStandards = await pagerduty.getServiceStandards(serviceId, account);
|
|
651
|
+
const serviceStandardsResponse = {
|
|
652
|
+
standards: serviceStandards
|
|
653
|
+
};
|
|
654
|
+
response.json(serviceStandardsResponse);
|
|
655
|
+
} catch (error) {
|
|
656
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
657
|
+
response.status(error.status).json({
|
|
658
|
+
errors: [
|
|
659
|
+
`${error.message}`
|
|
660
|
+
]
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
router.get("/services/:serviceId/metrics", async (request, response) => {
|
|
666
|
+
try {
|
|
667
|
+
const serviceId = request.params.serviceId || "";
|
|
668
|
+
const account = request.query.account || "";
|
|
669
|
+
const metrics = await pagerduty.getServiceMetrics(serviceId, account);
|
|
670
|
+
const metricsResponse = {
|
|
671
|
+
metrics
|
|
672
|
+
};
|
|
673
|
+
response.json(metricsResponse);
|
|
674
|
+
} catch (error) {
|
|
675
|
+
if (error instanceof backstagePluginCommon.HttpError) {
|
|
676
|
+
response.status(error.status).json({
|
|
677
|
+
errors: [
|
|
678
|
+
`${error.message}`
|
|
679
|
+
]
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
router.get("/health", async (_, response) => {
|
|
685
|
+
response.status(200).json({ status: "ok" });
|
|
686
|
+
});
|
|
687
|
+
router.use(backendCommon.errorHandler());
|
|
688
|
+
return router;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
exports.buildEntityMappingsResponse = buildEntityMappingsResponse;
|
|
692
|
+
exports.createComponentEntitiesReferenceDict = createComponentEntitiesReferenceDict;
|
|
693
|
+
exports.createRouter = createRouter;
|
|
694
|
+
//# sourceMappingURL=router.cjs.js.map
|