Refactor the Sentry plugin to use the proxy backend instead of a custom backend

This commit is contained in:
Dominik Henneke
2020-12-07 17:02:54 +01:00
parent 4266967979
commit 075d3dc5ae
36 changed files with 406 additions and 482 deletions
+3 -1
View File
@@ -1,3 +1,5 @@
# sentry-backend
Simple plugin forwarding requests to [Sentry](https://sentry.io) API.
> DEPRECATED
Please use the [proxy-backend](../proxy-backend) instead. See [CHANGELOG.md](./CHANGELOG.md).
+10 -1
View File
@@ -14,4 +14,13 @@
* limitations under the License.
*/
export * from './service/router';
import { Router } from 'express';
import { Logger } from 'winston';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const createRouter = async (_: Logger): Promise<Router> => Router();
throw new Error(
'The sentry-backend has been deprecated and replaced by the proxy-backend. See the ' +
'changelog on how to migrate to the proxy backend: https://github.com/backstage/backstage/blob/master/plugins/sentry/CHANGELOG.md.',
);
@@ -1,42 +0,0 @@
/*
* 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 { getSentryApiForwarder } from './sentry-api';
export async function createRouter(logger: Logger): Promise<express.Router> {
const router = Router();
router.use(express.json());
const SENTRY_TOKEN = process.env.SENTRY_TOKEN;
if (!SENTRY_TOKEN) {
if (process.env.NODE_ENV !== 'development') {
throw new Error(
'Sentry token must be provided in SENTRY_TOKEN environment variable to start the API.',
);
}
logger.warn(
'Failed to initialize Sentry backend, set SENTRY_TOKEN environment variable to start the API.',
);
} else {
const sentryForwarder = getSentryApiForwarder(SENTRY_TOKEN, logger);
router.use(sentryForwarder);
}
return router;
}
@@ -1,26 +0,0 @@
/*
* 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 { getRequestHeaders } from './sentry-api';
describe('SentryApiForwarder', () => {
it('should generate headers based on token passed in constructor', () => {
expect(getRequestHeaders('testtoken')).toEqual({
headers: {
Authorization: `Bearer testtoken`,
},
});
});
});
@@ -1,47 +0,0 @@
/*
* 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';
import { Logger } from 'winston';
export function getRequestHeaders(token: string) {
return {
headers: {
Authorization: `Bearer ${token}`,
},
};
}
export function getSentryApiForwarder(token: string, logger: Logger) {
return function forwardRequest(
request: express.Request,
response: express.Response,
) {
const sentryUrl = request.path;
const effectiveUrl = `https://sentry.io/${sentryUrl}`;
logger.info(`Calling Sentry REST API, ${effectiveUrl}`);
axios
.get(effectiveUrl, getRequestHeaders(token))
.then(res => {
response.send(res.data);
})
.catch(err => {
return response.status(err.response.status).json({
detail: err.response.statusText,
});
});
};
}
@@ -1,42 +0,0 @@
/*
* 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;
}
@@ -1,42 +0,0 @@
/*
* 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';
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...');
const PORT = parseInt(process.env.PORT || '5001', 10);
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);
});
});
}