[eem] disable entity discovery on plugin startup (#204536)

Disable entity discovery on plugin startup and remove some related
files.

We'll need a follow up to cleanup endpoints.

### Testing

- enable entity discovery from `main` with `PUT
kbn:/internal/entities/managed/enablement`, preferably in a cluster with
data so you can verify that the `.entities*` indices are also deleted
- checkout that branch and start kibana
- verify all v1 builtin definitions with their
transforms/templates/pipelines are deleted. `.entities` indices for
these definitions should also be gone

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Kevin Lacabane 2024-12-19 14:35:12 +01:00 committed by GitHub
parent 9562a19ab8
commit 505cc0fbbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 54 additions and 1350 deletions

View file

@ -1,68 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from './constants';
export const builtInContainersFromEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}containers_from_ecs_data`,
managed: true,
version: '0.1.0',
name: 'Containers from ECS data',
description:
'This definition extracts container entities from common data streams by looking for the ECS field container.id',
type: 'container',
indexPatterns: ['filebeat-*', 'logs-*', 'metrics-*', 'metricbeat-*'],
identityFields: ['container.id'],
displayNameTemplate: '{{container.id}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
{
source: '_index',
destination: 'source_index',
},
{
source: 'data_stream.type',
destination: 'source_data_stream.type',
},
{
source: 'data_stream.dataset',
destination: 'source_data_stream.dataset',
},
'container.name',
'container.image.name',
'container.image.tag',
'container.runtime',
'host.name',
'host.ip',
'host.mac',
'host.architecture',
'host.os.family',
'host.os.kernel',
'host.os.name',
'host.os.platform',
'host.os.type',
'host.os.version',
'cloud.provider',
'cloud.region',
'cloud.availability_zone',
'cloud.instance.id',
'cloud.instance.name',
'cloud.machine.type',
'cloud.service.name',
'agent.name',
'agent.type',
'agent.ephemeral_id',
],
});

View file

@ -1,68 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from './constants';
export const builtInHostsFromEcsEntityDefinition: EntityDefinition = entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}hosts_from_ecs_data`,
managed: true,
version: '0.1.0',
name: 'Hosts from ECS data',
description:
'This definition extracts host entities from common data streams by looking for the ECS field host.name',
type: 'host',
indexPatterns: ['filebeat-*', 'logs-*', 'metrics-*', 'metricbeat-*'],
identityFields: ['host.name'],
displayNameTemplate: '{{host.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
{
source: '_index',
destination: 'source_index',
},
{
source: 'data_stream.type',
destination: 'source_data_stream.type',
},
{
source: 'data_stream.dataset',
destination: 'source_data_stream.dataset',
},
'host.hostname',
'host.ip',
'host.mac',
'host.architecture',
'host.containerized',
'host.os.platform',
'host.os.name',
'host.os.type',
'host.os.codename',
'host.os.family',
'host.os.kernel',
'host.os.version',
'cloud.provider',
'cloud.region',
'cloud.availability_zone',
'cloud.instance.id',
'cloud.instance.name',
'cloud.service.name',
'cloud.machine.type',
'cloud.account.id',
'cloud.project.id',
'agent.id',
'agent.name',
'agent.type',
'agent.version',
],
});

View file

@ -6,17 +6,6 @@
*/
import { EntityDefinition } from '@kbn/entities-schema';
import { builtInServicesFromEcsEntityDefinition } from './services_from_ecs_data';
import { builtInHostsFromEcsEntityDefinition } from './hosts_from_ecs_data';
import { builtInContainersFromEcsEntityDefinition } from './containers_from_ecs_data';
import * as kubernetes from './kubernetes';
export { BUILT_IN_ID_PREFIX } from './constants';
export const builtInDefinitions: EntityDefinition[] = [
builtInServicesFromEcsEntityDefinition,
builtInHostsFromEcsEntityDefinition,
builtInContainersFromEcsEntityDefinition,
...Object.values(kubernetes),
];
export const builtInDefinitions: EntityDefinition[] = [];

View file

