mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Cloud] Extend metadata (#189001)
This commit is contained in:
parent
850aa69648
commit
56fc5ce8e1
12 changed files with 129 additions and 11 deletions
|
@ -487,7 +487,7 @@ The plugin exposes the static DefaultEditorController class to consume.
|
|||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/cloud/README.md[cloud]
|
||||
|The cloud plugin adds Cloud-specific features to Kibana.
|
||||
|The cloud plugin exposes Cloud-specific metadata to Kibana.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/cloud_integrations/cloud_chat/README.md[cloudChat]
|
||||
|
|
|
@ -246,6 +246,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.cloud_integrations.full_story.eventTypesAllowlist (array)',
|
||||
'xpack.cloud_integrations.full_story.pageVarsDebounceTime (duration)',
|
||||
'xpack.cloud.id (string)',
|
||||
'xpack.cloud.organization_id (string)',
|
||||
'xpack.cloud.organization_url (string)',
|
||||
'xpack.cloud.billing_url (string)',
|
||||
'xpack.cloud.profile_url (string)',
|
||||
|
@ -256,6 +257,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.serverless.orchestrator_target (string)',
|
||||
'xpack.cloud.onboarding.default_solution (string)',
|
||||
'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)',
|
||||
'xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled (boolean)',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# `cloud` plugin
|
||||
|
||||
The `cloud` plugin adds Cloud-specific features to Kibana.
|
||||
The `cloud` plugin exposes Cloud-specific metadata to Kibana.
|
|
@ -11,12 +11,14 @@ import { parseDeploymentIdFromDeploymentUrl } from './parse_deployment_id_from_d
|
|||
|
||||
export interface CloudDeploymentMetadata {
|
||||
id?: string;
|
||||
organization_id?: string;
|
||||
trial_end_date?: string;
|
||||
is_elastic_staff_owned?: boolean;
|
||||
deployment_url?: string;
|
||||
serverless?: {
|
||||
project_id?: string;
|
||||
project_type?: string;
|
||||
orchestrator_target?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,26 +31,40 @@ export function registerCloudDeploymentMetadataAnalyticsContext(
|
|||
}
|
||||
const {
|
||||
id: cloudId,
|
||||
organization_id: organizationId,
|
||||
trial_end_date: cloudTrialEndDate,
|
||||
is_elastic_staff_owned: cloudIsElasticStaffOwned,
|
||||
serverless: { project_id: projectId, project_type: projectType } = {},
|
||||
serverless: {
|
||||
project_id: projectId,
|
||||
project_type: projectType,
|
||||
orchestrator_target: orchestratorTarget,
|
||||
} = {},
|
||||
} = cloudMetadata;
|
||||
|
||||
analytics.registerContextProvider({
|
||||
name: 'Cloud Deployment Metadata',
|
||||
context$: of({
|
||||
cloudId,
|
||||
organizationId,
|
||||
deploymentId: parseDeploymentIdFromDeploymentUrl(cloudMetadata.deployment_url),
|
||||
cloudTrialEndDate,
|
||||
cloudIsElasticStaffOwned,
|
||||
projectId,
|
||||
projectType,
|
||||
orchestratorTarget,
|
||||
}),
|
||||
schema: {
|
||||
cloudId: {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'The Cloud ID' },
|
||||
},
|
||||
organizationId: {
|
||||
type: 'keyword',
|
||||
_meta: {
|
||||
description: 'The Elastic Cloud Organization ID that owns the deployment/project',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
deploymentId: {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'The Deployment ID', optional: true },
|
||||
|
@ -72,6 +88,13 @@ export function registerCloudDeploymentMetadataAnalyticsContext(
|
|||
type: 'keyword',
|
||||
_meta: { description: 'The Serverless Project type', optional: true },
|
||||
},
|
||||
orchestratorTarget: {
|
||||
type: 'keyword',
|
||||
_meta: {
|
||||
description: 'The Orchestrator Target where it is deployed (canary/non-canary)',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import { getSupportUrl } from './utils';
|
|||
|
||||
export interface CloudConfigType {
|
||||
id?: string;
|
||||
organization_id?: string;
|
||||
cname?: string;
|
||||
base_url?: string;
|
||||
profile_url?: string;
|
||||
|
@ -40,6 +41,7 @@ export interface CloudConfigType {
|
|||
project_id: string;
|
||||
project_name?: string;
|
||||
project_type?: string;
|
||||
orchestrator_target?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -89,6 +91,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
|
||||
return {
|
||||
cloudId: id,
|
||||
organizationId: this.config.organization_id,
|
||||
deploymentId: parseDeploymentIdFromDeploymentUrl(this.config.deployment_url),
|
||||
cname,
|
||||
baseUrl,
|
||||
|
@ -108,6 +111,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
projectId: this.config.serverless?.project_id,
|
||||
projectName: this.config.serverless?.project_name,
|
||||
projectType: this.config.serverless?.project_type,
|
||||
orchestratorTarget: this.config.serverless?.orchestrator_target,
|
||||
},
|
||||
registerCloudService: (contextProvider) => {
|
||||
this.contextProviders.push(contextProvider);
|
||||
|
|
|
@ -97,6 +97,10 @@ export interface CloudSetup {
|
|||
* Cloud ID. Undefined if not running on Cloud.
|
||||
*/
|
||||
cloudId?: string;
|
||||
/**
|
||||
* The Elastic Cloud Organization that owns this deployment/project.
|
||||
*/
|
||||
organizationId?: string;
|
||||
/**
|
||||
* The deployment's ID. Only available when running on Elastic Cloud.
|
||||
*/
|
||||
|
@ -208,5 +212,10 @@ export interface CloudSetup {
|
|||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
projectType?: string;
|
||||
/**
|
||||
* The serverless orchestrator target. The potential values are `canary` or `non-canary`
|
||||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
orchestratorTarget?: string;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,8 +20,10 @@ Object {
|
|||
"onboarding": Object {
|
||||
"defaultSolution": undefined,
|
||||
},
|
||||
"organizationId": undefined,
|
||||
"projectsUrl": "https://cloud.elastic.co/projects/",
|
||||
"serverless": Object {
|
||||
"orchestratorTarget": undefined,
|
||||
"projectId": undefined,
|
||||
"projectName": undefined,
|
||||
"projectType": undefined,
|
||||
|
|
|
@ -38,10 +38,12 @@ describe('createCloudUsageCollector', () => {
|
|||
expect(await collector.fetch(collectorFetchContext)).toStrictEqual({
|
||||
isCloudEnabled: true,
|
||||
isElasticStaffOwned: undefined,
|
||||
organizationId: undefined,
|
||||
trialEndDate: undefined,
|
||||
deploymentId: undefined,
|
||||
projectId: undefined,
|
||||
projectType: undefined,
|
||||
orchestratorTarget: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -54,11 +56,13 @@ describe('createCloudUsageCollector', () => {
|
|||
expect(await collector.fetch(collectorFetchContext)).toStrictEqual({
|
||||
isCloudEnabled: true,
|
||||
isElasticStaffOwned: undefined,
|
||||
organizationId: undefined,
|
||||
trialEndDate: '2020-10-01T14:30:16Z',
|
||||
inTrial: false,
|
||||
deploymentId: undefined,
|
||||
projectId: undefined,
|
||||
projectType: undefined,
|
||||
orchestratorTarget: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -67,9 +71,11 @@ describe('createCloudUsageCollector', () => {
|
|||
isCloudEnabled: true,
|
||||
trialEndDate: '2020-10-01T14:30:16Z',
|
||||
isElasticStaffOwned: true,
|
||||
organizationId: '1234',
|
||||
deploymentId: 'a-deployment-id',
|
||||
projectId: 'a-project-id',
|
||||
projectType: 'security',
|
||||
orchestratorTarget: 'canary',
|
||||
});
|
||||
|
||||
expect(await collector.fetch(collectorFetchContext)).toStrictEqual({
|
||||
|
@ -77,9 +83,11 @@ describe('createCloudUsageCollector', () => {
|
|||
trialEndDate: '2020-10-01T14:30:16Z',
|
||||
inTrial: false,
|
||||
isElasticStaffOwned: true,
|
||||
organizationId: '1234',
|
||||
deploymentId: 'a-deployment-id',
|
||||
projectId: 'a-project-id',
|
||||
projectType: 'security',
|
||||
orchestratorTarget: 'canary',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,9 +12,11 @@ export interface CloudUsageCollectorConfig {
|
|||
// Using * | undefined instead of ?: to force the calling code to list all the options (even when they can be undefined)
|
||||
trialEndDate: string | undefined;
|
||||
isElasticStaffOwned: boolean | undefined;
|
||||
organizationId: string | undefined;
|
||||
deploymentId: string | undefined;
|
||||
projectId: string | undefined;
|
||||
projectType: string | undefined;
|
||||
orchestratorTarget: string | undefined;
|
||||
}
|
||||
|
||||
interface CloudUsage {
|
||||
|
@ -22,9 +24,11 @@ interface CloudUsage {
|
|||
trialEndDate?: string;
|
||||
inTrial?: boolean;
|
||||
isElasticStaffOwned?: boolean;
|
||||
organizationId?: string;
|
||||
deploymentId?: string;
|
||||
projectId?: string;
|
||||
projectType?: string;
|
||||
orchestratorTarget?: string;
|
||||
}
|
||||
|
||||
export function createCloudUsageCollector(
|
||||
|
@ -35,19 +39,36 @@ export function createCloudUsageCollector(
|
|||
isCloudEnabled,
|
||||
trialEndDate,
|
||||
isElasticStaffOwned,
|
||||
organizationId,
|
||||
deploymentId,
|
||||
projectId,
|
||||
projectType,
|
||||
orchestratorTarget,
|
||||
} = config;
|
||||
const trialEndDateMs = trialEndDate ? new Date(trialEndDate).getTime() : undefined;
|
||||
return usageCollection.makeUsageCollector<CloudUsage>({
|
||||
type: 'cloud',
|
||||
isReady: () => true,
|
||||
schema: {
|
||||
isCloudEnabled: { type: 'boolean' },
|
||||
trialEndDate: { type: 'date' },
|
||||
inTrial: { type: 'boolean' },
|
||||
isElasticStaffOwned: { type: 'boolean' },
|
||||
isCloudEnabled: {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Is the deployment running in Elastic Cloud (ESS or Serverless)?' },
|
||||
},
|
||||
trialEndDate: { type: 'date', _meta: { description: 'End of the trial period' } },
|
||||
inTrial: {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Is the organization during the trial period?' },
|
||||
},
|
||||
isElasticStaffOwned: {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Is the deploymend owned by an Elastician' },
|
||||
},
|
||||
organizationId: {
|
||||
type: 'keyword',
|
||||
_meta: {
|
||||
description: 'The Elastic Cloud Organization ID that owns the deployment/project',
|
||||
},
|
||||
},
|
||||
deploymentId: {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'The ESS Deployment ID' },
|
||||
|
@ -60,16 +81,22 @@ export function createCloudUsageCollector(
|
|||
type: 'keyword',
|
||||
_meta: { description: 'The Serverless Project type' },
|
||||
},
|
||||
orchestratorTarget: {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'The Orchestrator Target where it is deployed (canary/non-canary)' },
|
||||
},
|
||||
},
|
||||
fetch: () => {
|
||||
return {
|
||||
isCloudEnabled,
|
||||
isElasticStaffOwned,
|
||||
organizationId,
|
||||
trialEndDate,
|
||||
...(trialEndDateMs ? { inTrial: Date.now() <= trialEndDateMs } : {}),
|
||||
deploymentId,
|
||||
projectId,
|
||||
projectType,
|
||||
orchestratorTarget,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@ const configSchema = schema.object({
|
|||
deployments_url: schema.string({ defaultValue: '/deployments' }),
|
||||
deployment_url: schema.maybe(schema.string()),
|
||||
id: schema.maybe(schema.string()),
|
||||
organization_id: schema.maybe(schema.string()),
|
||||
billing_url: schema.maybe(schema.string()),
|
||||
performance_url: schema.maybe(schema.string()),
|
||||
users_and_roles_url: schema.maybe(schema.string()),
|
||||
|
@ -44,6 +45,7 @@ const configSchema = schema.object({
|
|||
project_id: schema.maybe(schema.string()),
|
||||
project_name: schema.maybe(schema.string()),
|
||||
project_type: schema.maybe(schema.string()),
|
||||
orchestrator_target: schema.maybe(schema.string()),
|
||||
},
|
||||
// avoid future chicken-and-egg situation with the component populating the config
|
||||
{ unknowns: 'ignore' }
|
||||
|
@ -60,6 +62,7 @@ export const config: PluginConfigDescriptor<CloudConfigType> = {
|
|||
deployments_url: true,
|
||||
deployment_url: true,
|
||||
id: true,
|
||||
organization_id: true,
|
||||
billing_url: true,
|
||||
users_and_roles_url: true,
|
||||
performance_url: true,
|
||||
|
@ -72,6 +75,7 @@ export const config: PluginConfigDescriptor<CloudConfigType> = {
|
|||
project_id: true,
|
||||
project_name: true,
|
||||
project_type: true,
|
||||
orchestrator_target: true,
|
||||
},
|
||||
onboarding: {
|
||||
default_solution: true,
|
||||
|
|
|
@ -35,6 +35,10 @@ export interface CloudSetup {
|
|||
* @note The `cloudId` is a concatenation of the deployment name and a hash. Users can update the deployment name, changing the `cloudId`. However, the changed `cloudId` will not be re-injected into `kibana.yml`. If you need the current `cloudId` the best approach is to split the injected `cloudId` on the semi-colon, and replace the first element with the `persistent.cluster.metadata.display_name` value as provided by a call to `GET _cluster/settings`.
|
||||
*/
|
||||
cloudId?: string;
|
||||
/**
|
||||
* The Elastic Cloud Organization that owns this deployment/project.
|
||||
*/
|
||||
organizationId?: string;
|
||||
/**
|
||||
* The deployment's ID. Only available when running on Elastic Cloud.
|
||||
*/
|
||||
|
@ -127,6 +131,11 @@ export interface CloudSetup {
|
|||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
projectType?: string;
|
||||
/**
|
||||
* The serverless orchestrator target. The potential values are `canary` or `non-canary`
|
||||
* Will always be present if `isServerlessEnabled` is `true`
|
||||
*/
|
||||
orchestratorTarget?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -163,19 +172,23 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
|
||||
public setup(core: CoreSetup, { usageCollection }: PluginsSetup): CloudSetup {
|
||||
const isCloudEnabled = getIsCloudEnabled(this.config.id);
|
||||
const organizationId = this.config.organization_id;
|
||||
const projectId = this.config.serverless?.project_id;
|
||||
const projectType = this.config.serverless?.project_type;
|
||||
const orchestratorTarget = this.config.serverless?.orchestrator_target;
|
||||
const isServerlessEnabled = !!projectId;
|
||||
const deploymentId = parseDeploymentIdFromDeploymentUrl(this.config.deployment_url);
|
||||
|
||||
registerCloudDeploymentMetadataAnalyticsContext(core.analytics, this.config);
|
||||
registerCloudUsageCollector(usageCollection, {
|
||||
isCloudEnabled,
|
||||
organizationId,
|
||||
trialEndDate: this.config.trial_end_date,
|
||||
isElasticStaffOwned: this.config.is_elastic_staff_owned,
|
||||
deploymentId,
|
||||
projectId,
|
||||
projectType,
|
||||
orchestratorTarget,
|
||||
});
|
||||
|
||||
let decodedId: DecodedCloudId | undefined;
|
||||
|
@ -186,6 +199,7 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
return {
|
||||
...this.getCloudUrls(),
|
||||
cloudId: this.config.id,
|
||||
organizationId,
|
||||
instanceSizeMb: readInstanceSizeMb(),
|
||||
deploymentId,
|
||||
elasticsearchUrl: decodedId?.elasticsearchUrl,
|
||||
|
@ -207,6 +221,7 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
projectId,
|
||||
projectName: this.config.serverless?.project_name,
|
||||
projectType,
|
||||
orchestratorTarget,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7100,16 +7100,34 @@
|
|||
"cloud": {
|
||||
"properties": {
|
||||
"isCloudEnabled": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Is the deployment running in Elastic Cloud (ESS or Serverless)?"
|
||||
}
|
||||
},
|
||||
"trialEndDate": {
|
||||
"type": "date"
|
||||
"type": "date",
|
||||
"_meta": {
|
||||
"description": "End of the trial period"
|
||||
}
|
||||
},
|
||||
"inTrial": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Is the organization during the trial period?"
|
||||
}
|
||||
},
|
||||
"isElasticStaffOwned": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Is the deploymend owned by an Elastician"
|
||||
}
|
||||
},
|
||||
"organizationId": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "The Elastic Cloud Organization ID that owns the deployment/project"
|
||||
}
|
||||
},
|
||||
"deploymentId": {
|
||||
"type": "keyword",
|
||||
|
@ -7128,6 +7146,12 @@
|
|||
"_meta": {
|
||||
"description": "The Serverless Project type"
|
||||
}
|
||||
},
|
||||
"orchestratorTarget": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
"description": "The Orchestrator Target where it is deployed (canary/non-canary)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue