Skip to content

Commit

Permalink
[Stateful sidenav] Add cloud yml setting for onboarding default solut…
Browse files Browse the repository at this point in the history
…ion (#184808)
  • Loading branch information
sebelga authored Jun 6, 2024
1 parent 7d8fc90 commit 667a9d3
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'xpack.cloud.serverless.project_id (string)',
'xpack.cloud.serverless.project_name (string)',
'xpack.cloud.serverless.project_type (string)',
'xpack.cloud.onboarding.default_solution (string)',
'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)',
'xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled (boolean)',
'xpack.fleet.agents.enabled (boolean)',
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/cloud/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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 type { OnBoardingDefaultSolution } from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { parseOnboardingSolution } from './parse_onboarding_default_solution';

describe('parseOnboardingSolution', () => {
it('should return undefined if there is no default solution defined', () => {
expect(parseOnboardingSolution()).toBeUndefined();
});

it('should map correctly the cloud values to the Kibana values, regardless of case', () => {
[
['elasticsearch', 'es'],
['Elasticsearch', 'es'],
['observability', 'oblt'],
['Observability', 'oblt'],
['security', 'security'],
['Security', 'security'],
].forEach(([cloudValue, kibanaValue]) => {
expect(parseOnboardingSolution(cloudValue)).toBe(kibanaValue);
expect(parseOnboardingSolution(cloudValue.toUpperCase())).toBe(kibanaValue);
expect(parseOnboardingSolution(cloudValue.toLowerCase())).toBe(kibanaValue);
});
});

it('should return undefined for unknown values', () => {
expect(parseOnboardingSolution('unknown')).toBeUndefined();
});
});
39 changes: 39 additions & 0 deletions x-pack/plugins/cloud/common/parse_onboarding_default_solution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 type { OnBoardingDefaultSolution } from './types';

/**
* Cloud does not type the value of the "use case" that is set during onboarding for a deployment. Any string can
* be passed. This function maps the known values to the Kibana values.
*
* @param value The solution value set by Cloud.
* @returns The default solution value for onboarding that matches Kibana naming.
*/
export function parseOnboardingSolution(value?: string): OnBoardingDefaultSolution | undefined {
if (!value) return;

const solutions: Array<{
cloudValue: 'elasticsearch' | 'observability' | 'security';
kibanaValue: OnBoardingDefaultSolution;
}> = [
{
cloudValue: 'elasticsearch',
kibanaValue: 'es',
},
{
cloudValue: 'observability',
kibanaValue: 'oblt',
},
{
cloudValue: 'security',
kibanaValue: 'security',
},
];

return solutions.find(({ cloudValue }) => value.toLowerCase() === cloudValue)?.kibanaValue;
}
8 changes: 8 additions & 0 deletions x-pack/plugins/cloud/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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 type OnBoardingDefaultSolution = 'es' | 'oblt' | 'security';
1 change: 1 addition & 0 deletions x-pack/plugins/cloud/public/mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function createSetupMock(): jest.Mocked<CloudSetup> {
isElasticStaffOwned: true,
trialEndDate: new Date('2020-10-01T14:13:12Z'),
registerCloudService: jest.fn(),
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/cloud/public/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ describe('Cloud Plugin', () => {
expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object));
});

it('exposes `onboarding.default_solution`', () => {
const { setup } = setupPlugin({
onboarding: {
default_solution: 'Elasticsearch',
},
});
expect(setup.onboarding.defaultSolution).toBe('es');
});