@ -1,8 +0,0 @@
/*
* 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 const commonEcsIndexPatterns = ['metrics-kubernetes*', 'logs-*'];

View file

@ -1,28 +0,0 @@
/*
* 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 { MetadataField } from '@kbn/entities-schema';
import { globalMetadata } from './global_metadata';
export const commonEcsMetadata: MetadataField[] = [
...globalMetadata,
{
source: 'orchestrator.namespace',
destination: 'orchestrator.namespace',
aggregation: { type: 'terms', limit: 10 },
},
{
source: 'orchestrator.cluster_ip',
destination: 'orchestrator.cluster_id',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
{
source: 'orchestrator.cluster_name',
destination: 'orchestrator.cluster_name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
];

View file

@ -1,26 +0,0 @@
/*
* 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 { MetadataField } from '@kbn/entities-schema';
export const globalMetadata: MetadataField[] = [
{
source: '_index',
destination: 'source_index',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
{
source: 'data_stream.type',
destination: 'source_data_stream.type',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
{
source: 'data_stream.dataset',
destination: 'source_data_stream.dataset',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
];

View file

@ -1,8 +0,0 @@
/*
* 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 const commonOtelIndexPatterns = ['metrics-*otel*', 'logs-*'];

View file

@ -1,23 +0,0 @@
/*
* 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 { MetadataField } from '@kbn/entities-schema';
import { globalMetadata } from './global_metadata';
export const commonOtelMetadata: MetadataField[] = [
...globalMetadata,
{
source: 'k8s.namespace.name',
destination: 'k8s.namespace.name',
aggregation: { type: 'terms', limit: 10 },
},
{
source: 'k8s.cluster.name',
destination: 'k8s.cluster.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
];

View file

@ -1,46 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
import { globalMetadata } from '../common/global_metadata';
export const builtInKubernetesClusterEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_cluster_ecs`,
filter: 'orchestrator.cluster.name: *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Clusters from ECS data',
description:
'This definition extracts Kubernetes cluster entities from the Kubernetes integration data streams',
type: 'k8s.cluster.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['orchestrator.cluster.name'],
displayNameTemplate: '{{orchestrator.cluster.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...globalMetadata,
{
source: 'orchestrator.namespace',
destination: 'orchestrator.namespace',
aggregation: { type: 'terms', limit: 10 },
},
{
source: 'orchestrator.cluster_ip',
destination: 'orchestrator.cluster_id',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
import { commonEcsMetadata } from '../common/ecs_metadata';
export const builtInKubernetesCronJobEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_cron_job_ecs`,
filter: 'kubernetes.cronjob.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes CronJob from ECS data',
description:
'This definition extracts Kubernetes cron job entities from the Kubernetes integration data streams',
type: 'k8s.cronjob.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.cronjob.name'],
displayNameTemplate: '{{kubernetes.cronjob.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
import { commonEcsMetadata } from '../common/ecs_metadata';
export const builtInKubernetesDaemonSetEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_daemon_set_ecs`,
filter: 'kubernetes.daemonset.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes DaemonSet from ECS data',
description:
'This definition extracts Kubernetes daemon set entities from the Kubernetes integration data streams',
type: 'k8s.daemonset.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.daemonset.name'],
displayNameTemplate: '{{kubernetes.daemonset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsMetadata } from '../common/ecs_metadata';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
export const builtInKubernetesDeploymentEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_deployment_ecs`,
filter: 'kubernetes.deployment.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Deployment from ECS data',
description:
'This definition extracts Kubernetes deployment entities from the Kubernetes integration data streams',
type: 'k8s.deployment.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.deployment.name'],
displayNameTemplate: '{{kubernetes.deployment.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,17 +0,0 @@
/*
* 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 { builtInKubernetesClusterEcsEntityDefinition } from './cluster';
export { builtInKubernetesNodeEcsEntityDefinition } from './node';
export { builtInKubernetesPodEcsEntityDefinition } from './pod';
export { builtInKubernetesReplicaSetEcsEntityDefinition } from './replica_set';
export { builtInKubernetesDeploymentEcsEntityDefinition } from './deployment';
export { builtInKubernetesStatefulSetEcsEntityDefinition } from './stateful_set';
export { builtInKubernetesDaemonSetEcsEntityDefinition } from './daemon_set';
export { builtInKubernetesJobEcsEntityDefinition } from './job';
export { builtInKubernetesCronJobEcsEntityDefinition } from './cron_job';
export { builtInKubernetesServiceEcsEntityDefinition } from './service';

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
import { commonEcsMetadata } from '../common/ecs_metadata';
export const builtInKubernetesJobEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_job_ecs`,
filter: 'kubernetes.job.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Job from ECS data',
description:
'This definition extracts Kubernetes job entities from the Kubernetes integration data streams',
type: 'k8s.job.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.job.name'],
displayNameTemplate: '{{kubernetes.job.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
import { commonEcsMetadata } from '../common/ecs_metadata';
export const builtInKubernetesNodeEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_node_ecs`,
filer: 'kubernetes.node.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Node from ECS data',
description:
'This definition extracts Kubernetes node entities from the Kubernetes integration data streams',
type: 'k8s.node.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.node.name'],
displayNameTemplate: '{{kubernetes.node.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsMetadata } from '../common/ecs_metadata';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
export const builtInKubernetesPodEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_pod_ecs`,
filter: 'kubernetes.pod.uid: *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Pod from ECS data',
description:
'This definition extracts Kubernetes pod entities from the Kubernetes integration data streams',
type: 'k8s.pod.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.pod.uid'],
displayNameTemplate: '{{kubernetes.pod.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonEcsMetadata,
{
source: 'kubernetes.pod.name',
destination: 'kubernetes.pod.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsMetadata } from '../common/ecs_metadata';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
export const builtInKubernetesReplicaSetEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_replica_set_ecs`,
filer: 'kubernetes.replicaset.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes ReplicaSet from ECS data',
description:
'This definition extracts Kubernetes replica set entities from the Kubernetes integration data streams',
type: 'k8s.replicaset.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.replicaset.name'],
displayNameTemplate: '{{kubernetes.replicaset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsMetadata } from '../common/ecs_metadata';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
export const builtInKubernetesServiceEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_service_ecs`,
filter: 'kubernetes.service.name: *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Services from ECS data',
description:
'This definition extracts Kubernetes service entities from the Kubernetes integration data streams',
type: 'k8s.service.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.service.name'],
displayNameTemplate: '{{kubernetes.service.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,34 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonEcsMetadata } from '../common/ecs_metadata';
import { commonEcsIndexPatterns } from '../common/ecs_index_patterns';
export const builtInKubernetesStatefulSetEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_stateful_set_ecs`,
filter: 'kubernetes.statefulset.name : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes StatefulSet from ECS data',
description:
'This definition extracts Kubernetes stateful set entities from the Kubernetes integration data streams',
type: 'k8s.statefulset.ecs',
indexPatterns: commonEcsIndexPatterns,
identityFields: ['kubernetes.statefulset.name'],
displayNameTemplate: '{{kubernetes.statefulset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: commonEcsMetadata,
});

View file

@ -1,9 +0,0 @@
/*
* 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 * from './ecs';
export * from './semconv';

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
import { commonOtelMetadata } from '../common/otel_metadata';
export const builtInKubernetesClusterSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_cluster_semconv`,
filter: 'k8s.cluster.uid: *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Clusters from SemConv data',
description:
'This definition extracts Kubernetes cluster entities using data collected with OpenTelemetry',
type: 'kubernetes_cluster_semconv',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.cluster.uid'],
displayNameTemplate: '{{k8s.cluster.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.cluster.name',
destination: 'k8s.cluster.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
import { commonOtelMetadata } from '../common/otel_metadata';
export const builtInKubernetesCronJobSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_cron_job_semconv`,
filter: 'k8s.cronjob.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes CronJob from SemConv data',
description:
'This definition extracts Kubernetes cron job entities using data collected with OpenTelemetry',
type: 'k8s.cronjob.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.cronjob.uid'],
displayNameTemplate: '{{k8s.cronjob.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.cronjob.name',
destination: 'k8s.cronjob.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
import { commonOtelMetadata } from '../common/otel_metadata';
export const builtInKubernetesDaemonSetSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_daemon_set_semconv`,
filter: 'k8s.daemonset.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes DaemonSet from SemConv data',
description:
'This definition extracts Kubernetes daemon set entities using data collected with OpenTelemetry',
type: 'k8s.daemonset.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.daemonset.uid'],
displayNameTemplate: '{{k8s.daemonset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.daemonset.name',
destination: 'k8s.daemonset.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelMetadata } from '../common/otel_metadata';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
export const builtInKubernetesDeploymentSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_deployment_semconv`,
filter: 'k8s.deployment.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Deployment from SemConv data',
description:
'This definition extracts Kubernetes deployment entities using data collected with OpenTelemetry',
type: 'k8s.deployment.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.deployment.uid'],
displayNameTemplate: '{{k8s.deployment.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.deployment.name',
destination: 'k8s.deployment.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,16 +0,0 @@
/*
* 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 { builtInKubernetesClusterSemConvEntityDefinition } from './cluster';
export { builtInKubernetesNodeSemConvEntityDefinition } from './node';
export { builtInKubernetesPodSemConvEntityDefinition } from './pod';
export { builtInKubernetesReplicaSetSemConvEntityDefinition } from './replica_set';
export { builtInKubernetesDeploymentSemConvEntityDefinition } from './deployment';
export { builtInKubernetesStatefulSetSemConvEntityDefinition } from './stateful_set';
export { builtInKubernetesDaemonSetSemConvEntityDefinition } from './daemon_set';
export { builtInKubernetesJobSemConvEntityDefinition } from './job';
export { builtInKubernetesCronJobSemConvEntityDefinition } from './cron_job';

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
import { commonOtelMetadata } from '../common/otel_metadata';
export const builtInKubernetesJobSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_job_semconv`,
filter: 'k8s.job.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Job from SemConv data',
description:
'This definition extracts Kubernetes job entities using data collected with OpenTelemetry',
type: 'k8s.job.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.job.uid'],
displayNameTemplate: '{{k8s.job.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.job.name',
destination: 'k8s.job.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
import { commonOtelMetadata } from '../common/otel_metadata';
export const builtInKubernetesNodeSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_node_semconv`,
filter: 'k8s.node.uid: *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Node from SemConv data',
description:
'This definition extracts Kubernetes node entities using data collected with OpenTelemetry',
type: 'k8s.node.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.node.uid'],
displayNameTemplate: '{{k8s.node.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.node.name',
destination: 'k8s.node.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelMetadata } from '../common/otel_metadata';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
export const builtInKubernetesPodSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_pod_semconv`,
filter: 'k8s.pod.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes Pod from SemConv data',
description:
'This definition extracts Kubernetes pod entities using data collected with OpenTelemetry',
type: 'k8s.pod.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.pod.uid'],
displayNameTemplate: '{{k8s.pod.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.pod.name',
destination: 'k8s.pod.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelMetadata } from '../common/otel_metadata';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
export const builtInKubernetesReplicaSetSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_replica_set_semconv`,
filter: 'k8s.replicaset.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes ReplicaSet from SemConv data',
description:
'This definition extracts Kubernetes replica set entities using data collected with OpenTelemetry',
type: 'k8s.replicaset.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.replicaset.uid'],
displayNameTemplate: '{{k8s.replicaset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.replicaset.name',
destination: 'k8s.replicaset.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,41 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from '../../constants';
import { commonOtelMetadata } from '../common/otel_metadata';
import { commonOtelIndexPatterns } from '../common/otel_index_patterns';
export const builtInKubernetesStatefulSetSemConvEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
id: `${BUILT_IN_ID_PREFIX}kubernetes_stateful_set_semconv`,
filter: 'k8s.statefulset.uid : *',
managed: true,
version: '0.1.0',
name: 'Kubernetes StatefulSet from SemConv data',
description:
'This definition extracts Kubernetes stateful set entities using data collected with OpenTelemetry',
type: 'k8s.statefulset.otel',
indexPatterns: commonOtelIndexPatterns,
identityFields: ['k8s.statefulset.uid'],
displayNameTemplate: '{{k8s.statefulset.name}}',
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '5m',
},
},
metadata: [
...commonOtelMetadata,
{
source: 'k8s.statefulset.name',
destination: 'k8s.statefulset.name',
aggregation: { type: 'top_value', sort: { '@timestamp': 'desc' } },
},
],
});

View file

@ -1,57 +0,0 @@
/*
* 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 { EntityDefinition, entityDefinitionSchema } from '@kbn/entities-schema';
import { BUILT_IN_ID_PREFIX } from './constants';
export const builtInServicesFromEcsEntityDefinition: EntityDefinition =
entityDefinitionSchema.parse({
version: '0.5.0',
id: `${BUILT_IN_ID_PREFIX}services_from_ecs_data`,
name: 'Services from ECS data',
description:
'This definition extracts service entities from common data streams by looking for the ECS field service.name',
type: 'service',
managed: true,
indexPatterns: ['logs-*', 'filebeat*', 'traces-*'],
latest: {
timestampField: '@timestamp',
lookbackPeriod: '10m',
settings: {
frequency: '2m',
syncDelay: '2m',
},
},
identityFields: ['service.name'],
displayNameTemplate: '{{service.name}}',
metadata: [
{ source: '_index', destination: 'source_index' },
{
source: 'data_stream.type',
destination: 'source_data_stream.type',
},
{
source: 'data_stream.dataset',
destination: 'source_data_stream.dataset',
},
'agent.name',
'service.environment',
'service.name',
'service.namespace',
'service.version',
'service.runtime.name',
'service.runtime.version',
'service.language.name',
'cloud.provider',
'cloud.availability_zone',
'cloud.machine.type',
'kubernetes.namespace',
'orchestrator.cluster.name',
'k8s.namespace.name',
'k8s.cluster.name',
],
});

View file

@ -18,6 +18,9 @@ import { stopTransforms } from './stop_transforms';
import { deleteTransforms } from './delete_transforms';
import { EntityClient } from '../entity_client';
import { EntityManagerServerSetup } from '../../types';
import { deleteEntityDiscoveryAPIKey, readEntityDiscoveryAPIKey } from '../auth';
import { getClientsFromAPIKey } from '../utils';
export async function uninstallEntityDefinition({
definition,
@ -52,7 +55,7 @@ export async function uninstallBuiltInEntityDefinitions({
perPage: 1000,
});
await Promise.all(
await Promise.allSettled(
definitions.map(async ({ id }) => {
await entityClient.deleteEntityDefinition({ id, deleteData });
})
@ -60,3 +63,24 @@ export async function uninstallBuiltInEntityDefinitions({
return definitions;
}
export async function disableManagedEntityDiscovery({
server,
}: {
server: EntityManagerServerSetup;
}) {
const apiKey = await readEntityDiscoveryAPIKey(server);
if (!apiKey) {
return;
}
const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const entityClient = new EntityClient({ clusterClient, soClient, logger: server.logger });
await uninstallBuiltInEntityDefinitions({ entityClient, deleteData: true });
await deleteEntityDiscoveryAPIKey(soClient);
await server.security.authc.apiKeys.invalidateAsInternalUser({
ids: [apiKey.id],
});
}

View file

@ -35,7 +35,8 @@ export async function upgradeBuiltInEntityDefinitions({
);
}
const { esClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const esClient = clusterClient.asCurrentUser;
logger.debug(`Starting built-in definitions upgrade`);
const upgradedDefinitions = await installBuiltInEntityDefinitions({

View file

@ -5,11 +5,12 @@
* 2.0.
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { IScopedClusterClient } from '@kbn/core-elasticsearch-server';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { getFakeKibanaRequest } from '@kbn/security-plugin/server/authentication/api_keys/fake_kibana_request';
import { EntityManagerServerSetup } from '../types';
import { EntityDiscoveryAPIKey } from './auth/api_key/api_key';
import { EntityDiscoveryApiKeyType } from '../saved_objects';
export const getClientsFromAPIKey = ({
apiKey,
@ -17,9 +18,11 @@ export const getClientsFromAPIKey = ({
}: {
apiKey: EntityDiscoveryAPIKey;
server: EntityManagerServerSetup;
}): { esClient: ElasticsearchClient; soClient: SavedObjectsClientContract } => {
}): { clusterClient: IScopedClusterClient; soClient: SavedObjectsClientContract } => {
const fakeRequest = getFakeKibanaRequest({ id: apiKey.id, api_key: apiKey.apiKey });
const esClient = server.core.elasticsearch.client.asScoped(fakeRequest).asCurrentUser;
const soClient = server.core.savedObjects.getScopedClient(fakeRequest);
return { esClient, soClient };
const clusterClient = server.core.elasticsearch.client.asScoped(fakeRequest);
const soClient = server.core.savedObjects.getScopedClient(fakeRequest, {
includedHiddenTypes: [EntityDiscoveryApiKeyType.name],
});
return { clusterClient, soClient };
};

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { firstValueFrom } from 'rxjs';
import {
CoreSetup,
CoreStart,
@ -16,13 +17,9 @@ import {
PluginInitializerContext,
} from '@kbn/core/server';
import { registerRoutes } from '@kbn/server-route-repository';
import { firstValueFrom } from 'rxjs';
import { KibanaFeatureScope } from '@kbn/features-plugin/common';
import { EntityManagerConfig, configSchema, exposeToBrowserConfig } from '../common/config';
import { builtInDefinitions } from './lib/entities/built_in';
import { upgradeBuiltInEntityDefinitions } from './lib/entities/upgrade_entity_definition';
import { EntityClient } from './lib/entity_client';
import { installEntityManagerTemplates } from './lib/manage_index_templates';
import { entityManagerRouteRepository } from './routes';
import { EntityManagerRouteDependencies } from './routes/types';
import { EntityDiscoveryApiKeyType, entityDefinition } from './saved_objects';
@ -40,6 +37,8 @@ import {
READ_ENTITIES_PRIVILEGE,
} from './lib/v2/constants';
import { installBuiltInDefinitions } from './lib/v2/definitions/install_built_in_definitions';
import { disableManagedEntityDiscovery } from './lib/entities/uninstall_entity_definition';
import { installEntityManagerTemplates } from './lib/manage_index_templates';
import { instanceAsFilter } from './lib/v2/definitions/instance_as_filter';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@ -174,28 +173,20 @@ export class EntityManagerServerPlugin
installEntityManagerTemplates({
esClient: core.elasticsearch.client.asInternalUser,
logger: this.logger,
})
.then(async () => {
// the api key validation requires a check against the cluster license
// which is lazily loaded. we ensure it gets loaded before the update
await firstValueFrom(plugins.licensing.license$);
const { success } = await upgradeBuiltInEntityDefinitions({
definitions: builtInDefinitions,
server: this.server!,
});
}).catch((err) => this.logger.error(err));
if (success) {
this.logger.info('Builtin definitions were successfully upgraded');
}
})
.catch((err) => this.logger.error(err));
// Disable v1 built-in definitions.
// the api key invalidation requires a check against the cluster license
// which is lazily loaded. we ensure it gets loaded before the update
firstValueFrom(plugins.licensing.license$)
.then(() => disableManagedEntityDiscovery({ server: this.server! }))
.then(() => this.logger.info(`Disabled managed entity discovery`))
.catch((err) => this.logger.error(`Failed to disable managed entity discovery: ${err}`));
// Setup v2 definitions index
setupEntityDefinitionsIndex(core.elasticsearch.client, this.logger)
.then(() => installBuiltInDefinitions(core.elasticsearch.client, this.logger))
.catch((error) => {
this.logger.error(error);
});
.catch((err) => this.logger.error(err));
return {
getScopedClient: async ({ request }: { request: KibanaRequest }) => {

View file

@ -68,7 +68,8 @@ export const checkEntityDiscoveryEnabledRoute = createEntityManagerServerRoute({
return response.ok({ body: { enabled: false, reason: ERROR_API_KEY_NOT_VALID } });
}
const { esClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server });
const esClient = clusterClient.asCurrentUser;
const entityDiscoveryState = await Promise.all(
builtInDefinitions.map(async (builtInDefinition) => {

View file

@ -31,7 +31,6 @@
"@kbn/datemath",
"@kbn/server-route-repository",
"@kbn/zod",
"@kbn/zod-helpers",
"@kbn/encrypted-saved-objects-plugin",
"@kbn/licensing-plugin",
"@kbn/core-saved-objects-server",
@ -39,5 +38,6 @@
"@kbn/apm-utils",
"@kbn/features-plugin",
"@kbn/core-elasticsearch-server-mocks",
"@kbn/zod-helpers",
]
}

View file

@ -1,193 +0,0 @@
/*
* 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 semver from 'semver';
import expect from '@kbn/expect';
import { builtInDefinitions } from '@kbn/entityManager-plugin/server/lib/entities/built_in';
import { ERROR_API_KEY_NOT_FOUND } from '@kbn/entityManager-plugin/public';
import { builtInEntityDefinition as mockBuiltInEntityDefinition } from '@kbn/entityManager-plugin/server/lib/entities/helpers/fixtures';
import { EntityDefinition } from '@kbn/entities-schema';
import { EntityDefinitionWithState } from '@kbn/entityManager-plugin/server/lib/entities/types';
import { FtrProviderContext } from '../../ftr_provider_context';
import { createAdmin, createRuntimeUser } from './helpers/user';
import { Auth, getInstalledDefinitions, upgradeBuiltinDefinitions } from './helpers/request';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
const supertest = getService('supertest');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const enablementRequest =
(method: 'get' | 'put' | 'delete') =>
async (auth: Auth, expectedCode: number, query: { [key: string]: any } = {}) => {
const response = await supertestWithoutAuth[method]('/internal/entities/managed/enablement')
.auth(auth.username, auth.password)
.query(query)
.set('kbn-xsrf', 'xxx')
.send()
.expect(expectedCode);
return response.body;
};
const entityDiscoveryState = enablementRequest('get');
const enableEntityDiscovery = enablementRequest('put');
const disableEntityDiscovery = enablementRequest('delete');
const expectNoInstalledDefinitions = async () => {
const definitionsResponse = await getInstalledDefinitions(supertest);
expect(definitionsResponse.definitions).to.eql([]);
};
const isInstalledAndRunning = (
definition: EntityDefinition,
installedDefinitions: EntityDefinitionWithState[]
) => {
return installedDefinitions.find((installedDefinition) => {
return (
installedDefinition.id === definition.id &&
installedDefinition.version === definition.version &&
installedDefinition.state.installed &&
installedDefinition.state.running
);
});
};
describe('Entity discovery builtin definitions', () => {
let authorizedUser: { username: string; password: string };
let unauthorizedUser: { username: string; password: string };
before(async () => {
[authorizedUser, unauthorizedUser] = await Promise.all([
createAdmin({ esClient }),
createRuntimeUser({ esClient }),
]);
});
describe('enablement/disablement', () => {
describe('with authorized user', () => {
it('should enable and disable entity discovery', async () => {
const enableResponse = await enableEntityDiscovery(authorizedUser, 200);
expect(enableResponse.success).to.eql(true, "authorized user can't enable EEM");
const definitionsResponse = await getInstalledDefinitions(supertestWithoutAuth, {
auth: authorizedUser,
});
expect(definitionsResponse.definitions.length).to.eql(builtInDefinitions.length);
expect(
builtInDefinitions.every((builtin) =>
isInstalledAndRunning(builtin, definitionsResponse.definitions)
)
).to.eql(true, 'all builtin definitions are not installed/running');
let stateResponse = await entityDiscoveryState(authorizedUser, 200);
expect(stateResponse.enabled).to.eql(
true,
`EEM is not enabled; response: ${JSON.stringify(stateResponse)}`
);
const disableResponse = await disableEntityDiscovery(authorizedUser, 200, {
deleteData: true,
});
expect(disableResponse.success).to.eql(
true,
`authorized user failed to disable EEM; response: ${JSON.stringify(disableResponse)}`
);
stateResponse = await entityDiscoveryState(authorizedUser, 200);
expect(stateResponse.enabled).to.eql(false, 'EEM is not disabled');
await expectNoInstalledDefinitions();
});
});
describe('with unauthorized user', () => {
it('should fail to enable entity discovery', async () => {
await enableEntityDiscovery(unauthorizedUser, 403);
const stateResponse = await entityDiscoveryState(unauthorizedUser, 200);
expect(stateResponse.enabled).to.eql(false, 'EEM is enabled');
await expectNoInstalledDefinitions();
});
it('should fail to disable entity discovery', async () => {
const enableResponse = await enableEntityDiscovery(authorizedUser, 200);
expect(enableResponse.success).to.eql(true, "authorized user can't enable EEM");
await disableEntityDiscovery(unauthorizedUser, 403);
const disableResponse = await disableEntityDiscovery(authorizedUser, 200, {
deleteData: true,
});
expect(disableResponse.success).to.eql(true, "authorized user can't disable EEM");
});
});
});
describe('upgrade', () => {
it('should noop when no api key stored', async () => {
const result = await upgradeBuiltinDefinitions(supertest, []);
expect(result).to.eql({ success: false, reason: ERROR_API_KEY_NOT_FOUND });
});
it('should upgrade existing definitions', async () => {
await expectNoInstalledDefinitions();
const enableResponse = await enableEntityDiscovery(authorizedUser, 200);
expect(enableResponse.success).to.eql(true, "authorized user can't enable EEM");
let definitionsResponse = await getInstalledDefinitions(supertest);
expect(definitionsResponse.definitions.length).to.eql(builtInDefinitions.length);
// increment the version of builtin definitions
const updatedBuiltinDefinitions = definitionsResponse.definitions.map((definition) => {
return {
...definition,
version: semver.inc(definition.version, 'minor')!,
};
});
const upgradeResponse = await upgradeBuiltinDefinitions(
supertest,
updatedBuiltinDefinitions
);
expect(upgradeResponse.success).to.eql(true);
// check builtin definitions are running the latest version
definitionsResponse = await getInstalledDefinitions(supertest);
expect(definitionsResponse.definitions.length).to.eql(builtInDefinitions.length);
expect(
updatedBuiltinDefinitions.every((builtin) =>
isInstalledAndRunning(builtin, definitionsResponse.definitions)
)
).to.eql(true, 'all builtin definitions are not installed/running');
await disableEntityDiscovery(authorizedUser, 200, { deleteData: true });
});
});
it('should install new builtin definitions', async () => {
await expectNoInstalledDefinitions();
const enableResponse = await enableEntityDiscovery(authorizedUser, 200);
expect(enableResponse.success).to.eql(true, "authorized user can't enable EEM");
// inject definition to simulate release of new builtin definition
const latestBuiltInDefinitions = [...builtInDefinitions, mockBuiltInEntityDefinition];
const upgradeResponse = await upgradeBuiltinDefinitions(supertest, latestBuiltInDefinitions);
expect(upgradeResponse.success).to.eql(true, 'upgrade was not successful');
const definitionsResponse = await getInstalledDefinitions(supertest);
expect(definitionsResponse.definitions.length).to.eql(latestBuiltInDefinitions.length);
expect(
isInstalledAndRunning(mockBuiltInEntityDefinition, definitionsResponse.definitions)
).to.ok();
await disableEntityDiscovery(authorizedUser, 200, { deleteData: true });
});
});
}

View file

@ -5,21 +5,9 @@
* 2.0.
*/
import { z } from '@kbn/zod';
import {
Plugin,
CoreSetup,
RequestHandlerContext,
KibanaRequest,
KibanaResponseFactory,
Logger,
PluginInitializerContext,
} from '@kbn/core/server';
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
import { upgradeBuiltInEntityDefinitions } from '@kbn/entityManager-plugin/server/lib/entities/upgrade_entity_definition';
import { Plugin, PluginInitializerContext } from '@kbn/core/server';
import { SecurityPluginStart } from '@kbn/security-plugin-types-server';
import { EncryptedSavedObjectsPluginStart } from '@kbn/encrypted-saved-objects-plugin/server';
import { entityDefinitionSchema } from '@kbn/entities-schema';
interface FixtureStartDeps {
encryptedSavedObjects: EncryptedSavedObjectsPluginStart;
@ -27,48 +15,9 @@ interface FixtureStartDeps {
}
export class FixturePlugin implements Plugin<void, void, {}, FixtureStartDeps> {
private logger: Logger;
constructor(context: PluginInitializerContext<{}>) {
this.logger = context.logger.get();
}
public setup(core: CoreSetup<FixtureStartDeps>) {
core.http.createRouter().post(
{
path: '/api/entities/upgrade_builtin_definitions',
validate: {
body: buildRouteValidationWithZod(
z.object({
definitions: z.array(entityDefinitionSchema),
})
),
},
},
async (
context: RequestHandlerContext,
req: KibanaRequest<any, any, any, any>,
res: KibanaResponseFactory
) => {
const [coreStart, { encryptedSavedObjects, security }] = await core.getStartServices();
const result = await upgradeBuiltInEntityDefinitions({
definitions: req.body.definitions,
server: {
encryptedSavedObjects,
security,
core: coreStart,
logger: this.logger,
config: {},
isServerless: false,
},
});
return res.ok({ body: result });
}
);
}
constructor(context: PluginInitializerContext<{}>) {}
public setup() {}
public start() {}
public stop() {}
}

View file

@ -11,11 +11,7 @@
"@kbn/core",
"@kbn/encrypted-saved-objects-plugin",
"@kbn/core-plugins-server",
"@kbn/zod-helpers",
"@kbn/entityManager-plugin",
"@kbn/security-plugin-types-server",
"@kbn/entities-schema",
"@kbn/zod",
],
"exclude": [
"target/**/*",

View file

@ -11,7 +11,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
describe('Entity Manager', function () {
this.tags(['entityManager']);
loadTestFile(require.resolve('./builtin_definitions'));
loadTestFile(require.resolve('./definitions'));
loadTestFile(require.resolve('./count'));
loadTestFile(require.resolve('./search'));