diff --git a/x-pack/plugins/cloud/server/plugin.ts b/x-pack/plugins/cloud/server/plugin.ts index 6abfb864d1cd0..fea8be9f934e1 100644 --- a/x-pack/plugins/cloud/server/plugin.ts +++ b/x-pack/plugins/cloud/server/plugin.ts @@ -10,6 +10,7 @@ import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/se import { CloudConfigType } from './config'; import { registerCloudUsageCollector } from './collectors'; import { getIsCloudEnabled } from '../common/is_cloud_enabled'; +import { parseDeploymentIdFromDeploymentUrl } from './utils'; interface PluginsSetup { usageCollection?: UsageCollectionSetup; @@ -17,6 +18,7 @@ interface PluginsSetup { export interface CloudSetup { cloudId?: string; + deploymentId?: string; isCloudEnabled: boolean; apm: { url?: string; @@ -40,6 +42,7 @@ export class CloudPlugin implements Plugin { return { cloudId: this.config.id, + deploymentId: parseDeploymentIdFromDeploymentUrl(this.config.deployment_url), isCloudEnabled, apm: { url: this.config.apm?.url, diff --git a/x-pack/plugins/cloud/server/utils.test.ts b/x-pack/plugins/cloud/server/utils.test.ts new file mode 100644 index 0000000000000..00e7de7336c7a --- /dev/null +++ b/x-pack/plugins/cloud/server/utils.test.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { parseDeploymentIdFromDeploymentUrl } from './utils'; + +describe('parseDeploymentIdFromDeploymentUrl', () => { + it('should return undefined if there is no deploymentUrl configured', () => { + expect(parseDeploymentIdFromDeploymentUrl()).toBeUndefined(); + }); + + it('should return the deploymentId if this is a valid deployment url', () => { + expect(parseDeploymentIdFromDeploymentUrl('deployments/uuid-deployment-1')).toBe( + 'uuid-deployment-1' + ); + }); +}); diff --git a/x-pack/plugins/cloud/server/utils.ts b/x-pack/plugins/cloud/server/utils.ts new file mode 100644 index 0000000000000..635f0e83f79e5 --- /dev/null +++ b/x-pack/plugins/cloud/server/utils.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function parseDeploymentIdFromDeploymentUrl(deploymentUrl?: string) { + if (!deploymentUrl) { + return; + } + return deploymentUrl.split('/').pop(); +} diff --git a/x-pack/plugins/fleet/server/services/settings.test.ts b/x-pack/plugins/fleet/server/services/settings.test.ts new file mode 100644 index 0000000000000..a9f9600addc39 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/settings.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { appContextService } from './app_context'; +import { getCloudFleetServersHosts } from './settings'; + +jest.mock('./app_context'); + +const mockedAppContextService = appContextService as jest.Mocked; + +describe('getCloudFleetServersHosts', () => { + it('should return undefined if cloud is not setup', () => { + expect(getCloudFleetServersHosts()).toBeUndefined(); + }); + + it('should return fleet server hosts if cloud is correctly setup', () => { + mockedAppContextService.getCloud.mockReturnValue({ + cloudId: + 'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==', + isCloudEnabled: true, + deploymentId: 'deployment-id-1', + apm: {}, + }); + + expect(getCloudFleetServersHosts()).toMatchInlineSnapshot(` + Array [ + "https://deployment-id-1.fleet.us-east-1.aws.found.io", + ] + `); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts index e0723a8e16306..4ef9a3a95cbd0 100644 --- a/x-pack/plugins/fleet/server/services/settings.ts +++ b/x-pack/plugins/fleet/server/services/settings.ts @@ -8,7 +8,7 @@ import Boom from '@hapi/boom'; import type { SavedObjectsClientContract } from 'kibana/server'; -import { GLOBAL_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; +import { decodeCloudId, GLOBAL_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; import type { SettingsSOAttributes, Settings, BaseSettings } from '../../common'; import { appContextService } from './app_context'; @@ -65,9 +65,25 @@ export async function saveSettings( } export function createDefaultSettings(): BaseSettings { - const fleetServerHosts = appContextService.getConfig()?.agents?.fleet_server?.hosts ?? []; + const configFleetServerHosts = appContextService.getConfig()?.agents?.fleet_server?.hosts; + const cloudFleetServerHosts = getCloudFleetServersHosts(); + + const fleetServerHosts = configFleetServerHosts ?? cloudFleetServerHosts ?? []; return { fleet_server_hosts: fleetServerHosts, }; } + +export function getCloudFleetServersHosts() { + const cloudSetup = appContextService.getCloud(); + if (cloudSetup && cloudSetup.isCloudEnabled && cloudSetup.cloudId && cloudSetup.deploymentId) { + const res = decodeCloudId(cloudSetup.cloudId); + if (!res) { + return; + } + + // Fleet Server url are formed like this `https://.fleet. + return [`https://${cloudSetup.deploymentId}.fleet.${res.host}`]; + } +}