Skip to content

Commit

Permalink
Merge pull request #16 from PagerDuty/next
Browse files Browse the repository at this point in the history
release: 0.2.0
  • Loading branch information
t1agob authored Jul 12, 2024
2 parents 7435964 + 1c77aae commit 54d493b
Show file tree
Hide file tree
Showing 9 changed files with 2,998 additions and 1,105 deletions.
Binary file added .yarn/install-state.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion backstage.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "1.25.2"
"version": "1.28.4"
}
8 changes: 7 additions & 1 deletion config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { PagerDutyOAuthConfig } from '@pagerduty/backstage-plugin-common';
import { PagerDutyAccountConfig, PagerDutyOAuthConfig } from '@pagerduty/backstage-plugin-common';

export interface Config {
/**
Expand Down Expand Up @@ -42,5 +42,11 @@ export interface Config {
* @deepVisibility secret
*/
oauth?: PagerDutyOAuthConfig;

/**
* Optional PagerDuty multi-account configuration
* @deepVisibility secret
*/
accounts?: PagerDutyAccountConfig[];
};
}
28 changes: 18 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin-module"
"role": "backend-plugin-module",
"pluginPackage": "scaffolder",
"pluginId": "pagerduty-actions"
},
"homepage": "https://pagerduty.github.io/backstage-plugin-docs/index.html",
"repository": {
"type": "git",
"url": "https://github.com/PagerDuty/backstage-plugin-scaffolder-actions.git",
"directory": "."
},
"scripts": {
"start": "yarn tsc && backstage-cli package start",
Expand All @@ -22,23 +30,23 @@
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage/backend-common": "^0.21.6",
"@backstage/backend-defaults": "^0.2.16",
"@backstage/backend-plugin-api": "^0.6.16",
"@backstage/backend-common": "^0.23.2",
"@backstage/backend-defaults": "^0.3.3",
"@backstage/backend-plugin-api": "^0.6.21",
"@backstage/config": "^1.2.0",
"@backstage/plugin-scaffolder-node": "^0.4.2",
"@backstage/plugin-scaffolder-node": "^0.4.7",
"@pagerduty/backstage-plugin-common": "0.2.0",
"@rjsf/core": "^5.14.3",
"@rjsf/utils": "^5.19.3",
"node-fetch": "^2.6.7",
"react": "18.3.1",
"winston": "^3.2.1",
"yn": "^4.0.0",
"zod": "^3.22.4"
},
"peerDependencies": {
"@pagerduty/backstage-plugin-common": "^0.1.3"
},
"devDependencies": {
"@backstage/cli": "^0.24.0",
"@pagerduty/backstage-plugin-common": "^0.1.3",
"@backstage/cli": "^0.26.10",
"@types/jest": "^29.5.12",
"@types/node": "^20.9.2",
"@types/node-fetch": "2.6.11",
"@types/supertest": "^2.0.12",
Expand Down
38 changes: 29 additions & 9 deletions src/actions/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { loadAuthConfig } from '../auth/auth';
import { LoggerService, RootConfigService } from '@backstage/backend-plugin-api';
import { Config } from "@backstage/config";
import { loadBackendConfig } from "@backstage/backend-common";
import { loadPagerDutyEndpointsFromConfig, getAccountByEscalationPolicyId } from '../apis/pagerduty';

export type CreatePagerDutyServiceActionProps = {
config: RootConfigService;
logger: LoggerService;
};

export const createPagerDutyServiceAction = (props? : CreatePagerDutyServiceActionProps) => {
export const createPagerDutyServiceAction = (props?: CreatePagerDutyServiceActionProps) => {

let loggerService: LoggerService;

Expand All @@ -38,7 +39,7 @@ export const createPagerDutyServiceAction = (props? : CreatePagerDutyServiceActi
},

async handler(ctx) {
try {
try {
loggerService = props?.logger ? props.logger : ctx.logger;
const configService = props?.config;

Expand All @@ -49,17 +50,29 @@ export const createPagerDutyServiceAction = (props? : CreatePagerDutyServiceActi

// Load the auth configuration
await loadAuthConfig({
config: configService,
config: configService,
legacyConfig: legacyConfig,
logger: loggerService,
});

// Load endpoint configuration
loadPagerDutyEndpointsFromConfig({
config: configService,
legacyConfig: legacyConfig,
logger: loggerService,
});

const account: string = await getAccountByEscalationPolicyId(ctx.input.escalationPolicyId);

// Create service in PagerDuty
const service: CreateServiceResponse = await api.createService(
ctx.input.name,
ctx.input.description,
ctx.input.escalationPolicyId,
ctx.input.alertGrouping);
loggerService.info(`Creating service '${ctx.input.name}' in account '${account}'.`);
const service: CreateServiceResponse = await api.createService({
name: ctx.input.name,
description: ctx.input.description,
escalationPolicyId: ctx.input.escalationPolicyId,
account: account,
alertGrouping: ctx.input.alertGrouping
});
loggerService.info(`Service '${ctx.input.name}' created successfully!`);
loggerService.info(`Alert grouping set to '${service.alertGrouping}'`);

Expand All @@ -68,7 +81,14 @@ export const createPagerDutyServiceAction = (props? : CreatePagerDutyServiceActi

// Create Backstage Integration in PagerDuty service
const backstageIntegrationId = 'PRO19CT'; // ID for Backstage integration
const integrationKey = await api.createServiceIntegration(service.id, backstageIntegrationId);

loggerService.info(`Creating Backstage Integration for service '${ctx.input.name}' in account '${account}'.`);

const integrationKey = await api.createServiceIntegration({
serviceId: service.id,
vendorId: backstageIntegrationId,
account
});
loggerService.info(`Backstage Integration for service '${ctx.input.name}' created successfully!`);

ctx.output('integrationKey', integrationKey);
Expand Down
79 changes: 64 additions & 15 deletions src/apis/pagerduty.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable jest/no-conditional-expect */
import { createService, createServiceIntegration } from "./pagerduty";
import { PagerDutyAccountConfig } from "@pagerduty/backstage-plugin-common";
import { createService, createServiceIntegration, getAccountByEscalationPolicyId, insertEndpointConfig, setFallbackEndpointConfig } from "./pagerduty";

import { mocked } from "jest-mock";
import fetch, { Response } from "node-fetch";
Expand All @@ -23,7 +24,19 @@ function mockedResponse(status: number, body: any): Promise<Response> {
} as Response);
}

describe("PagerDuty API", () => {
describe("PagerDuty API", () => {
beforeAll(() => {

const mockAccount : PagerDutyAccountConfig = {
id: "testaccount",
apiBaseUrl: "https://mock.api.pagerduty.com",
eventsBaseUrl: "https://mock.events.pagerduty.com",
};

insertEndpointConfig(mockAccount);
setFallbackEndpointConfig(mockAccount);
});

afterEach(() => {
jest.clearAllMocks();
});
Expand Down Expand Up @@ -51,7 +64,11 @@ describe("PagerDuty API", () => {
)
);

const result = await createService(name, description, escalationPolicyId, "intelligent");
const result = await createService({
name,
description,
escalationPolicyId,
alertGrouping: "intelligent"});

expect(result).toEqual(expectedResponse);
expect(fetch).toHaveBeenCalledTimes(2);
Expand All @@ -75,7 +92,12 @@ describe("PagerDuty API", () => {
})
);

const result = await createService(name, description, escalationPolicyId, "null");
const result = await createService({
name,
description,
escalationPolicyId,
alertGrouping:"null"
});

expect(result).toEqual(expectedResponse);
expect(fetch).toHaveBeenCalledTimes(2);
Expand All @@ -94,7 +116,7 @@ describe("PagerDuty API", () => {
mockedResponse(201, { service: { id: "S3RV1CE1D", html_url: "https://testaccount.pagerduty.com/services/S3RV1CE1D" } })
);

const result = await createService(name, description, escalationPolicyId);
const result = await createService({name, description, escalationPolicyId});

expect(result).toEqual(expectedResponse);
expect(fetch).toHaveBeenCalledTimes(2);
Expand All @@ -113,7 +135,7 @@ describe("PagerDuty API", () => {
mockedResponse(201, { service: { id: "S3RV1CE1D", html_url: "https://testaccount.pagerduty.com/services/S3RV1CE1D" } })
);

const result = await createService(name, description, escalationPolicyId);
const result = await createService({name, description, escalationPolicyId});

expect(result).toEqual(expectedResponse);
expect(fetch).toHaveBeenCalledTimes(2);
Expand All @@ -131,7 +153,7 @@ describe("PagerDuty API", () => {
);

try {
await createService(name, description, escalationPolicyId);
await createService({name, description, escalationPolicyId});
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service. Caller provided invalid arguments.");
}
Expand All @@ -149,7 +171,7 @@ describe("PagerDuty API", () => {
);

try {
await createService(name, description, escalationPolicyId);
await createService({name, description, escalationPolicyId});
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service. Caller did not supply credentials or did not provide the correct credentials.");
}
Expand All @@ -169,7 +191,7 @@ describe("PagerDuty API", () => {
);

try {
await createService(name, description, escalationPolicyId);
await createService({name, description, escalationPolicyId});
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service. Account does not have the abilities to perform the action.");
}
Expand All @@ -187,11 +209,38 @@ describe("PagerDuty API", () => {
);

try {
await createService(name, description, escalationPolicyId);
await createService({name, description, escalationPolicyId});
} catch (error) {
expect(((error as Error).message)).toEqual("Failed to create service. Caller is not authorized to view the requested resource.");
}
});

it.each(testInputs)("should get account from escalation policy id", async () => {
const escalationPolicyId = "12345";

mocked(fetch).mockReturnValueOnce(
mockedResponse(200, {
escalation_policies: [
{
id: "12345",
name: "Test Escalation Policy",
summary: "Test Escalation Policy Summary",
type: "escalation_policy",
}
],
limit: 50,
offset: 0,
total: 1,
more: false,
})
);


const account = await getAccountByEscalationPolicyId(escalationPolicyId);

expect(account).toEqual("testaccount");
expect(fetch).toHaveBeenCalledTimes(1);
});
});

describe("createServiceIntegration", () => {
Expand All @@ -206,7 +255,7 @@ describe("PagerDuty API", () => {
);


const result = await createServiceIntegration(serviceId, vendorId);
const result = await createServiceIntegration({serviceId, vendorId});

expect(result).toEqual(expectedResponse);
expect(fetch).toHaveBeenCalledTimes(1);
Expand All @@ -225,7 +274,7 @@ describe("PagerDuty API", () => {
const expectedErrorMessage = "Failed to create service integration. Caller provided invalid arguments.";

try {
await createServiceIntegration(serviceId, vendorId);
await createServiceIntegration({serviceId, vendorId});
} catch (error) {
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
Expand All @@ -242,7 +291,7 @@ describe("PagerDuty API", () => {
const expectedErrorMessage = "Failed to create service integration. Caller did not supply credentials or did not provide the correct credentials.";

try {
await createServiceIntegration(serviceId, vendorId);
await createServiceIntegration({serviceId, vendorId});
} catch (error) {
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
Expand All @@ -259,7 +308,7 @@ describe("PagerDuty API", () => {
const expectedErrorMessage = "Failed to create service integration. Caller is not authorized to view the requested resource.";

try {
await createServiceIntegration(serviceId, vendorId);
await createServiceIntegration({serviceId, vendorId});
} catch (error) {
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
Expand All @@ -276,7 +325,7 @@ describe("PagerDuty API", () => {
const expectedErrorMessage = "Failed to create service integration. Rate limit exceeded.";

try {
await createServiceIntegration(serviceId, vendorId);
await createServiceIntegration({serviceId, vendorId});
} catch (error) {
expect(((error as Error).message)).toEqual(expectedErrorMessage);
}
Expand Down
Loading

0 comments on commit 54d493b

Please sign in to comment.