refactor: Use single HostDiscovery and deprecate SingleHostDiscovery via re-exporting
Signed-off-by: Jack Palmer <jackpalmer@spotify.com>
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* 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 { ConfigReader } from '@backstage/config';
|
||||
import { SingleHostDiscovery } from './SingleHostDiscovery';
|
||||
|
||||
describe('SingleHostDiscovery', () => {
|
||||
it('is created from config', async () => {
|
||||
const discovery = SingleHostDiscovery.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'http://localhost:40',
|
||||
listen: { port: 80, host: 'localhost' },
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(discovery.getBaseUrl('catalog')).resolves.toBe(
|
||||
'http://localhost:80/api/catalog',
|
||||
);
|
||||
await expect(discovery.getExternalBaseUrl('catalog')).resolves.toBe(
|
||||
'http://localhost:40/api/catalog',
|
||||
);
|
||||
});
|
||||
|
||||
it('can configure the base path', async () => {
|
||||
const discovery = SingleHostDiscovery.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'http://localhost:40',
|
||||
listen: { port: 80, host: 'localhost' },
|
||||
},
|
||||
}),
|
||||
{ basePath: '/service' },
|
||||
);
|
||||
|
||||
await expect(discovery.getBaseUrl('catalog')).resolves.toBe(
|
||||
'http://localhost:80/service/catalog',
|
||||
);
|
||||
await expect(discovery.getExternalBaseUrl('catalog')).resolves.toBe(
|
||||
'http://localhost:40/service/catalog',
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[{ listen: ':80' }, 'http://localhost:80'],
|
||||
[{ listen: ':40', https: true }, 'https://localhost:40'],
|
||||
[{ listen: '127.0.0.1:80' }, 'http://127.0.0.1:80'],
|
||||
[{ listen: '127.0.0.1:80', https: true }, 'https://127.0.0.1:80'],
|
||||
[{ listen: '0.0.0.0:40' }, 'http://127.0.0.1:40'],
|
||||
[{ listen: { port: 80 } }, 'http://localhost:80'],
|
||||
[{ listen: { port: 8000 } }, 'http://localhost:8000'],
|
||||
[{ listen: { port: 80, host: '0.0.0.0' } }, 'http://127.0.0.1:80'],
|
||||
[{ listen: { port: 80, host: '::' } }, 'http://localhost:80'],
|
||||
[{ listen: { port: 80, host: '::1' } }, 'http://[::1]:80'],
|
||||
[{ listen: { port: 90, host: '::2' }, https: true }, 'https://[::2]:90'],
|
||||
])('resolves internal baseUrl for %j as %s', async (config, expected) => {
|
||||
const discovery = SingleHostDiscovery.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
baseUrl: 'http://localhost:40',
|
||||
...config,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(discovery.getBaseUrl('catalog')).resolves.toBe(
|
||||
`${expected}/api/catalog`,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* 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 { Config } from '@backstage/config';
|
||||
import { PluginEndpointDiscovery } from './types';
|
||||
import { readHttpServerOptions } from '@backstage/backend-app-api';
|
||||
|
||||
/**
|
||||
* SingleHostDiscovery is a basic PluginEndpointDiscovery implementation
|
||||
* that assumes that all plugins are hosted in a single deployment.
|
||||
*
|
||||
* The deployment may be scaled horizontally, as long as the external URL
|
||||
* is the same for all instances. However, internal URLs will always be
|
||||
* resolved to the same host, so there won't be any balancing of internal traffic.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Use `HostDiscovery` instead
|
||||
*/
|
||||
export class SingleHostDiscovery implements PluginEndpointDiscovery {
|
||||
/**
|
||||
* Creates a new SingleHostDiscovery discovery instance by reading
|
||||
* from the `backend` config section, specifically the `.baseUrl` for
|
||||
* discovering the external URL, and the `.listen` and `.https` config
|
||||
* for the internal one.
|
||||
*
|
||||
* The basePath defaults to `/api`, meaning the default full internal
|
||||
* path for the `catalog` plugin will be `http://localhost:7007/api/catalog`.
|
||||
*/
|
||||
static fromConfig(config: Config, options?: { basePath?: string }) {
|
||||
const basePath = options?.basePath ?? '/api';
|
||||
const externalBaseUrl = config.getString('backend.baseUrl');
|
||||
|
||||
const {
|
||||
listen: { host: listenHost = '::', port: listenPort },
|
||||
} = readHttpServerOptions(config.getConfig('backend'));
|
||||
const protocol = config.has('backend.https') ? 'https' : 'http';
|
||||
|
||||
// Translate bind-all to localhost, and support IPv6
|
||||
let host = listenHost;
|
||||
if (host === '::' || host === '') {
|
||||
// We use localhost instead of ::1, since IPv6-compatible systems should default
|
||||
// to using IPv6 when they see localhost, but if the system doesn't support IPv6
|
||||
// things will still work.
|
||||
host = 'localhost';
|
||||
} else if (host === '0.0.0.0') {
|
||||
host = '127.0.0.1';
|
||||
}
|
||||
if (host.includes(':')) {
|
||||
host = `[${host}]`;
|
||||
}
|
||||
|
||||
const internalBaseUrl = `${protocol}://${host}:${listenPort}`;
|
||||
|
||||
return new SingleHostDiscovery(
|
||||
internalBaseUrl + basePath,
|
||||
externalBaseUrl + basePath,
|
||||
);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private readonly internalBaseUrl: string,
|
||||
private readonly externalBaseUrl: string,
|
||||
) {}
|
||||
|
||||
async getBaseUrl(pluginId: string): Promise<string> {
|
||||
return `${this.internalBaseUrl}/${pluginId}`;
|
||||
}
|
||||
|
||||
async getExternalBaseUrl(pluginId: string): Promise<string> {
|
||||
return `${this.externalBaseUrl}/${pluginId}`;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { SingleHostDiscovery } from './SingleHostDiscovery';
|
||||
import { HostDiscovery } from './HostDiscovery';
|
||||
/**
|
||||
* SingleHostDiscovery is a basic PluginEndpointDiscovery implementation
|
||||
* that assumes that all plugins are hosted in a single deployment.
|
||||
*
|
||||
* The deployment may be scaled horizontally, as long as the external URL
|
||||
* is the same for all instances. However, internal URLs will always be
|
||||
* resolved to the same host, so there won't be any balancing of internal traffic.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Use {@link HostDiscovery} instead
|
||||
*/
|
||||
export const SingleHostDiscovery = HostDiscovery;
|
||||
export { HostDiscovery } from './HostDiscovery';
|
||||
export type { PluginEndpointDiscovery } from './types';
|
||||
|
||||
Reference in New Issue
Block a user