mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[cloud plugin] Add serverless projectId to configuration and contract (#161728)
## Summary Fix https://github.com/elastic/kibana/issues/161652 Add the `serverless.projectId` config setting to the `cloud` plugin, and expose the `isCloudServerless` and `serverless.projectId` info from the cloud plugin's API.
This commit is contained in:
parent
e5bcc87202
commit
a9786dfd6b
12 changed files with 217 additions and 4 deletions
|
@ -221,6 +221,8 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.cloud.organization_url (string)',
|
||||
'xpack.cloud.billing_url (string)',
|
||||
'xpack.cloud.profile_url (string)',
|
||||
// can't be used to infer urls or customer id from the outside
|
||||
'xpack.cloud.serverless.project_id (string)',
|
||||
'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)',
|
||||
'xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled (boolean)',
|
||||
'xpack.fleet.agents.enabled (boolean)',
|
||||
|
|
|
@ -26,6 +26,10 @@ function createSetupMock(): jest.Mocked<CloudSetup> {
|
|||
isElasticStaffOwned: true,
|
||||
trialEndDate: new Date('2020-10-01T14:13:12Z'),
|
||||
registerCloudService: jest.fn(),
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -42,6 +46,10 @@ const createStartMock = (): jest.Mocked<CloudStart> => ({
|
|||
billingUrl: 'billing-url',
|
||||
profileUrl: 'profile-url',
|
||||
organizationUrl: 'organization-url',
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
export const cloudMock = {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { decodeCloudIdMock, parseDeploymentIdFromDeploymentUrlMock } from './plugin.test.mocks';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { CloudPlugin } from './plugin';
|
||||
import { CloudPlugin, type CloudConfigType } from './plugin';
|
||||
import type { DecodedCloudId } from '../common/decode_cloud_id';
|
||||
|
||||
const baseConfig = {
|
||||
|
@ -25,11 +25,12 @@ describe('Cloud Plugin', () => {
|
|||
|
||||
describe('#setup', () => {
|
||||
describe('interface', () => {
|
||||
const setupPlugin = () => {
|
||||
const setupPlugin = (configParts: Partial<CloudConfigType> = {}) => {
|
||||
const initContext = coreMock.createPluginInitializerContext({
|
||||
...baseConfig,
|
||||
id: 'cloudId',
|
||||
cname: 'cloud.elastic.co',
|
||||
...configParts,
|
||||
});
|
||||
const plugin = new CloudPlugin(initContext);
|
||||
|
||||
|
@ -114,11 +115,38 @@ describe('Cloud Plugin', () => {
|
|||
expect(decodeCloudIdMock).toHaveBeenCalledTimes(1);
|
||||
expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object));
|
||||
});
|
||||
|
||||
describe('isServerlessEnabled', () => {
|
||||
it('is `true` when `serverless.projectId` is set', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
expect(setup.isServerlessEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('is `false` when `serverless.projectId` is not set', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: undefined,
|
||||
});
|
||||
expect(setup.isServerlessEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('exposes `serverless.projectId`', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
expect(setup.serverless.projectId).toBe('my-awesome-project');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#start', () => {
|
||||
const startPlugin = () => {
|
||||
const startPlugin = (configParts: Partial<CloudConfigType> = {}) => {
|
||||
const plugin = new CloudPlugin(
|
||||
coreMock.createPluginInitializerContext({
|
||||
id: 'cloudId',
|
||||
|
@ -132,6 +160,7 @@ describe('Cloud Plugin', () => {
|
|||
chat: {
|
||||
enabled: false,
|
||||
},
|
||||
...configParts,
|
||||
})
|
||||
);
|
||||
const coreSetup = coreMock.createSetup();
|
||||
|
@ -154,5 +183,38 @@ describe('Cloud Plugin', () => {
|
|||
]
|
||||
`);
|
||||
});
|
||||
|
||||
describe('isServerlessEnabled', () => {
|
||||
it('is `true` when `serverless.projectId` is set', () => {
|
||||
const { plugin } = startPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
const coreStart = coreMock.createStart();
|
||||
const start = plugin.start(coreStart);
|
||||
expect(start.isServerlessEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('is `false` when `serverless.projectId` is not set', () => {
|
||||
const { plugin } = startPlugin({
|
||||
serverless: undefined,
|
||||
});
|
||||
const coreStart = coreMock.createStart();
|
||||
const start = plugin.start(coreStart);
|
||||
expect(start.isServerlessEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('exposes `serverless.projectId`', () => {
|
||||
const { plugin } = startPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
const coreStart = coreMock.createStart();
|
||||
const start = plugin.start(coreStart);
|
||||
expect(start.serverless.projectId).toBe('my-awesome-project');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,6 +26,9 @@ export interface CloudConfigType {
|
|||
organization_url?: string;
|
||||
trial_end_date?: string;
|
||||
is_elastic_staff_owned?: boolean;
|
||||
serverless?: {
|
||||
project_id: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface CloudUrls {
|
||||
|
@ -39,12 +42,14 @@ interface CloudUrls {
|
|||
export class CloudPlugin implements Plugin<CloudSetup> {
|
||||
private readonly config: CloudConfigType;
|
||||
private readonly isCloudEnabled: boolean;
|
||||
private readonly isServerlessEnabled: boolean;
|
||||
private readonly contextProviders: FC[] = [];
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.config = this.initializerContext.config.get<CloudConfigType>();
|
||||
this.isCloudEnabled = getIsCloudEnabled(this.config.id);
|
||||
this.isServerlessEnabled = !!this.config.serverless?.project_id;
|
||||
this.logger = initializerContext.logger.get();
|
||||
}
|
||||
|
||||
|
@ -77,6 +82,10 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
trialEndDate: trialEndDate ? new Date(trialEndDate) : undefined,
|
||||
isElasticStaffOwned,
|
||||
isCloudEnabled: this.isCloudEnabled,
|
||||
isServerlessEnabled: this.isServerlessEnabled,
|
||||
serverless: {
|
||||
projectId: this.config.serverless?.project_id,
|
||||
},
|
||||
registerCloudService: (contextProvider) => {
|
||||
this.contextProviders.push(contextProvider);
|
||||
},
|
||||
|
@ -118,6 +127,10 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
organizationUrl,
|
||||
elasticsearchUrl: decodedId?.elasticsearchUrl,
|
||||
kibanaUrl: decodedId?.kibanaUrl,
|
||||
isServerlessEnabled: this.isServerlessEnabled,
|
||||
serverless: {
|
||||
projectId: this.config.serverless?.project_id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,21 @@ export interface CloudStart {
|
|||
* The full URL to the Kibana deployment.
|
||||
*/
|
||||
kibanaUrl?: string;
|
||||
/**
|
||||
* `true` when running on Serverless Elastic Cloud
|
||||
* Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is.
|
||||
*/
|
||||
isServerlessEnabled: boolean;
|
||||
/**
|
||||
* Serverless configuration
|
||||
*/
|
||||
serverless: {
|
||||
/**
|
||||
* The serverless projectId.
|
||||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
projectId?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CloudSetup {
|
||||
|
@ -112,4 +127,19 @@ export interface CloudSetup {
|
|||
* @param contextProvider The React component from the Service Provider.
|
||||
*/
|
||||
registerCloudService: (contextProvider: FC) => void;
|
||||
/**
|
||||
* `true` when running on Serverless Elastic Cloud
|
||||
* Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is.
|
||||
*/
|
||||
isServerlessEnabled: boolean;
|
||||
/**
|
||||
* Serverless configuration
|
||||
*/
|
||||
serverless: {
|
||||
/**
|
||||
* The serverless projectId.
|
||||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
projectId?: string;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ const configSchema = schema.object({
|
|||
profile_url: schema.maybe(schema.string()),
|
||||
trial_end_date: schema.maybe(schema.string()),
|
||||
is_elastic_staff_owned: schema.maybe(schema.boolean()),
|
||||
serverless: schema.maybe(
|
||||
schema.object({
|
||||
project_id: schema.string(),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
export type CloudConfigType = TypeOf<typeof configSchema>;
|
||||
|
@ -44,6 +49,9 @@ export const config: PluginConfigDescriptor<CloudConfigType> = {
|
|||
profile_url: true,
|
||||
trial_end_date: true,
|
||||
is_elastic_staff_owned: true,
|
||||
serverless: {
|
||||
project_id: true,
|
||||
},
|
||||
},
|
||||
schema: configSchema,
|
||||
};
|
||||
|
|
|
@ -23,6 +23,10 @@ function createSetupMock(): jest.Mocked<CloudSetup> {
|
|||
url: undefined,
|
||||
secretToken: undefined,
|
||||
},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { decodeCloudIdMock, parseDeploymentIdFromDeploymentUrlMock } from './plugin.test.mocks';
|
||||
import { coreMock } from '@kbn/core/server/mocks';
|
||||
import type { CloudConfigType } from './config';
|
||||
import { CloudPlugin } from './plugin';
|
||||
import type { DecodedCloudId } from '../common/decode_cloud_id';
|
||||
|
||||
|
@ -23,11 +24,12 @@ describe('Cloud Plugin', () => {
|
|||
decodeCloudIdMock.mockReset().mockReturnValue({});
|
||||
});
|
||||
|
||||
const setupPlugin = () => {
|
||||
const setupPlugin = (configParts: Partial<CloudConfigType> = {}) => {
|
||||
const initContext = coreMock.createPluginInitializerContext({
|
||||
...baseConfig,
|
||||
id: 'cloudId',
|
||||
cname: 'cloud.elastic.co',
|
||||
...configParts,
|
||||
});
|
||||
const plugin = new CloudPlugin(initContext);
|
||||
|
||||
|
@ -90,6 +92,33 @@ describe('Cloud Plugin', () => {
|
|||
expect(decodeCloudIdMock).toHaveBeenCalledTimes(1);
|
||||
expect(decodeCloudIdMock).toHaveBeenCalledWith('cloudId', expect.any(Object));
|
||||
});
|
||||
|
||||
describe('isServerlessEnabled', () => {
|
||||
it('is `true` when `serverless.projectId` is set', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
expect(setup.isServerlessEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('is `false` when `serverless.projectId` is not set', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: undefined,
|
||||
});
|
||||
expect(setup.isServerlessEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('exposes `serverless.projectId`', () => {
|
||||
const { setup } = setupPlugin({
|
||||
serverless: {
|
||||
project_id: 'my-awesome-project',
|
||||
},
|
||||
});
|
||||
expect(setup.serverless.projectId).toBe('my-awesome-project');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -71,6 +71,21 @@ export interface CloudSetup {
|
|||
url?: string;
|
||||
secretToken?: string;
|
||||
};
|
||||
/**
|
||||
* `true` when running on Serverless Elastic Cloud
|
||||
* Note that `isCloudEnabled` will always be true when `isServerlessEnabled` is.
|
||||
*/
|
||||
isServerlessEnabled: boolean;
|
||||
/**
|
||||
* Serverless configuration
|
||||
*/
|
||||
serverless: {
|
||||
/**
|
||||
* The serverless projectId.
|
||||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
projectId?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,6 +109,8 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
|
||||
public setup(core: CoreSetup, { usageCollection }: PluginsSetup): CloudSetup {
|
||||
const isCloudEnabled = getIsCloudEnabled(this.config.id);
|
||||
const isServerlessEnabled = !!this.config.serverless?.project_id;
|
||||
|
||||
registerCloudDeploymentMetadataAnalyticsContext(core.analytics, this.config);
|
||||
registerCloudUsageCollector(usageCollection, {
|
||||
isCloudEnabled,
|
||||
|
@ -121,6 +138,10 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
url: this.config.apm?.url,
|
||||
secretToken: this.config.apm?.secret_token,
|
||||
},
|
||||
isServerlessEnabled,
|
||||
serverless: {
|
||||
projectId: this.config.serverless?.project_id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@ const defaultPortCloud = {
|
|||
cloudHost: 'us-central1.gcp.cloud.es.io',
|
||||
cloudDefaultPort: '443',
|
||||
registerCloudService: jest.fn(),
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
// 9243
|
||||
const customPortCloud = {
|
||||
|
@ -25,17 +29,29 @@ const customPortCloud = {
|
|||
cloudHost: 'us-central1.gcp.cloud.es.io',
|
||||
cloudDefaultPort: '9243',
|
||||
registerCloudService: jest.fn(),
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
const missingDeploymentIdCloud = {
|
||||
cloudId:
|
||||
'dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=',
|
||||
isCloudEnabled: true,
|
||||
registerCloudService: jest.fn(),
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
const noCloud = {
|
||||
cloudId: undefined,
|
||||
isCloudEnabled: false,
|
||||
registerCloudService: jest.fn(),
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
describe('getCloudEnterpriseSearchHost', () => {
|
||||
|
|
|
@ -18,6 +18,10 @@ export const getCloud = ({ isCloudEnabled }: { isCloudEnabled: boolean }) => {
|
|||
profileUrl: 'https://profile.url',
|
||||
snapshotsUrl: 'https://snapshots.url',
|
||||
registerCloudService: () => {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
return cloud;
|
||||
|
|
|
@ -120,6 +120,10 @@ describe('getCloudFleetServersHosts', () => {
|
|||
deploymentId: 'deployment-id-1',
|
||||
cloudHost: 'us-east-1.aws.found.io',
|
||||
apm: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
expect(getCloudFleetServersHosts()).toMatchInlineSnapshot(`
|
||||
|
@ -138,6 +142,10 @@ describe('getCloudFleetServersHosts', () => {
|
|||
cloudHost: 'test.fr',
|
||||
cloudDefaultPort: '9243',
|
||||
apm: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
expect(getCloudFleetServersHosts()).toMatchInlineSnapshot(`
|
||||
|
@ -171,6 +179,10 @@ describe('createCloudFleetServerHostIfNeeded', () => {
|
|||
isCloudEnabled: true,
|
||||
deploymentId: 'deployment-id-1',
|
||||
apm: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
});
|
||||
mockedGetDefaultFleetServerHost.mockResolvedValue({
|
||||
id: 'test',
|
||||
|
@ -190,6 +202,10 @@ describe('createCloudFleetServerHostIfNeeded', () => {
|
|||
deploymentId: 'deployment-id-1',
|
||||
cloudHost: 'us-east-1.aws.found.io',
|
||||
apm: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
});
|
||||
mockedGetDefaultFleetServerHost.mockResolvedValue(null);
|
||||
soClient.create.mockResolvedValue({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue