@pagerduty/backstage-plugin-scaffolder-actions 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.d.ts +32 -29
- package/dist/actions/custom.cjs.js +83 -0
- package/dist/actions/custom.cjs.js.map +1 -0
- package/dist/apis/pagerduty.cjs.js +451 -0
- package/dist/apis/pagerduty.cjs.js.map +1 -0
- package/dist/auth/auth.cjs.js +260 -0
- package/dist/auth/auth.cjs.js.map +1 -0
- package/dist/index.cjs.js +4 -664
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/module.cjs.js +30 -0
- package/dist/module.cjs.js.map +1 -0
- package/package.json +25 -20
- package/LICENSE +0 -201
- package/README.md +0 -42
package/dist/index.cjs.js
CHANGED
|
@@ -2,671 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
8
|
-
var zod = require('zod');
|
|
9
|
-
var fetch$1 = require('node-fetch');
|
|
10
|
-
var backstagePluginCommon = require('@pagerduty/backstage-plugin-common');
|
|
11
|
-
var backendCommon = require('@backstage/backend-common');
|
|
5
|
+
var module$1 = require('./module.cjs.js');
|
|
6
|
+
var custom = require('./actions/custom.cjs.js');
|
|
12
7
|
|
|
13
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
14
8
|
|
|
15
|
-
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch$1);
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let _config$1;
|
|
20
|
-
let _legacyConfig$1;
|
|
21
|
-
let _logger$1;
|
|
22
|
-
async function getAuthToken(accountId) {
|
|
23
|
-
if (!authPersistence?.accountTokens) {
|
|
24
|
-
_logger$1.debug("Auth config not loaded. Loading auth config...");
|
|
25
|
-
await loadAuthConfig({
|
|
26
|
-
config: _config$1,
|
|
27
|
-
legacyConfig: _legacyConfig$1,
|
|
28
|
-
logger: _logger$1
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (isLegacyConfig$1) {
|
|
32
|
-
_logger$1.debug("Using legacy config for auth token retrieval.");
|
|
33
|
-
if (authPersistence.accountTokens.default.authToken !== "" && authPersistence.accountTokens.default.authToken.includes("Bearer") && authPersistence.accountTokens.default.authTokenExpiryDate > Date.now() || authPersistence.accountTokens.default.authToken !== "" && authPersistence.accountTokens.default.authToken.includes("Token")) {
|
|
34
|
-
return authPersistence.accountTokens.default.authToken;
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
_logger$1.debug("Using new config for auth token retrieval.");
|
|
38
|
-
if (accountId && accountId !== "") {
|
|
39
|
-
if (authPersistence.accountTokens[accountId].authToken !== "" && authPersistence.accountTokens[accountId].authToken.includes("Bearer") && authPersistence.accountTokens[accountId].authTokenExpiryDate > Date.now() || authPersistence.accountTokens[accountId].authToken !== "" && authPersistence.accountTokens[accountId].authToken.includes("Token")) {
|
|
40
|
-
return authPersistence.accountTokens[accountId].authToken;
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
const defaultFallback = authPersistence.defaultAccount ?? "";
|
|
44
|
-
_logger$1.debug("No account ID provided. Using default account token.");
|
|
45
|
-
if (authPersistence.accountTokens[defaultFallback].authToken !== "" && authPersistence.accountTokens[defaultFallback].authToken.includes("Bearer") && authPersistence.accountTokens[defaultFallback].authTokenExpiryDate > Date.now() || authPersistence.accountTokens[defaultFallback].authToken !== "" && authPersistence.accountTokens[defaultFallback].authToken.includes("Token")) {
|
|
46
|
-
return authPersistence.accountTokens[defaultFallback].authToken;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return "";
|
|
51
|
-
}
|
|
52
|
-
async function loadAuthConfig({ config, legacyConfig, logger }) {
|
|
53
|
-
try {
|
|
54
|
-
const defaultAccountId = "default";
|
|
55
|
-
_config$1 = config;
|
|
56
|
-
_legacyConfig$1 = legacyConfig;
|
|
57
|
-
_logger$1 = logger;
|
|
58
|
-
authPersistence = {
|
|
59
|
-
accountTokens: {}
|
|
60
|
-
};
|
|
61
|
-
if (!readOptionalObject$1("pagerDuty.accounts")) {
|
|
62
|
-
isLegacyConfig$1 = true;
|
|
63
|
-
logger.warn("No PagerDuty accounts configuration found in config file. Reverting to legacy configuration.");
|
|
64
|
-
if (!readOptionalString$1("pagerDuty.apiToken")) {
|
|
65
|
-
logger.warn("No PagerDuty API token found in config file. Trying OAuth token instead...");
|
|
66
|
-
if (!readOptionalObject$1("pagerDuty.oauth")) {
|
|
67
|
-
logger.error("No PagerDuty OAuth configuration found in config file.");
|
|
68
|
-
} else if (!readOptionalString$1("pagerDuty.oauth.clientId") || !readOptionalString$1("pagerDuty.oauth.clientSecret") || !readOptionalString$1("pagerDuty.oauth.subDomain")) {
|
|
69
|
-
logger.error("Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.");
|
|
70
|
-
} else {
|
|
71
|
-
const tokenInfo = await getOAuthToken(
|
|
72
|
-
readString$1("pagerDuty.oauth.clientId"),
|
|
73
|
-
readString$1("pagerDuty.oauth.clientSecret"),
|
|
74
|
-
readString$1("pagerDuty.oauth.subDomain"),
|
|
75
|
-
readOptionalString$1("pagerDuty.oauth.region") ?? "us"
|
|
76
|
-
);
|
|
77
|
-
authPersistence.accountTokens[defaultAccountId] = tokenInfo;
|
|
78
|
-
logger.debug("PagerDuty OAuth configuration loaded successfully.");
|
|
79
|
-
}
|
|
80
|
-
} else {
|
|
81
|
-
authPersistence.accountTokens[defaultAccountId] = {
|
|
82
|
-
authToken: `Token token=${readOptionalString$1("pagerDuty.apiToken")}`,
|
|
83
|
-
authTokenExpiryDate: Date.now() + 36e5 * 24 * 365 * 2
|
|
84
|
-
// 2 years
|
|
85
|
-
};
|
|
86
|
-
logger.debug("PagerDuty API token loaded successfully.");
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
logger.debug("New PagerDuty accounts configuration found in config file.");
|
|
90
|
-
isLegacyConfig$1 = false;
|
|
91
|
-
const accounts = JSON.parse(JSON.stringify(readOptionalObject$1("pagerDuty.accounts")));
|
|
92
|
-
if (accounts && accounts?.length === 1) {
|
|
93
|
-
logger.debug("Only one account found in config file. Setting it as default.");
|
|
94
|
-
authPersistence.defaultAccount = accounts[0].id;
|
|
95
|
-
}
|
|
96
|
-
await Promise.all(
|
|
97
|
-
accounts?.map(async (account) => {
|
|
98
|
-
const maskedAccountId = maskString(account.id);
|
|
99
|
-
if (account.isDefault && !authPersistence.defaultAccount) {
|
|
100
|
-
logger.debug(`Default account found in config file. Setting it as default.`);
|
|
101
|
-
authPersistence.defaultAccount = account.id;
|
|
102
|
-
}
|
|
103
|
-
if (!account.apiToken) {
|
|
104
|
-
logger.warn("No PagerDuty API token found in config file. Trying OAuth token instead...");
|
|
105
|
-
if (!account.oauth) {
|
|
106
|
-
logger.error("No PagerDuty OAuth configuration found in config file.");
|
|
107
|
-
} else if (!account.oauth.clientId || !account.oauth.clientSecret || !account.oauth.subDomain) {
|
|
108
|
-
logger.error("Missing required PagerDuty OAuth parameters in config file. 'clientId', 'clientSecret', and 'subDomain' are required. 'region' is optional.");
|
|
109
|
-
} else {
|
|
110
|
-
const tokenInfo = await getOAuthToken(
|
|
111
|
-
account.oauth.clientId,
|
|
112
|
-
account.oauth.clientSecret,
|
|
113
|
-
account.oauth.subDomain,
|
|
114
|
-
account.oauth.region ?? "us"
|
|
115
|
-
);
|
|
116
|
-
authPersistence.accountTokens[account.id] = tokenInfo;
|
|
117
|
-
logger.debug(`PagerDuty OAuth configuration loaded successfully for account ${maskedAccountId}.`);
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
authPersistence.accountTokens[account.id] = {
|
|
121
|
-
authToken: `Token token=${account.apiToken}`,
|
|
122
|
-
authTokenExpiryDate: Date.now() + 36e5 * 24 * 365 * 2
|
|
123
|
-
// 2 years
|
|
124
|
-
};
|
|
125
|
-
logger.debug(`PagerDuty API token loaded successfully for account ${maskedAccountId}.`);
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
if (!authPersistence.defaultAccount) {
|
|
130
|
-
logger.error("No default account found in config file. One account must be marked as default.");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
} catch (error) {
|
|
134
|
-
logger.error(`Unable to retrieve valid PagerDuty AUTH configuration from config file: ${error}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
function readOptionalString$1(key) {
|
|
138
|
-
if (!_config$1) {
|
|
139
|
-
return _legacyConfig$1.getOptionalString(key);
|
|
140
|
-
}
|
|
141
|
-
return _config$1.getOptionalString(key);
|
|
142
|
-
}
|
|
143
|
-
function readOptionalObject$1(key) {
|
|
144
|
-
if (!_config$1) {
|
|
145
|
-
return _legacyConfig$1.getOptional(key);
|
|
146
|
-
}
|
|
147
|
-
return _config$1.getOptional(key);
|
|
148
|
-
}
|
|
149
|
-
function readString$1(key) {
|
|
150
|
-
if (!_config$1) {
|
|
151
|
-
return _legacyConfig$1.getString(key);
|
|
152
|
-
}
|
|
153
|
-
return _config$1.getString(key);
|
|
154
|
-
}
|
|
155
|
-
async function getOAuthToken(clientId, clientSecret, subDomain, region) {
|
|
156
|
-
if (!clientId || !clientSecret || !subDomain) {
|
|
157
|
-
throw new Error("Missing required PagerDuty OAuth parameters.");
|
|
158
|
-
}
|
|
159
|
-
const scopes = `
|
|
160
|
-
abilities.read
|
|
161
|
-
analytics.read
|
|
162
|
-
change_events.read
|
|
163
|
-
escalation_policies.read
|
|
164
|
-
incidents.read
|
|
165
|
-
oncalls.read
|
|
166
|
-
schedules.read
|
|
167
|
-
services.read
|
|
168
|
-
services.write
|
|
169
|
-
standards.read
|
|
170
|
-
teams.read
|
|
171
|
-
users.read
|
|
172
|
-
vendors.read
|
|
173
|
-
`;
|
|
174
|
-
const urlencoded = new URLSearchParams();
|
|
175
|
-
urlencoded.append("grant_type", "client_credentials");
|
|
176
|
-
urlencoded.append("client_id", clientId);
|
|
177
|
-
urlencoded.append("client_secret", clientSecret);
|
|
178
|
-
urlencoded.append("scope", `as_account-${region}.${subDomain} ${scopes}`);
|
|
179
|
-
let response;
|
|
180
|
-
const options = {
|
|
181
|
-
method: "POST",
|
|
182
|
-
headers: {
|
|
183
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
184
|
-
},
|
|
185
|
-
body: urlencoded
|
|
186
|
-
};
|
|
187
|
-
const baseUrl = "https://identity.pagerduty.com/oauth/token";
|
|
188
|
-
try {
|
|
189
|
-
response = await fetch(baseUrl, options);
|
|
190
|
-
} catch (error) {
|
|
191
|
-
throw new Error(`Failed to retrieve oauth token: ${error}`);
|
|
192
|
-
}
|
|
193
|
-
switch (response.status) {
|
|
194
|
-
case 400:
|
|
195
|
-
throw new backstagePluginCommon.HttpError("Failed to retrieve valid token. Bad Request - Invalid arguments provided.", 400);
|
|
196
|
-
case 401:
|
|
197
|
-
throw new backstagePluginCommon.HttpError("Failed to retrieve valid token. Forbidden - Invalid credentials provided.", 401);
|
|
198
|
-
}
|
|
199
|
-
const authResponse = await response.json();
|
|
200
|
-
const result = {
|
|
201
|
-
authToken: `Bearer ${authResponse.access_token}`,
|
|
202
|
-
authTokenExpiryDate: Date.now() + authResponse.expires_in * 1e3
|
|
203
|
-
};
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
function maskString(str) {
|
|
207
|
-
return str[0] + "*".repeat(str.length - 2) + str.slice(-1);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const EndpointConfig = {};
|
|
211
|
-
let fallbackEndpointConfig;
|
|
212
|
-
let isLegacyConfig = false;
|
|
213
|
-
let _config;
|
|
214
|
-
let _legacyConfig;
|
|
215
|
-
let _logger;
|
|
216
|
-
function setFallbackEndpointConfig(account) {
|
|
217
|
-
fallbackEndpointConfig = {
|
|
218
|
-
eventsBaseUrl: account.eventsBaseUrl !== void 0 ? account.eventsBaseUrl : "https://events.pagerduty.com/v2",
|
|
219
|
-
apiBaseUrl: account.apiBaseUrl !== void 0 ? account.apiBaseUrl : "https://api.pagerduty.com"
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
function insertEndpointConfig(account) {
|
|
223
|
-
EndpointConfig[account.id] = {
|
|
224
|
-
eventsBaseUrl: account.eventsBaseUrl !== void 0 ? account.eventsBaseUrl : "https://events.pagerduty.com/v2",
|
|
225
|
-
apiBaseUrl: account.apiBaseUrl !== void 0 ? account.apiBaseUrl : "https://api.pagerduty.com"
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function loadPagerDutyEndpointsFromConfig({ config, legacyConfig, logger }) {
|
|
229
|
-
_config = config;
|
|
230
|
-
_legacyConfig = legacyConfig;
|
|
231
|
-
_logger = logger;
|
|
232
|
-
if (readOptionalObject("pagerDuty.accounts")) {
|
|
233
|
-
_logger.debug(`New accounts configuration detected. Loading PagerDuty endpoints from config.`);
|
|
234
|
-
isLegacyConfig = false;
|
|
235
|
-
const accounts = JSON.parse(JSON.stringify(readOptionalObject("pagerDuty.accounts")));
|
|
236
|
-
if (accounts?.length === 1) {
|
|
237
|
-
_logger.debug(`Single account configuration detected. Loading PagerDuty endpoints from config to 'default'.`);
|
|
238
|
-
EndpointConfig.default = {
|
|
239
|
-
eventsBaseUrl: accounts[0].eventsBaseUrl !== void 0 ? accounts[0].eventsBaseUrl : "https://events.pagerduty.com/v2",
|
|
240
|
-
apiBaseUrl: accounts[0].apiBaseUrl !== void 0 ? accounts[0].apiBaseUrl : "https://api.pagerduty.com"
|
|
241
|
-
};
|
|
242
|
-
} else {
|
|
243
|
-
_logger.debug(`Multiple account configuration detected. Loading PagerDuty endpoints from config.`);
|
|
244
|
-
accounts?.forEach((account) => {
|
|
245
|
-
if (account.isDefault) {
|
|
246
|
-
setFallbackEndpointConfig(account);
|
|
247
|
-
}
|
|
248
|
-
insertEndpointConfig(account);
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
} else {
|
|
252
|
-
_logger.debug(`Loading legacy PagerDuty endpoints from config.`);
|
|
253
|
-
isLegacyConfig = true;
|
|
254
|
-
EndpointConfig.default = {
|
|
255
|
-
eventsBaseUrl: readOptionalString("pagerDuty.eventsBaseUrl") !== void 0 ? readString("pagerDuty.eventsBaseUrl") : "https://events.pagerduty.com/v2",
|
|
256
|
-
apiBaseUrl: readOptionalString("pagerDuty.apiBaseUrl") !== void 0 ? readString("pagerDuty.apiBaseUrl") : "https://api.pagerduty.com"
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
function getApiBaseUrl(account) {
|
|
261
|
-
if (isLegacyConfig === true) {
|
|
262
|
-
return EndpointConfig.default.apiBaseUrl;
|
|
263
|
-
}
|
|
264
|
-
if (account) {
|
|
265
|
-
return EndpointConfig[account].apiBaseUrl;
|
|
266
|
-
}
|
|
267
|
-
return fallbackEndpointConfig.apiBaseUrl;
|
|
268
|
-
}
|
|
269
|
-
async function createService({ name, description, escalationPolicyId, account, alertGrouping }) {
|
|
270
|
-
let alertGroupingParameters = "null";
|
|
271
|
-
let response;
|
|
272
|
-
const apiBaseUrl = getApiBaseUrl(account);
|
|
273
|
-
const baseUrl = `${apiBaseUrl}/services`;
|
|
274
|
-
let body = JSON.stringify({
|
|
275
|
-
service: {
|
|
276
|
-
type: "service",
|
|
277
|
-
name,
|
|
278
|
-
description,
|
|
279
|
-
alert_creation: "create_alerts_and_incidents",
|
|
280
|
-
auto_pause_notifications_parameters: {
|
|
281
|
-
enabled: true,
|
|
282
|
-
timeout: 300
|
|
283
|
-
},
|
|
284
|
-
escalation_policy: {
|
|
285
|
-
id: escalationPolicyId,
|
|
286
|
-
type: "escalation_policy_reference"
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
if (await isEventNoiseReductionEnabled(account) && alertGrouping !== void 0) {
|
|
291
|
-
alertGroupingParameters = alertGrouping;
|
|
292
|
-
switch (alertGroupingParameters) {
|
|
293
|
-
case "intelligent":
|
|
294
|
-
body = JSON.stringify({
|
|
295
|
-
service: {
|
|
296
|
-
type: "service",
|
|
297
|
-
name,
|
|
298
|
-
description,
|
|
299
|
-
escalation_policy: {
|
|
300
|
-
id: escalationPolicyId,
|
|
301
|
-
type: "escalation_policy_reference"
|
|
302
|
-
},
|
|
303
|
-
alert_creation: "create_alerts_and_incidents",
|
|
304
|
-
alert_grouping_parameters: {
|
|
305
|
-
type: alertGroupingParameters
|
|
306
|
-
},
|
|
307
|
-
auto_pause_notifications_parameters: {
|
|
308
|
-
enabled: true,
|
|
309
|
-
timeout: 300
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
break;
|
|
314
|
-
case "time":
|
|
315
|
-
body = JSON.stringify({
|
|
316
|
-
service: {
|
|
317
|
-
type: "service",
|
|
318
|
-
name,
|
|
319
|
-
description,
|
|
320
|
-
escalation_policy: {
|
|
321
|
-
id: escalationPolicyId,
|
|
322
|
-
type: "escalation_policy_reference"
|
|
323
|
-
},
|
|
324
|
-
alert_creation: "create_alerts_and_incidents",
|
|
325
|
-
alert_grouping_parameters: {
|
|
326
|
-
type: alertGroupingParameters,
|
|
327
|
-
config: {
|
|
328
|
-
timeout: 0
|
|
329
|
-
}
|
|
330
|
-
},
|
|
331
|
-
auto_pause_notifications_parameters: {
|
|
332
|
-
enabled: true,
|
|
333
|
-
timeout: 300
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
break;
|
|
338
|
-
case "content_based":
|
|
339
|
-
body = JSON.stringify({
|
|
340
|
-
service: {
|
|
341
|
-
type: "service",
|
|
342
|
-
name,
|
|
343
|
-
description,
|
|
344
|
-
escalation_policy: {
|
|
345
|
-
id: escalationPolicyId,
|
|
346
|
-
type: "escalation_policy_reference"
|
|
347
|
-
},
|
|
348
|
-
alert_creation: "create_alerts_and_incidents",
|
|
349
|
-
alert_grouping_parameters: {
|
|
350
|
-
type: alertGroupingParameters,
|
|
351
|
-
config: {
|
|
352
|
-
aggregate: "all",
|
|
353
|
-
time_window: 0,
|
|
354
|
-
fields: [
|
|
355
|
-
"source",
|
|
356
|
-
"summary"
|
|
357
|
-
]
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
auto_pause_notifications_parameters: {
|
|
361
|
-
enabled: true,
|
|
362
|
-
timeout: 300
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
break;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
const token = await getAuthToken(account);
|
|
370
|
-
const options = {
|
|
371
|
-
method: "POST",
|
|
372
|
-
body,
|
|
373
|
-
headers: {
|
|
374
|
-
Authorization: token,
|
|
375
|
-
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
376
|
-
"Content-Type": "application/json"
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
try {
|
|
380
|
-
response = await fetch__default.default(baseUrl, options);
|
|
381
|
-
} catch (error) {
|
|
382
|
-
throw new Error(`Failed to create service: ${error}`);
|
|
383
|
-
}
|
|
384
|
-
switch (response.status) {
|
|
385
|
-
case 400:
|
|
386
|
-
throw new Error(`Failed to create service. Caller provided invalid arguments.`);
|
|
387
|
-
case 401:
|
|
388
|
-
throw new Error(`Failed to create service. Caller did not supply credentials or did not provide the correct credentials.`);
|
|
389
|
-
case 402:
|
|
390
|
-
throw new Error(`Failed to create service. Account does not have the abilities to perform the action.`);
|
|
391
|
-
case 403:
|
|
392
|
-
throw new Error(`Failed to create service. Caller is not authorized to view the requested resource.`);
|
|
393
|
-
}
|
|
394
|
-
let result;
|
|
395
|
-
try {
|
|
396
|
-
result = await response.json();
|
|
397
|
-
const createServiceResult = {
|
|
398
|
-
url: result.service.html_url,
|
|
399
|
-
id: result.service.id,
|
|
400
|
-
alertGrouping: alertGroupingParameters
|
|
401
|
-
};
|
|
402
|
-
return createServiceResult;
|
|
403
|
-
} catch (error) {
|
|
404
|
-
throw new Error(`Failed to parse service information: ${error}`);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
async function createServiceIntegration({ serviceId, vendorId, account }) {
|
|
408
|
-
let response;
|
|
409
|
-
const apiBaseUrl = getApiBaseUrl(account);
|
|
410
|
-
const baseUrl = `${apiBaseUrl}/services`;
|
|
411
|
-
const token = await getAuthToken(account);
|
|
412
|
-
const options = {
|
|
413
|
-
method: "POST",
|
|
414
|
-
body: JSON.stringify({
|
|
415
|
-
integration: {
|
|
416
|
-
name: "Backstage",
|
|
417
|
-
service: {
|
|
418
|
-
id: serviceId,
|
|
419
|
-
type: "service_reference"
|
|
420
|
-
},
|
|
421
|
-
vendor: {
|
|
422
|
-
id: vendorId,
|
|
423
|
-
type: "vendor_reference"
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}),
|
|
427
|
-
headers: {
|
|
428
|
-
Authorization: token,
|
|
429
|
-
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
430
|
-
"Content-Type": "application/json"
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
try {
|
|
434
|
-
response = await fetch__default.default(`${baseUrl}/${serviceId}/integrations`, options);
|
|
435
|
-
} catch (error) {
|
|
436
|
-
throw new Error(`Failed to create service integration: ${error}`);
|
|
437
|
-
}
|
|
438
|
-
switch (response.status) {
|
|
439
|
-
case 400:
|
|
440
|
-
throw new Error(`Failed to create service integration. Caller provided invalid arguments.`);
|
|
441
|
-
case 401:
|
|
442
|
-
throw new Error(`Failed to create service integration. Caller did not supply credentials or did not provide the correct credentials.`);
|
|
443
|
-
case 403:
|
|
444
|
-
throw new Error(`Failed to create service integration. Caller is not authorized to view the requested resource.`);
|
|
445
|
-
case 429:
|
|
446
|
-
throw new Error(`Failed to create service integration. Rate limit exceeded.`);
|
|
447
|
-
}
|
|
448
|
-
let result;
|
|
449
|
-
try {
|
|
450
|
-
result = await response.json();
|
|
451
|
-
return result.integration.integration_key ?? "";
|
|
452
|
-
} catch (error) {
|
|
453
|
-
throw new Error(`Failed to parse service information: ${error}`);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
async function isEventNoiseReductionEnabled(account) {
|
|
457
|
-
let response;
|
|
458
|
-
const baseUrl = getApiBaseUrl(account);
|
|
459
|
-
const token = await getAuthToken(account);
|
|
460
|
-
const options = {
|
|
461
|
-
method: "GET",
|
|
462
|
-
headers: {
|
|
463
|
-
Authorization: token,
|
|
464
|
-
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
465
|
-
"Content-Type": "application/json"
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
try {
|
|
469
|
-
response = await fetch__default.default(`${baseUrl}/abilities`, options);
|
|
470
|
-
} catch (error) {
|
|
471
|
-
throw new Error(`Failed to read abilities: ${error}`);
|
|
472
|
-
}
|
|
473
|
-
switch (response.status) {
|
|
474
|
-
case 401:
|
|
475
|
-
throw new Error(`Failed to read abilities. Caller did not supply credentials or did not provide the correct credentials.`);
|
|
476
|
-
case 403:
|
|
477
|
-
throw new Error(`Failed to read abilities. Caller is not authorized to view the requested resource.`);
|
|
478
|
-
case 429:
|
|
479
|
-
throw new Error(`Failed to read abilities. Rate limit exceeded.`);
|
|
480
|
-
}
|
|
481
|
-
let result;
|
|
482
|
-
try {
|
|
483
|
-
result = await response.json();
|
|
484
|
-
if (result.abilities.includes("preview_intelligent_alert_grouping") && result.abilities.includes("time_based_alert_grouping")) {
|
|
485
|
-
return true;
|
|
486
|
-
}
|
|
487
|
-
return false;
|
|
488
|
-
} catch (error) {
|
|
489
|
-
throw new Error(`Failed to parse abilities information: ${error}`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
function readOptionalString(key) {
|
|
493
|
-
if (!_config) {
|
|
494
|
-
return _legacyConfig.getOptionalString(key);
|
|
495
|
-
}
|
|
496
|
-
return _config.getOptionalString(key);
|
|
497
|
-
}
|
|
498
|
-
function readOptionalObject(key) {
|
|
499
|
-
if (!_config) {
|
|
500
|
-
return _legacyConfig.getOptional(key);
|
|
501
|
-
}
|
|
502
|
-
return _config.getOptional(key);
|
|
503
|
-
}
|
|
504
|
-
function readString(key) {
|
|
505
|
-
if (!_config) {
|
|
506
|
-
return _legacyConfig.getString(key);
|
|
507
|
-
}
|
|
508
|
-
return _config.getString(key);
|
|
509
|
-
}
|
|
510
|
-
async function getAccountByEscalationPolicyId(escalationPolicyId) {
|
|
511
|
-
const escalationPoliciesList = await getAllEscalationPolicies();
|
|
512
|
-
const escalationPolicy = escalationPoliciesList.find((policy) => policy.id === escalationPolicyId);
|
|
513
|
-
return escalationPolicy?.account ?? "";
|
|
514
|
-
}
|
|
515
|
-
async function getEscalationPolicies(offset, limit, account) {
|
|
516
|
-
let response;
|
|
517
|
-
const params = `total=true&sort_by=name&offset=${offset}&limit=${limit}`;
|
|
518
|
-
const options = {
|
|
519
|
-
method: "GET",
|
|
520
|
-
headers: {
|
|
521
|
-
Authorization: await getAuthToken(account),
|
|
522
|
-
"Accept": "application/vnd.pagerduty+json;version=2",
|
|
523
|
-
"Content-Type": "application/json"
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
const apiBaseUrl = getApiBaseUrl(account);
|
|
527
|
-
const baseUrl = `${apiBaseUrl}/escalation_policies`;
|
|
528
|
-
try {
|
|
529
|
-
response = await fetch__default.default(`${baseUrl}?${params}`, options);
|
|
530
|
-
} catch (error) {
|
|
531
|
-
throw new Error(`Failed to retrieve escalation policies: ${error}`);
|
|
532
|
-
}
|
|
533
|
-
switch (response.status) {
|
|
534
|
-
case 400:
|
|
535
|
-
throw new backstagePluginCommon.HttpError("Failed to list escalation policies. Caller provided invalid arguments.", 400);
|
|
536
|
-
case 401:
|
|
537
|
-
throw new backstagePluginCommon.HttpError("Failed to list escalation policies. Caller did not supply credentials or did not provide the correct credentials.", 401);
|
|
538
|
-
case 403:
|
|
539
|
-
throw new backstagePluginCommon.HttpError("Failed to list escalation policies. Caller is not authorized to view the requested resource.", 403);
|
|
540
|
-
case 429:
|
|
541
|
-
throw new backstagePluginCommon.HttpError("Failed to list escalation policies. Rate limit exceeded.", 429);
|
|
542
|
-
}
|
|
543
|
-
let result;
|
|
544
|
-
try {
|
|
545
|
-
result = await response.json();
|
|
546
|
-
return [result.more ?? false, result.escalation_policies];
|
|
547
|
-
} catch (error) {
|
|
548
|
-
throw new backstagePluginCommon.HttpError(`Failed to parse escalation policy information: ${error}`, 500);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
async function getAllEscalationPolicies() {
|
|
552
|
-
const limit = 50;
|
|
553
|
-
let offset = 0;
|
|
554
|
-
let moreResults = false;
|
|
555
|
-
let results = [];
|
|
556
|
-
await Promise.all(
|
|
557
|
-
Object.keys(EndpointConfig).map(async (account) => {
|
|
558
|
-
try {
|
|
559
|
-
offset = 0;
|
|
560
|
-
do {
|
|
561
|
-
const res = await getEscalationPolicies(offset, limit, account);
|
|
562
|
-
res[1].forEach((policy) => {
|
|
563
|
-
policy.account = account;
|
|
564
|
-
});
|
|
565
|
-
results = results.concat(res[1]);
|
|
566
|
-
if (res[0] === true) {
|
|
567
|
-
moreResults = true;
|
|
568
|
-
offset += limit;
|
|
569
|
-
} else {
|
|
570
|
-
moreResults = false;
|
|
571
|
-
}
|
|
572
|
-
} while (moreResults === true);
|
|
573
|
-
} catch (error) {
|
|
574
|
-
if (error instanceof backstagePluginCommon.HttpError) {
|
|
575
|
-
throw error;
|
|
576
|
-
} else {
|
|
577
|
-
throw new backstagePluginCommon.HttpError(`${error}`, 500);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
})
|
|
581
|
-
);
|
|
582
|
-
return results;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
const createPagerDutyServiceAction = (props) => {
|
|
586
|
-
let loggerService;
|
|
587
|
-
return pluginScaffolderNode.createTemplateAction({
|
|
588
|
-
id: "pagerduty:service:create",
|
|
589
|
-
schema: {
|
|
590
|
-
input: zod.z.object({
|
|
591
|
-
name: zod.z.string().min(1, "name is required").describe("Name of the service"),
|
|
592
|
-
description: zod.z.string().min(1, "description is required").describe("Description of the service"),
|
|
593
|
-
escalationPolicyId: zod.z.string().min(1, "Escalation policy is required").describe("Escalation policy ID"),
|
|
594
|
-
alertGrouping: zod.z.string().optional().describe("Alert grouping parameters")
|
|
595
|
-
}),
|
|
596
|
-
output: zod.z.object({
|
|
597
|
-
serviceUrl: zod.z.string().describe("PagerDuty Service URL"),
|
|
598
|
-
serviceId: zod.z.string().describe("PagerDuty Service ID"),
|
|
599
|
-
integrationKey: zod.z.string().describe("Backstage Integration Key")
|
|
600
|
-
})
|
|
601
|
-
},
|
|
602
|
-
async handler(ctx) {
|
|
603
|
-
try {
|
|
604
|
-
loggerService = props?.logger ? props.logger : ctx.logger;
|
|
605
|
-
const configService = props?.config;
|
|
606
|
-
const legacyConfig = await backendCommon.loadBackendConfig({
|
|
607
|
-
logger: loggerService,
|
|
608
|
-
argv: []
|
|
609
|
-
});
|
|
610
|
-
await loadAuthConfig({
|
|
611
|
-
config: configService,
|
|
612
|
-
legacyConfig,
|
|
613
|
-
logger: loggerService
|
|
614
|
-
});
|
|
615
|
-
loadPagerDutyEndpointsFromConfig({
|
|
616
|
-
config: configService,
|
|
617
|
-
legacyConfig,
|
|
618
|
-
logger: loggerService
|
|
619
|
-
});
|
|
620
|
-
const account = await getAccountByEscalationPolicyId(ctx.input.escalationPolicyId);
|
|
621
|
-
loggerService.info(`Creating service '${ctx.input.name}' in account '${account}'.`);
|
|
622
|
-
const service = await createService({
|
|
623
|
-
name: ctx.input.name,
|
|
624
|
-
description: ctx.input.description,
|
|
625
|
-
escalationPolicyId: ctx.input.escalationPolicyId,
|
|
626
|
-
account,
|
|
627
|
-
alertGrouping: ctx.input.alertGrouping
|
|
628
|
-
});
|
|
629
|
-
loggerService.info(`Service '${ctx.input.name}' created successfully!`);
|
|
630
|
-
loggerService.info(`Alert grouping set to '${service.alertGrouping}'`);
|
|
631
|
-
ctx.output("serviceUrl", service.url);
|
|
632
|
-
ctx.output("serviceId", service.id);
|
|
633
|
-
ctx.output("account", account);
|
|
634
|
-
const backstageIntegrationId = "PRO19CT";
|
|
635
|
-
loggerService.info(`Creating Backstage Integration for service '${ctx.input.name}' in account '${account}'.`);
|
|
636
|
-
const integrationKey = await createServiceIntegration({
|
|
637
|
-
serviceId: service.id,
|
|
638
|
-
vendorId: backstageIntegrationId,
|
|
639
|
-
account
|
|
640
|
-
});
|
|
641
|
-
loggerService.info(`Backstage Integration for service '${ctx.input.name}' created successfully!`);
|
|
642
|
-
ctx.output("integrationKey", integrationKey);
|
|
643
|
-
} catch (error) {
|
|
644
|
-
loggerService.error(`${error}`);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
});
|
|
648
|
-
};
|
|
649
|
-
|
|
650
|
-
const pagerDutyScaffolderActions = backendPluginApi.createBackendModule({
|
|
651
|
-
pluginId: "scaffolder",
|
|
652
|
-
moduleId: "pagerduty-actions",
|
|
653
|
-
register(env) {
|
|
654
|
-
env.registerInit({
|
|
655
|
-
deps: {
|
|
656
|
-
config: backendPluginApi.coreServices.rootConfig,
|
|
657
|
-
logger: backendPluginApi.coreServices.logger,
|
|
658
|
-
scaffolder: alpha.scaffolderActionsExtensionPoint
|
|
659
|
-
},
|
|
660
|
-
async init({ config, logger, scaffolder }) {
|
|
661
|
-
scaffolder.addActions(createPagerDutyServiceAction({
|
|
662
|
-
config,
|
|
663
|
-
logger
|
|
664
|
-
}));
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
exports.createPagerDutyServiceAction = createPagerDutyServiceAction;
|
|
671
|
-
exports.default = pagerDutyScaffolderActions;
|
|
10
|
+
exports.default = module$1.pagerDutyScaffolderActions;
|
|
11
|
+
exports.createPagerDutyServiceAction = custom.createPagerDutyServiceAction;
|
|
672
12
|
//# sourceMappingURL=index.cjs.js.map
|