From 0609e726936e457c0407fa83ba8783409275f864 Mon Sep 17 00:00:00 2001 From: Samira Mokaram Date: Thu, 22 Oct 2020 15:12:38 +0200 Subject: [PATCH] add pagerduty backend --- packages/backend/package.json | 1 + packages/backend/src/index.ts | 3 + packages/backend/src/plugins/pagerduty.ts | 27 ++++++++ plugins/pagerduty-backend/.eslintrc.js | 3 + plugins/pagerduty-backend/README.md | 13 ++++ plugins/pagerduty-backend/package.json | 40 ++++++++++++ plugins/pagerduty-backend/src/index.ts | 17 +++++ plugins/pagerduty-backend/src/run.ts | 33 ++++++++++ .../src/service/router.test.ts | 45 ++++++++++++++ .../pagerduty-backend/src/service/router.ts | 42 +++++++++++++ .../src/service/standaloneServer.ts | 62 +++++++++++++++++++ plugins/pagerduty-backend/src/setupTests.ts | 18 ++++++ 12 files changed, 304 insertions(+) create mode 100644 packages/backend/src/plugins/pagerduty.ts create mode 100644 plugins/pagerduty-backend/.eslintrc.js create mode 100644 plugins/pagerduty-backend/README.md create mode 100644 plugins/pagerduty-backend/package.json create mode 100644 plugins/pagerduty-backend/src/index.ts create mode 100644 plugins/pagerduty-backend/src/run.ts create mode 100644 plugins/pagerduty-backend/src/service/router.test.ts create mode 100644 plugins/pagerduty-backend/src/service/router.ts create mode 100644 plugins/pagerduty-backend/src/service/standaloneServer.ts create mode 100644 plugins/pagerduty-backend/src/setupTests.ts diff --git a/packages/backend/package.json b/packages/backend/package.json index ef55b007a7..c31629e82e 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -31,6 +31,7 @@ "@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.25", "@backstage/plugin-sentry-backend": "^0.1.1-alpha.25", "@backstage/plugin-techdocs-backend": "^0.1.1-alpha.25", + "@backstage/plugin-pagerduty-backend": "^0.1.1-alpha.25", "@gitbeaker/node": "^23.5.0", "@octokit/rest": "^18.0.0", "azure-devops-node-api": "^10.1.1", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 18fd44f089..0ca17c7d7f 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -46,6 +46,7 @@ import techdocs from './plugins/techdocs'; import graphql from './plugins/graphql'; import app from './plugins/app'; import { PluginEnvironment } from './types'; +import pagerduty from './plugins/pagerduty'; function makeCreateEnv(config: ConfigReader) { const root = getRootLogger(); @@ -79,6 +80,7 @@ async function main() { const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes')); const graphqlEnv = useHotMemoize(module, () => createEnv('graphql')); const appEnv = useHotMemoize(module, () => createEnv('app')); + const pagerdutyEnv = useHotMemoize(module, () => createEnv('pagerduty')); const apiRouter = Router(); apiRouter.use('/catalog', await catalog(catalogEnv)); @@ -90,6 +92,7 @@ async function main() { apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); apiRouter.use('/proxy', await proxy(proxyEnv)); apiRouter.use('/graphql', await graphql(graphqlEnv)); + apiRouter.use('/pagerduty', await pagerduty(pagerdutyEnv)); apiRouter.use(notFoundHandler()); const service = createServiceBuilder(module) diff --git a/packages/backend/src/plugins/pagerduty.ts b/packages/backend/src/plugins/pagerduty.ts new file mode 100644 index 0000000000..6dc3d8c9ba --- /dev/null +++ b/packages/backend/src/plugins/pagerduty.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouter } from '@backstage/plugin-pagerduty-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ + logger, + config, +}: PluginEnvironment) { + return await createRouter({ + logger, + config, + }); +} diff --git a/plugins/pagerduty-backend/.eslintrc.js b/plugins/pagerduty-backend/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/pagerduty-backend/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/pagerduty-backend/README.md b/plugins/pagerduty-backend/README.md new file mode 100644 index 0000000000..099a94a85f --- /dev/null +++ b/plugins/pagerduty-backend/README.md @@ -0,0 +1,13 @@ +# pagerduty + +Welcome to the pagerduty backend plugin! + +_This plugin was created through the Backstage CLI_ + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/pagerduty](http://localhost:3000/pagerduty). + +You can also serve the plugin in isolation by running `yarn start` in the plugin directory. +This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. +It is only meant for local development, and the setup for it can be found inside the [/dev](/dev) directory. diff --git a/plugins/pagerduty-backend/package.json b/plugins/pagerduty-backend/package.json new file mode 100644 index 0000000000..cad4ba268e --- /dev/null +++ b/plugins/pagerduty-backend/package.json @@ -0,0 +1,40 @@ +{ + "name": "@backstage/plugin-pagerduty-backend", + "version": "0.1.1-alpha.25", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "start": "backstage-cli backend:dev", + "build": "backstage-cli backend:build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/backend-common": "^0.1.1-alpha.25", + "@backstage/config": "^0.1.1-alpha.25", + "@types/express": "^4.17.6", + "express": "^4.17.1", + "express-promise-router": "^3.0.3", + "winston": "^3.2.1", + "node-fetch": "^2.6.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.25", + "@types/supertest": "^2.0.8", + "supertest": "^4.0.2", + "msw": "^0.20.5" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/pagerduty-backend/src/index.ts b/plugins/pagerduty-backend/src/index.ts new file mode 100644 index 0000000000..7612c392a2 --- /dev/null +++ b/plugins/pagerduty-backend/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './service/router'; diff --git a/plugins/pagerduty-backend/src/run.ts b/plugins/pagerduty-backend/src/run.ts new file mode 100644 index 0000000000..b96989e4b8 --- /dev/null +++ b/plugins/pagerduty-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7000; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/pagerduty-backend/src/service/router.test.ts b/plugins/pagerduty-backend/src/service/router.test.ts new file mode 100644 index 0000000000..0aaeafa379 --- /dev/null +++ b/plugins/pagerduty-backend/src/service/router.test.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import express from 'express'; +import request from 'supertest'; + +import { createRouter } from './router'; + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); diff --git a/plugins/pagerduty-backend/src/service/router.ts b/plugins/pagerduty-backend/src/service/router.ts new file mode 100644 index 0000000000..eb7cc734c2 --- /dev/null +++ b/plugins/pagerduty-backend/src/service/router.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler } from '@backstage/backend-common'; +import { Config } from '@backstage/config'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; + +export interface RouterOptions { + logger: Logger; + config: Config; +} + +export async function createRouter( + options: RouterOptions, +): Promise { + const { logger } = options; + + const router = Router(); + router.use(express.json()); + + router.get('/health', (_, response) => { + logger.info('PONG!'); + response.send({ status: 'ok' }); + }); + router.use(errorHandler()); + return router; +} diff --git a/plugins/pagerduty-backend/src/service/standaloneServer.ts b/plugins/pagerduty-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..73f928bef4 --- /dev/null +++ b/plugins/pagerduty-backend/src/service/standaloneServer.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createServiceBuilder } from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'pagerduty-backend' }); + logger.debug('Starting application server...'); + const router = await createRouter({ + logger, + }); + + const service = createServiceBuilder(module) + .enableCors({ origin: 'http://localhost:3000' }) + .addRouter('/pagerduty', router); + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/pagerduty-backend/src/setupTests.ts b/plugins/pagerduty-backend/src/setupTests.ts new file mode 100644 index 0000000000..a5907fd52f --- /dev/null +++ b/plugins/pagerduty-backend/src/setupTests.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; +global.fetch = require('node-fetch');