Merge pull request #9225 from RoadieHQ/softer-proxy-startup
allow backend to start if proxy target is not set
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
---
|
||||
'@backstage/plugin-proxy-backend': patch
|
||||
---
|
||||
|
||||
Adds a new option `skipInvalidTargets` for the proxy `createRouter` which allows the proxy backend to be started with an invalid proxy configuration. If configured, it will simply skip the failed proxy and mount the other valid proxies.
|
||||
|
||||
To configure it to pass by failing proxies:
|
||||
|
||||
```
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
skipInvalidProxies: true,
|
||||
});
|
||||
```
|
||||
|
||||
If you would like it to fail if a proxy is configured badly:
|
||||
|
||||
```
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
});
|
||||
```
|
||||
@@ -30,23 +30,96 @@ const mockCreateProxyMiddleware = createProxyMiddleware as jest.MockedFunction<
|
||||
>;
|
||||
|
||||
describe('createRouter', () => {
|
||||
it('works', async () => {
|
||||
const logger = getVoidLogger();
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'https://example.com:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
describe('where all proxy config are valid', () => {
|
||||
it('works', async () => {
|
||||
const logger = getVoidLogger();
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'https://example.com:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
},
|
||||
},
|
||||
},
|
||||
proxy: {
|
||||
'/test': {
|
||||
target: 'https://example.com',
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
});
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
});
|
||||
|
||||
describe('where buildMiddleware would fail', () => {
|
||||
it('throws an error if skip failures is not set', async () => {
|
||||
const logger = getVoidLogger();
|
||||
logger.warn = jest.fn();
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'https://example.com:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
},
|
||||
},
|
||||
// no target would cause the buildMiddleware to fail
|
||||
proxy: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
await expect(
|
||||
createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
}),
|
||||
).rejects.toThrow(new Error('Proxy target must be a string'));
|
||||
});
|
||||
|
||||
it('works if skip failures is set', async () => {
|
||||
const logger = getVoidLogger();
|
||||
logger.warn = jest.fn();
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'https://example.com:7007',
|
||||
listen: {
|
||||
port: 7007,
|
||||
},
|
||||
},
|
||||
// no target would cause the buildMiddleware to fail
|
||||
proxy: {
|
||||
'/test': {
|
||||
headers: {
|
||||
Authorization: 'Bearer supersecret',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
const router = await createRouter({
|
||||
config,
|
||||
logger,
|
||||
discovery,
|
||||
skipInvalidProxies: true,
|
||||
});
|
||||
expect((logger.warn as jest.Mock).mock.calls[0][0]).toEqual(
|
||||
'skipped configuring /test due to Proxy target must be a string',
|
||||
);
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
expect(router).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ export interface RouterOptions {
|
||||
logger: Logger;
|
||||
config: Config;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
skipInvalidProxies?: boolean;
|
||||
}
|
||||
|
||||
export interface ProxyConfig extends Options {
|
||||
@@ -185,11 +186,20 @@ export async function createRouter(
|
||||
const { pathname: pathPrefix } = new URL(externalUrl);
|
||||
|
||||
const proxyConfig = options.config.getOptional('proxy') ?? {};
|
||||
|
||||
Object.entries(proxyConfig).forEach(([route, proxyRouteConfig]) => {
|
||||
router.use(
|
||||
route,
|
||||
buildMiddleware(pathPrefix, options.logger, route, proxyRouteConfig),
|
||||
);
|
||||
try {
|
||||
router.use(
|
||||
route,
|
||||
buildMiddleware(pathPrefix, options.logger, route, proxyRouteConfig),
|
||||
);
|
||||
} catch (e) {
|
||||
if (options.skipInvalidProxies) {
|
||||
options.logger.warn(`skipped configuring ${route} due to ${e.message}`);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
|
||||
Reference in New Issue
Block a user