describe('isServerlessEnabled', () => {
it('is `true` when `serverless.projectId` is set', () => {
const { setup } = setupPlugin({
Expand Down
10 changes: 9 additions & 1 deletion x-pack/plugins/cloud/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import React, { FC, PropsWithChildren } from 'react';
import type { Logger } from '@kbn/logging';
import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';

import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url';
import { CLOUD_SNAPSHOTS_PATH } from '../common/constants';
import { decodeCloudId, type DecodedCloudId } from '../common/decode_cloud_id';
import type { CloudSetup, CloudStart } from './types';
import { getFullCloudUrl } from '../common/utils';
import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution';
import type { CloudSetup, CloudStart } from './types';
import { getSupportUrl } from './utils';

export interface CloudConfigType {
Expand All @@ -31,6 +33,9 @@ export interface CloudConfigType {
performance_url?: string;
trial_end_date?: string;
is_elastic_staff_owned?: boolean;
onboarding?: {
default_solution?: string;
};
serverless?: {
project_id: string;
project_name?: string;
Expand Down Expand Up @@ -95,6 +100,9 @@ export class CloudPlugin implements Plugin<CloudSetup> {
trialEndDate: trialEndDate ? new Date(trialEndDate) : undefined,
isElasticStaffOwned,
isCloudEnabled: this.isCloudEnabled,
onboarding: {
defaultSolution: parseOnboardingSolution(this.config.onboarding?.default_solution),
},
isServerlessEnabled: this.isServerlessEnabled,
serverless: {
projectId: this.config.serverless?.project_id,
Expand Down
10 changes: 10 additions & 0 deletions x-pack/plugins/cloud/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import type { FC, PropsWithChildren } from 'react';
import type { OnBoardingDefaultSolution } from '../common';

export interface CloudStart {
/**
Expand Down Expand Up @@ -174,6 +175,15 @@ export interface CloudSetup {
* @param contextProvider The React component from the Service Provider.
*/
registerCloudService: (contextProvider: FC) => void;
/**
* Onboarding configuration
*/
onboarding: {
/**
* The default solution selected during onboarding.
*/
defaultSolution?: OnBoardingDefaultSolution;
};
/**
* `true` when running on Serverless Elastic Cloud
* Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is.
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/cloud/server/__snapshots__/plugin.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions x-pack/plugins/cloud/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const configSchema = schema.object({
projects_url: offeringBasedSchema({ serverless: schema.string({ defaultValue: '/projects/' }) }),
trial_end_date: schema.maybe(schema.string()),
is_elastic_staff_owned: schema.maybe(schema.boolean()),
onboarding: schema.maybe(
schema.object({
default_solution: schema.maybe(schema.string()),
})
),
serverless: schema.maybe(
schema.object(
{
Expand Down Expand Up @@ -68,6 +73,9 @@ export const config: PluginConfigDescriptor<CloudConfigType> = {
project_name: true,
project_type: true,
},
onboarding: {
default_solution: true,
},
},
schema: configSchema,
};
1 change: 1 addition & 0 deletions x-pack/plugins/cloud/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function createSetupMock(): jest.Mocked<CloudSetup> {
url: undefined,
secretToken: undefined,
},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/cloud/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ describe('Cloud Plugin', () => {
expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object));
});

it('exposes `onboarding.default_solution`', () => {
const { setup } = setupPlugin({
onboarding: {
default_solution: 'Elasticsearch',
},
});
expect(setup.onboarding.defaultSolution).toBe('es');
});

describe('isServerlessEnabled', () => {
it('is `true` when `serverless.projectId` is set', () => {
const { setup } = setupPlugin({
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/cloud/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context';
import type { CloudConfigType } from './config';
import { registerCloudUsageCollector } from './collectors';
import type { OnBoardingDefaultSolution } from '../common';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url';
import { decodeCloudId, DecodedCloudId } from '../common/decode_cloud_id';
import { parseOnboardingSolution } from '../common/parse_onboarding_default_solution';
import { getFullCloudUrl } from '../common/utils';
import { readInstanceSizeMb } from './env';

Expand Down Expand Up @@ -88,6 +90,15 @@ export interface CloudSetup {
url?: string;
secretToken?: string;
};
/**
* Onboarding configuration.
*/
onboarding: {
/**
* The default solution selected during onboarding.
*/
defaultSolution?: OnBoardingDefaultSolution;
};
/**
* `true` when running on Serverless Elastic Cloud
* Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is.
Expand Down Expand Up @@ -188,6 +199,9 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
url: this.config.apm?.url,
secretToken: this.config.apm?.secret_token,
},
onboarding: {
defaultSolution: parseOnboardingSolution(this.config.onboarding?.default_solution),
},
isServerlessEnabled,
serverless: {
projectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const defaultPortCloud = {
cloudHost: 'us-central1.gcp.cloud.es.io',
cloudDefaultPort: '443',
registerCloudService: jest.fn(),
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand All @@ -29,6 +30,7 @@ const customPortCloud = {
cloudHost: 'us-central1.gcp.cloud.es.io',
cloudDefaultPort: '9243',
registerCloudService: jest.fn(),
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand All @@ -39,6 +41,7 @@ const missingDeploymentIdCloud = {
'dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=',
isCloudEnabled: true,
registerCloudService: jest.fn(),
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand All @@ -48,6 +51,7 @@ const noCloud = {
cloudId: undefined,
isCloudEnabled: false,
registerCloudService: jest.fn(),
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/.storybook/context/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
profileUrl: 'https://profile.url',
snapshotsUrl: 'https://snapshots.url',
registerCloudService: () => {},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ describe('getCloudFleetServersHosts', () => {
deploymentId: 'deployment-id-1',
cloudHost: 'us-east-1.aws.found.io',
apm: {},
onboarding: {},
isServerlessEnabled: true,
serverless: {
projectId: undefined,
Expand All @@ -176,6 +177,7 @@ describe('getCloudFleetServersHosts', () => {
deploymentId: 'deployment-id-1',
cloudHost: 'us-east-1.aws.found.io',
apm: {},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand All @@ -198,6 +200,7 @@ describe('getCloudFleetServersHosts', () => {
cloudHost: 'test.fr',
cloudDefaultPort: '9243',
apm: {},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down Expand Up @@ -233,6 +236,7 @@ describe('createCloudFleetServerHostIfNeeded', () => {
isCloudEnabled: true,
deploymentId: 'deployment-id-1',
apm: {},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand All @@ -256,6 +260,7 @@ describe('createCloudFleetServerHostIfNeeded', () => {
deploymentId: 'deployment-id-1',
cloudHost: 'us-east-1.aws.found.io',
apm: {},
onboarding: {},
isServerlessEnabled: false,
serverless: {
projectId: undefined,
Expand Down

0 comments on commit 667a9d3

Please sign in to comment.