Merge pull request #18915 from backstage/rugvip/proxy-refactor
proxy-backend: move proxy configuration to proxy.endpoints
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-proxy-backend': minor
|
||||
---
|
||||
|
||||
Defining proxy endpoints directly under the root `proxy` configuration key is deprecated. Endpoints should now be declared under `proxy.endpoints` instead. The `skipInvalidProxies` and `reviveConsumedRequestBodies` can now also be configured through static configuration.
|
||||
+62
-61
@@ -51,80 +51,81 @@ backend:
|
||||
|
||||
# See README.md in the proxy-backend plugin for information on the configuration format
|
||||
proxy:
|
||||
'/circleci/api':
|
||||
target: https://circleci.com/api/v1.1
|
||||
headers:
|
||||
Circle-Token: ${CIRCLECI_AUTH_TOKEN}
|
||||
endpoints:
|
||||
'/circleci/api':
|
||||
target: https://circleci.com/api/v1.1
|
||||
headers:
|
||||
Circle-Token: ${CIRCLECI_AUTH_TOKEN}
|
||||
|
||||
'/jenkins/api':
|
||||
target: http://localhost:8080
|
||||
headers:
|
||||
Authorization: ${JENKINS_BASIC_AUTH_HEADER}
|
||||
'/jenkins/api':
|
||||
target: http://localhost:8080
|
||||
headers:
|
||||
Authorization: ${JENKINS_BASIC_AUTH_HEADER}
|
||||
|
||||
'/travisci/api':
|
||||
target: https://api.travis-ci.com
|
||||
changeOrigin: true
|
||||
headers:
|
||||
Authorization: ${TRAVISCI_AUTH_TOKEN}
|
||||
travis-api-version: '3'
|
||||
'/travisci/api':
|
||||
target: https://api.travis-ci.com
|
||||
changeOrigin: true
|
||||
headers:
|
||||
Authorization: ${TRAVISCI_AUTH_TOKEN}
|
||||
travis-api-version: '3'
|
||||
|
||||
'/newrelic/apm/api':
|
||||
target: https://api.newrelic.com/v2
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_REST_API_KEY}
|
||||
'/newrelic/apm/api':
|
||||
target: https://api.newrelic.com/v2
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_REST_API_KEY}
|
||||
|
||||
'/newrelic/api':
|
||||
target: https://api.newrelic.com
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_USER_KEY}
|
||||
'/newrelic/api':
|
||||
target: https://api.newrelic.com
|
||||
headers:
|
||||
X-Api-Key: ${NEW_RELIC_USER_KEY}
|
||||
|
||||
'/pagerduty':
|
||||
target: https://api.pagerduty.com
|
||||
headers:
|
||||
Authorization: Token token=${PAGERDUTY_TOKEN}
|
||||
'/pagerduty':
|
||||
target: https://api.pagerduty.com
|
||||
headers:
|
||||
Authorization: Token token=${PAGERDUTY_TOKEN}
|
||||
|
||||
'/buildkite/api':
|
||||
target: https://api.buildkite.com/v2/
|
||||
headers:
|
||||
Authorization: ${BUILDKITE_TOKEN}
|
||||
'/buildkite/api':
|
||||
target: https://api.buildkite.com/v2/
|
||||
headers:
|
||||
Authorization: ${BUILDKITE_TOKEN}
|
||||
|
||||
'/sentry/api':
|
||||
target: https://sentry.io/api/
|
||||
allowedMethods: ['GET']
|
||||
headers:
|
||||
Authorization: ${SENTRY_TOKEN}
|
||||
'/sentry/api':
|
||||
target: https://sentry.io/api/
|
||||
allowedMethods: ['GET']
|
||||
headers:
|
||||
Authorization: ${SENTRY_TOKEN}
|
||||
|
||||
'/ilert':
|
||||
target: https://api.ilert.com
|
||||
allowedMethods: ['GET', 'POST', 'PUT']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: ${ILERT_AUTH_HEADER}
|
||||
'/ilert':
|
||||
target: https://api.ilert.com
|
||||
allowedMethods: ['GET', 'POST', 'PUT']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: ${ILERT_AUTH_HEADER}
|
||||
|
||||
'/airflow':
|
||||
target: https://your.airflow.instance.com/api/v1
|
||||
headers:
|
||||
Authorization: ${AIRFLOW_BASIC_AUTH_HEADER}
|
||||
'/airflow':
|
||||
target: https://your.airflow.instance.com/api/v1
|
||||
headers:
|
||||
Authorization: ${AIRFLOW_BASIC_AUTH_HEADER}
|
||||
|
||||
'/gocd':
|
||||
target: https://your.gocd.instance.com/go/api
|
||||
allowedMethods: ['GET']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: Basic ${GOCD_AUTH_CREDENTIALS}
|
||||
'/gocd':
|
||||
target: https://your.gocd.instance.com/go/api
|
||||
allowedMethods: ['GET']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: Basic ${GOCD_AUTH_CREDENTIALS}
|
||||
|
||||
'/dynatrace':
|
||||
target: https://your.dynatrace.instance.com/api/v2
|
||||
headers:
|
||||
Authorization: 'Api-Token ${DYNATRACE_ACCESS_TOKEN}'
|
||||
'/dynatrace':
|
||||
target: https://your.dynatrace.instance.com/api/v2
|
||||
headers:
|
||||
Authorization: 'Api-Token ${DYNATRACE_ACCESS_TOKEN}'
|
||||
|
||||
'/stackstorm':
|
||||
target: https://your.stackstorm.instance.com/api
|
||||
headers:
|
||||
St2-Api-Key: ${ST2_API_KEY}
|
||||
'/stackstorm':
|
||||
target: https://your.stackstorm.instance.com/api
|
||||
headers:
|
||||
St2-Api-Key: ${ST2_API_KEY}
|
||||
|
||||
'/puppetdb':
|
||||
target: https://your.puppetdb.instance.com
|
||||
'/puppetdb':
|
||||
target: https://your.puppetdb.instance.com
|
||||
|
||||
organization:
|
||||
name: My Company
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"@backstage/plugin-permission-backend": "workspace:^",
|
||||
"@backstage/plugin-permission-common": "workspace:^",
|
||||
"@backstage/plugin-permission-node": "workspace:^",
|
||||
"@backstage/plugin-proxy-backend": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-backend": "workspace:^",
|
||||
"@backstage/plugin-search-backend": "workspace:^",
|
||||
"@backstage/plugin-search-backend-module-catalog": "workspace:^",
|
||||
|
||||
@@ -39,6 +39,7 @@ import { devtoolsPlugin } from '@backstage/plugin-devtools-backend';
|
||||
import { TaskScheduleDefinition } from '@backstage/backend-tasks';
|
||||
import { adrPlugin } from '@backstage/plugin-adr-backend';
|
||||
import { lighthousePlugin } from '@backstage/plugin-lighthouse-backend';
|
||||
import { proxyPlugin } from '@backstage/plugin-proxy-backend';
|
||||
|
||||
const backend = createBackend();
|
||||
|
||||
@@ -98,6 +99,9 @@ backend.add(kubernetesPlugin());
|
||||
// Lighthouse
|
||||
backend.add(lighthousePlugin());
|
||||
|
||||
// Proxy
|
||||
backend.add(proxyPlugin());
|
||||
|
||||
// Permissions
|
||||
backend.add(permissionPlugin());
|
||||
backend.add(permissionModuleAllowAllPolicy());
|
||||
|
||||
@@ -13,14 +13,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
|
||||
// @alpha
|
||||
export const proxyPlugin: (
|
||||
options?:
|
||||
| {
|
||||
skipInvalidProxies?: boolean | undefined;
|
||||
reviveConsumedRequestBodies?: boolean | undefined;
|
||||
}
|
||||
| undefined,
|
||||
) => BackendFeature;
|
||||
export const proxyPlugin: () => BackendFeature;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface RouterOptions {
|
||||
|
||||
Vendored
+56
-44
@@ -15,51 +15,63 @@
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
/**
|
||||
* A list of forwarding-proxies. Each key is a route to match,
|
||||
* below the prefix that the proxy plugin is mounted on. It must
|
||||
* start with a '/'.
|
||||
*/
|
||||
proxy?: {
|
||||
[key: string]:
|
||||
| string
|
||||
| {
|
||||
/**
|
||||
* Target of the proxy. Url string to be parsed with the url module.
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* Object with extra headers to be added to target requests.
|
||||
*/
|
||||
headers?: {
|
||||
/** @visibility secret */
|
||||
Authorization?: string;
|
||||
/** @visibility secret */
|
||||
authorization?: string;
|
||||
/** @visibility secret */
|
||||
'X-Api-Key'?: string;
|
||||
/** @visibility secret */
|
||||
'x-api-key'?: string;
|
||||
[key: string]: string | undefined;
|
||||
/**
|
||||
* Rather than failing to start up, the proxy backend will instead just warn on invalid endpoints.
|
||||
*/
|
||||
skipInvalidProxies?: boolean;
|
||||
|
||||
/**
|
||||
* Revive request bodies that have already been consumed by earlier middleware.
|
||||
*/
|
||||
reviveConsumedRequestBodies?: boolean;
|
||||
|
||||
/**
|
||||
* A list of forwarding-proxies. Each key is a route to match,
|
||||
* below the prefix that the proxy plugin is mounted on. It must
|
||||
* start with a '/'.
|
||||
*/
|
||||
endpoints?: {
|
||||
[key: string]:
|
||||
| string
|
||||
| {
|
||||
/**
|
||||
* Target of the proxy. Url string to be parsed with the url module.
|
||||
*/
|
||||
target: string;
|
||||
/**
|
||||
* Object with extra headers to be added to target requests.
|
||||
*/
|
||||
headers?: {
|
||||
/** @visibility secret */
|
||||
Authorization?: string;
|
||||
/** @visibility secret */
|
||||
authorization?: string;
|
||||
/** @visibility secret */
|
||||
'X-Api-Key'?: string;
|
||||
/** @visibility secret */
|
||||
'x-api-key'?: string;
|
||||
[key: string]: string | undefined;
|
||||
};
|
||||
/**
|
||||
* Changes the origin of the host header to the target URL. Default: true.
|
||||
*/
|
||||
changeOrigin?: boolean;
|
||||
/**
|
||||
* Rewrite target's url path. Object-keys will be used as RegExp to match paths.
|
||||
* If pathRewrite is not specified, it is set to a single rewrite that removes the entire prefix and route.
|
||||
*/
|
||||
pathRewrite?: { [regexp: string]: string };
|
||||
/**
|
||||
* Limit the forwarded HTTP methods, for example allowedMethods: ['GET'] to enforce read-only access.
|
||||
*/
|
||||
allowedMethods?: string[];
|
||||
/**
|
||||
* Limit the forwarded HTTP methods. By default, only the headers that are considered safe for CORS
|
||||
* and headers that are set by the proxy will be forwarded.
|
||||
*/
|
||||
allowedHeaders?: string[];
|
||||
};
|
||||
/**
|
||||
* Changes the origin of the host header to the target URL. Default: true.
|
||||
*/
|
||||
changeOrigin?: boolean;
|
||||
/**
|
||||
* Rewrite target's url path. Object-keys will be used as RegExp to match paths.
|
||||
* If pathRewrite is not specified, it is set to a single rewrite that removes the entire prefix and route.
|
||||
*/
|
||||
pathRewrite?: { [regexp: string]: string };
|
||||
/**
|
||||
* Limit the forwarded HTTP methods, for example allowedMethods: ['GET'] to enforce read-only access.
|
||||
*/
|
||||
allowedMethods?: string[];
|
||||
/**
|
||||
* Limit the forwarded HTTP methods. By default, only the headers that are considered safe for CORS
|
||||
* and headers that are set by the proxy will be forwarded.
|
||||
*/
|
||||
allowedHeaders?: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
"yup": "^0.32.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/config-loader": "workspace:^",
|
||||
"@types/http-proxy-middleware": "^0.19.3",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"@types/uuid": "^8.0.0",
|
||||
|
||||
@@ -26,32 +26,25 @@ import { createRouter } from './service/router';
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export const proxyPlugin = createBackendPlugin(
|
||||
(options?: {
|
||||
skipInvalidProxies?: boolean;
|
||||
reviveConsumedRequestBodies?: boolean;
|
||||
}) => ({
|
||||
pluginId: 'proxy',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
config: coreServices.rootConfig,
|
||||
discovery: coreServices.discovery,
|
||||
logger: coreServices.logger,
|
||||
httpRouter: coreServices.httpRouter,
|
||||
},
|
||||
async init({ config, discovery, logger, httpRouter }) {
|
||||
httpRouter.use(
|
||||
await createRouter({
|
||||
config,
|
||||
discovery,
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
skipInvalidProxies: options?.skipInvalidProxies,
|
||||
reviveConsumedRequestBodies: options?.reviveConsumedRequestBodies,
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
);
|
||||
export const proxyPlugin = createBackendPlugin({
|
||||
pluginId: 'proxy',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
config: coreServices.rootConfig,
|
||||
discovery: coreServices.discovery,
|
||||
logger: coreServices.logger,
|
||||
httpRouter: coreServices.httpRouter,
|
||||
},
|
||||
async init({ config, discovery, logger, httpRouter }) {
|
||||
httpRouter.use(
|
||||
await createRouter({
|
||||
config,
|
||||
discovery,
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
|
||||
import { getVoidLogger, SingleHostDiscovery } from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
ConfigSources,
|
||||
MutableConfigSource,
|
||||
StaticConfigSource,
|
||||
} from '@backstage/config-loader';
|
||||
import express from 'express';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
@@ -56,34 +60,36 @@ describe('createRouter reloadable configuration', () => {
|
||||
const logger = getVoidLogger();
|
||||
|
||||
// Grab the subscriber function and use mutable config data to mock a config file change
|
||||
let subscriber: () => void;
|
||||
const mutableConfigData: any = {
|
||||
backend: {
|
||||
baseUrl: 'http://localhost:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
},
|
||||
},
|
||||
proxy: {
|
||||
'/test': {
|
||||
target: 'https://non-existing-example.com',
|
||||
pathRewrite: {
|
||||
'.*': '/',
|
||||
const mutableConfigSource = MutableConfigSource.create({ data: {} });
|
||||
const config = await ConfigSources.toConfig(
|
||||
ConfigSources.merge([
|
||||
StaticConfigSource.create({
|
||||
data: {
|
||||
backend: {
|
||||
baseUrl: 'http://localhost:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
},
|
||||
},
|
||||
proxy: {
|
||||
endpoints: {
|
||||
'/test': {
|
||||
target: 'https://non-existing-example.com',
|
||||
pathRewrite: {
|
||||
'.*': '/',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
mutableConfigSource,
|
||||
]),
|
||||
);
|
||||
|
||||
const mockConfig = Object.assign(new ConfigReader(mutableConfigData), {
|
||||
subscribe: (s: () => void) => {
|
||||
subscriber = s;
|
||||
return { unsubscribe: () => {} };
|
||||
},
|
||||
});
|
||||
|
||||
const discovery = SingleHostDiscovery.fromConfig(mockConfig);
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
const router = await createRouter({
|
||||
config: mockConfig,
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
});
|
||||
@@ -100,13 +106,18 @@ describe('createRouter reloadable configuration', () => {
|
||||
|
||||
expect(response1.status).toEqual(200);
|
||||
|
||||
mutableConfigData.proxy['/test2'] = {
|
||||
target: 'https://non-existing-example.com',
|
||||
pathRewrite: {
|
||||
'.*': '/',
|
||||
mutableConfigSource.setData({
|
||||
proxy: {
|
||||
endpoints: {
|
||||
'/test2': {
|
||||
target: 'https://non-existing-example.com',
|
||||
pathRewrite: {
|
||||
'.*': '/',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
subscriber!();
|
||||
});
|
||||
|
||||
const response2 = await agent.get('/test2');
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { getVoidLogger, SingleHostDiscovery } from '@backstage/backend-common';
|
||||
import { mockServices } from '@backstage/backend-test-utils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { Request, Response } from 'express';
|
||||
import * as http from 'http';
|
||||
@@ -45,10 +46,12 @@ describe('createRouter', () => {
|
||||
},
|
||||
},
|
||||
proxy: {
|
||||
'/test': {
|
||||
target: 'https://example.com',
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
endpoints: {
|
||||
'/test': {
|
||||
target: 'https://example.com',
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -68,6 +71,32 @@ describe('createRouter', () => {
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
|
||||
it('supports deprecated proxy configuration', async () => {
|
||||
const router = await createRouter({
|
||||
config: mockServices.rootConfig({
|
||||
data: {
|
||||
proxy: {
|
||||
'/test': {
|
||||
target: 'https://example.com',
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
logger,
|
||||
discovery,
|
||||
});
|
||||
expect(router).toBeDefined();
|
||||
expect(mockCreateProxyMiddleware).toHaveBeenCalledWith(
|
||||
expect.any(Function),
|
||||
expect.objectContaining({
|
||||
target: 'https://example.com',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('revives request bodies when set', async () => {
|
||||
const router = await createRouter({
|
||||
config,
|
||||
@@ -112,9 +141,11 @@ describe('createRouter', () => {
|
||||
},
|
||||
// no target would cause the buildMiddleware to fail
|
||||
proxy: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
endpoints: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -141,9 +172,11 @@ describe('createRouter', () => {
|
||||
},
|
||||
// no target would cause the buildMiddleware to fail
|
||||
proxy: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
endpoints: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -191,6 +191,31 @@ export function buildMiddleware(
|
||||
return createProxyMiddleware(filter, fullConfig);
|
||||
}
|
||||
|
||||
function readProxyConfig(config: Config, logger: Logger): unknown {
|
||||
const endpoints = config.getOptionalConfig('proxy.endpoints')?.get();
|
||||
if (endpoints) {
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
const root = config.getOptionalConfig('proxy')?.get();
|
||||
if (!root) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const rootEndpoints = Object.fromEntries(
|
||||
Object.entries(root).filter(([key]) => key.startsWith('/')),
|
||||
);
|
||||
if (Object.keys(rootEndpoints).length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
"Configuring proxy endpoints in the root 'proxy' configuration is deprecated. Move this configuration to 'proxy.endpoints' instead.",
|
||||
);
|
||||
|
||||
return rootEndpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link https://expressjs.com/en/api.html#router | "express router"} that proxy each target configured under the `proxy` key of the config
|
||||
* @example
|
||||
@@ -215,25 +240,39 @@ export async function createRouter(
|
||||
const router = Router();
|
||||
let currentRouter = Router();
|
||||
|
||||
const skipInvalidProxies =
|
||||
options.skipInvalidProxies ??
|
||||
options.config.getOptionalBoolean('proxy.skipInvalidProxies') ??
|
||||
false;
|
||||
const reviveConsumedRequestBodies =
|
||||
options.reviveConsumedRequestBodies ??
|
||||
options.config.getOptionalBoolean('proxy.reviveConsumedRequestBodies') ??
|
||||
false;
|
||||
const proxyOptions = {
|
||||
skipInvalidProxies,
|
||||
reviveConsumedRequestBodies,
|
||||
logger: options.logger,
|
||||
};
|
||||
|
||||
const externalUrl = await options.discovery.getExternalBaseUrl('proxy');
|
||||
const { pathname: pathPrefix } = new URL(externalUrl);
|
||||
|
||||
const proxyConfig = options.config.getOptional('proxy') ?? {};
|
||||
configureMiddlewares(options, currentRouter, pathPrefix, proxyConfig);
|
||||
const proxyConfig = readProxyConfig(options.config, options.logger);
|
||||
configureMiddlewares(proxyOptions, currentRouter, pathPrefix, proxyConfig);
|
||||
router.use((...args) => currentRouter(...args));
|
||||
|
||||
if (options.config.subscribe) {
|
||||
let currentKey = JSON.stringify(proxyConfig);
|
||||
|
||||
options.config.subscribe(() => {
|
||||
const newProxyConfig = options.config.getOptional('proxy') ?? {};
|
||||
const newProxyConfig = readProxyConfig(options.config, options.logger);
|
||||
const newKey = JSON.stringify(newProxyConfig);
|
||||
|
||||
if (currentKey !== newKey) {
|
||||
currentKey = newKey;
|
||||
currentRouter = Router();
|
||||
configureMiddlewares(
|
||||
options,
|
||||
proxyOptions,
|
||||
currentRouter,
|
||||
pathPrefix,
|
||||
newProxyConfig,
|
||||
@@ -246,7 +285,11 @@ export async function createRouter(
|
||||
}
|
||||
|
||||
function configureMiddlewares(
|
||||
options: RouterOptions,
|
||||
options: {
|
||||
reviveConsumedRequestBodies: boolean;
|
||||
skipInvalidProxies: boolean;
|
||||
logger: Logger;
|
||||
},
|
||||
router: express.Router,
|
||||
pathPrefix: string,
|
||||
proxyConfig: any,
|
||||
|
||||
@@ -8014,8 +8014,10 @@ __metadata:
|
||||
dependencies:
|
||||
"@backstage/backend-common": "workspace:^"
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/config-loader": "workspace:^"
|
||||
"@types/express": ^4.17.6
|
||||
"@types/http-proxy-middleware": ^0.19.3
|
||||
"@types/supertest": ^2.0.8
|
||||
@@ -25184,6 +25186,7 @@ __metadata:
|
||||
"@backstage/plugin-permission-backend": "workspace:^"
|
||||
"@backstage/plugin-permission-common": "workspace:^"
|
||||
"@backstage/plugin-permission-node": "workspace:^"
|
||||
"@backstage/plugin-proxy-backend": "workspace:^"
|
||||
"@backstage/plugin-scaffolder-backend": "workspace:^"
|
||||
"@backstage/plugin-search-backend": "workspace:^"
|
||||
"@backstage/plugin-search-backend-module-catalog": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user