diff --git a/x-pack/plugins/fleet/server/services/settings.test.ts b/x-pack/plugins/fleet/server/services/settings.test.ts index 75712c471f20c1..bec0f737c0bc86 100644 --- a/x-pack/plugins/fleet/server/services/settings.test.ts +++ b/x-pack/plugins/fleet/server/services/settings.test.ts @@ -8,7 +8,7 @@ import { savedObjectsClientMock } from 'src/core/server/mocks'; import { appContextService } from './app_context'; -import { getCloudFleetServersHosts, settingsSetup } from './settings'; +import { getCloudFleetServersHosts, normalizeFleetServerHost, settingsSetup } from './settings'; jest.mock('./app_context'); @@ -205,3 +205,22 @@ describe('settingsSetup', () => { expect(soClientMock.update).not.toBeCalled(); }); }); + +describe('normalizeFleetServerHost', () => { + const scenarios = [ + { sourceUrl: 'http://test.fr', expectedUrl: 'http://test.fr:80' }, + { sourceUrl: 'http://test.fr/test/toto', expectedUrl: 'http://test.fr:80/test/toto' }, + { sourceUrl: 'https://test.fr', expectedUrl: 'https://test.fr:443' }, + { sourceUrl: 'https://test.fr/test/toto', expectedUrl: 'https://test.fr:443/test/toto' }, + { sourceUrl: 'https://test.fr:9243', expectedUrl: 'https://test.fr:9243' }, + { sourceUrl: 'https://test.fr:9243/test/toto', expectedUrl: 'https://test.fr:9243/test/toto' }, + ]; + + for (const scenario of scenarios) { + it(`should transform ${scenario.sourceUrl} correctly`, () => { + const url = normalizeFleetServerHost(scenario.sourceUrl); + + expect(url).toEqual(scenario.expectedUrl); + }); + } +}); diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts index a03c220eecb83d..6b1a17fc5b0603 100644 --- a/x-pack/plugins/fleet/server/services/settings.ts +++ b/x-pack/plugins/fleet/server/services/settings.ts @@ -51,6 +51,30 @@ export async function settingsSetup(soClient: SavedObjectsClientContract) { } } +function getPortForURL(url: URL) { + if (url.port !== '') { + return url.port; + } + + if (url.protocol === 'http:') { + return '80'; + } + + if (url.protocol === 'https:') { + return '443'; + } +} + +export function normalizeFleetServerHost(host: string) { + // Fleet server is not using default port for http|https https://github.com/elastic/beats/issues/25420 + const fleetServerURL = new URL(host); + + // We are building the URL manualy as url format will not include the port if the port is 80 or 443 + return `${fleetServerURL.protocol}//${fleetServerURL.hostname}:${getPortForURL(fleetServerURL)}${ + fleetServerURL.pathname === '/' ? '' : fleetServerURL.pathname + }`; +} + export async function saveSettings( soClient: SavedObjectsClientContract, newData: Partial> @@ -58,10 +82,15 @@ export async function saveSettings( try { const settings = await getSettings(soClient); + const data = { ...newData }; + if (data.fleet_server_hosts) { + data.fleet_server_hosts = data.fleet_server_hosts.map(normalizeFleetServerHost); + } + const res = await soClient.update( GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, settings.id, - newData + data ); return {