Add Sentry plugin backend API (forwarding proxy)

This commit is contained in:
Wojciech Adaszynski
2020-05-15 11:29:27 +02:00
parent ee84a874f8
commit f8ee87ce1d
12 changed files with 253 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
extends: [require.resolve('@backstage/cli/config/eslint.backend')],
};
+3
View File
@@ -0,0 +1,3 @@
# sentry-backend
Simple plugin forwarding requests to [Sentry](https://sentry.io) API.
+34
View File
@@ -0,0 +1,34 @@
{
"name": "@backstage/plugin-sentry-backend",
"version": "0.1.1-alpha.5",
"main": "dist",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": true,
"scripts": {
"build": "tsc",
"start": "backstage-cli plugin:serve",
"lint": "backstage-cli lint",
"test": "backstage-cli test",
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.5",
"@backstage/core": "^0.1.1-alpha.5",
"axios": "^0.19.2",
"cors": "^2.8.5",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"helmet": "^3.22.0",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.5",
"@backstage/dev-utils": "^0.1.1-alpha.5",
"@types/jest": "^25.2.1",
"@types/node": "^12.0.0"
},
"files": [
"dist/**/*.{js,d.ts}"
]
}
+16
View File
@@ -0,0 +1,16 @@
/*
* 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';
@@ -0,0 +1,35 @@
/*
* 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 { Logger } from 'winston';
import Router from 'express-promise-router';
import express from 'express';
import { SentryApiForwarder } from './sentry-api';
export async function createRouter(
rootLogger: Logger,
): Promise<express.Router> {
const router = Router();
const sentryForwarder = new SentryApiForwarder('');
const logger = rootLogger.child({ plugin: 'sentry' });
router.get('*', (req, res) => sentryForwarder.fowardRequest(req, res));
const app = express();
app.set('logger', logger);
app.use('/', router);
return app;
}
@@ -0,0 +1,38 @@
/*
* 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 express from 'express';
import axios from 'axios';
export class SentryApiForwarder {
constructor(private token: string) {}
public fowardRequest(request: express.Request, response: express.Response) {
const sentryUrl = request.path;
axios
.get(`https://sentry.io/${sentryUrl}`, {
headers: {
Authorization: `Bearer ${this.token}`,
},
})
.then(res => {
response.send(res.data);
})
.catch(err => {
return response.status(err.response.status).json({
detail: err.response.statusText,
});
});
}
}
@@ -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,
notFoundHandler,
requestLoggingHandler,
} from '@backstage/backend-common';
import cors from 'cors';
import express from 'express';
import helmet from 'helmet';
import { Logger } from 'winston';
import { createRouter } from './router';
export async function createStandaloneApplication(
logger: Logger,
): Promise<express.Application> {
const app = express();
app.use(helmet());
app.use(cors());
app.use(express.json());
app.use(requestLoggingHandler());
app.use('/', await createRouter(logger));
app.use(notFoundHandler());
app.use(errorHandler());
return app;
}
@@ -0,0 +1,43 @@
/*
* 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 { Server } from 'http';
import { Logger } from 'winston';
import { createStandaloneApplication } from './standaloneApplication';
const PORT = 5009;
export async function startStandaloneServer(
parentLogger: Logger,
): Promise<Server> {
const logger = parentLogger.child({ service: 'scaffolder-backend' });
logger.debug('Creating application...');
const app = await createStandaloneApplication(logger);
logger.debug('Starting application server...');
return await new Promise((resolve, reject) => {
const server = app.listen(PORT, (err?: Error) => {
if (err) {
reject(err);
return;
}
logger.info(`Listening on port ${PORT}`);
resolve(server);
});
});
}
+11
View File
@@ -0,0 +1,11 @@
{
"extends": "../../packages/backend/tsconfig.json",
"include": [
"./src"
],
"compilerOptions": {
"baseUrl": "./src",
"outDir": "./dist",
"skipLibCheck": true
}
}