diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts index 3f408ca16857b..d7f34d7e9e484 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/container_entity.ts @@ -15,8 +15,8 @@ class ContainerEntity extends Serializable { super({ ...fields, 'entity.type': 'container', - 'entity.definitionId': 'builtin_containers_from_ecs_data', - 'entity.identityFields': ['container.id'], + 'entity.definition_id': 'builtin_containers_from_ecs_data', + 'entity.identity_fields': ['container.id'], }); } } @@ -36,7 +36,7 @@ export function containerEntity({ 'source_data_stream.type': dataStreamType, 'agent.name': agentName, 'container.id': containerId, - 'entity.displayName': containerId, + 'entity.display_name': containerId, 'entity.id': entityId, }); } diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts index 3077e8bae6414..c2c0330bb03ca 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/host_entity.ts @@ -15,8 +15,8 @@ class HostEntity extends Serializable { super({ ...fields, 'entity.type': 'host', - 'entity.definitionId': 'builtin_hosts_from_ecs_data', - 'entity.identityFields': ['host.name'], + 'entity.definition_id': 'builtin_hosts_from_ecs_data', + 'entity.identity_fields': ['host.name'], }); } } @@ -36,7 +36,7 @@ export function hostEntity({ 'source_data_stream.type': dataStreamType, 'agent.name': agentName, 'host.name': hostName, - 'entity.displayName': hostName, + 'entity.display_name': hostName, 'entity.id': entityId, }); } diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts index 4242476735a11..8665ef0120e25 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/index.ts @@ -31,15 +31,15 @@ export type EntityFields = Fields & 'source_data_stream.type': string | string[]; 'source_data_stream.dataset': string | string[]; 'event.ingested': string; - sourceIndex: string; - 'entity.lastSeenTimestamp': string; - 'entity.schemaVersion': string; - 'entity.definitionVersion': string; - 'entity.displayName': string; - 'entity.identityFields': string | string[]; + source_index: string; + 'entity.last_seen_timestamp': string; + 'entity.schema_version': string; + 'entity.definition_version': string; + 'entity.display_name': string; + 'entity.identity_fields': string | string[]; 'entity.id': string; 'entity.type': string; - 'entity.definitionId': string; + 'entity.definition_id': string; [key: string]: any; }>; diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts index 092135c4160e6..e711f2dad223f 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/service_entity.ts @@ -15,8 +15,8 @@ class ServiceEntity extends Serializable { super({ ...fields, 'entity.type': 'service', - 'entity.definitionId': 'builtin_services_from_ecs_data', - 'entity.identityFields': ['service.name'], + 'entity.definition_id': 'builtin_services_from_ecs_data', + 'entity.identity_fields': ['service.name'], }); } } @@ -36,7 +36,7 @@ export function serviceEntity({ }) { return new ServiceEntity({ 'service.name': serviceName, - 'entity.displayName': serviceName, + 'entity.display_name': serviceName, 'service.environment': environment, 'source_data_stream.type': dataStreamType, 'agent.name': agentName, diff --git a/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts b/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts index 65bf290eae32f..4c5d17111fca6 100644 --- a/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts +++ b/packages/kbn-apm-synthtrace/src/lib/entities/entities_synthtrace_es_client.ts @@ -62,7 +62,7 @@ function lastSeenTimestampTransform() { const timestamp = document['@timestamp']; if (timestamp) { const isoString = new Date(timestamp).toISOString(); - document['entity.lastSeenTimestamp'] = isoString; + document['entity.last_seen_timestamp'] = isoString; document['event.ingested'] = isoString; delete document['@timestamp']; } diff --git a/packages/kbn-investigation-shared/src/rest_specs/entity.ts b/packages/kbn-investigation-shared/src/rest_specs/entity.ts index 1c29192c2a098..8e571f3e2a4d4 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/entity.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/entity.ts @@ -19,13 +19,12 @@ const metricsSchema = z.object({ const entitySchema = z.object({ id: z.string(), - definitionId: z.string(), - definitionVersion: z.string(), - displayName: z.string(), - firstSeenTimestamp: z.string(), - lastSeenTimestamp: z.string(), - identityFields: z.array(z.string()), - schemaVersion: z.string(), + definition_id: z.string(), + definition_version: z.string(), + display_name: z.string(), + last_seen_timestamp: z.string(), + identity_fields: z.array(z.string()), + schema_version: z.string(), type: z.string(), metrics: metricsSchema, }); diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts index c8ef716371338..000edeadbcf83 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.test.ts @@ -9,19 +9,15 @@ import { entityLatestSchema, entityMetadataSchema } from './entity'; const entity = { entity: { - lastSeenTimestamp: '2024-08-06T17:03:50.722Z', - schemaVersion: 'v1', - definitionVersion: '999.999.999', - displayName: 'message_processor', - identityFields: ['log.logger', 'event.category'], + last_seen_timestamp: '2024-08-06T17:03:50.722Z', + schema_version: 'v1', + definition_version: '999.999.999', + display_name: 'message_processor', + identity_fields: ['log.logger', 'event.category'], id: '6UHVPiduEC2qk6rMjs1Jzg==', - metrics: { - logRate: 100, - errorRate: 0, - }, type: 'service', - firstSeenTimestamp: '2024-08-06T16:50:00.000Z', - definitionId: 'admin-console-services', + metrics: {}, + definition_id: 'admin-console-services', }, }; @@ -47,7 +43,7 @@ const metadata = { ingested: '2024-08-06T17:06:24.444700Z', category: '', }, - sourceIndex: ['kbn-data-forge-fake_stack.message_processor-2024-08-01'], + source_index: ['kbn-data-forge-fake_stack.message_processor-2024-08-01'], log: { logger: 'message_processor', }, diff --git a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts index 3eb87a797ef21..9ab02e0931d9c 100644 --- a/x-pack/packages/kbn-entities-schema/src/schema/entity.ts +++ b/x-pack/packages/kbn-entities-schema/src/schema/entity.ts @@ -11,12 +11,12 @@ import { arrayOfStringsSchema } from './common'; export const entityBaseSchema = z.object({ id: z.string(), type: z.string(), - identityFields: arrayOfStringsSchema, - displayName: z.string(), + identity_fields: arrayOfStringsSchema, + display_name: z.string(), metrics: z.record(z.string(), z.number()), - definitionVersion: z.string(), - schemaVersion: z.string(), - definitionId: z.string(), + definition_version: z.string(), + schema_version: z.string(), + definition_id: z.string(), }); export interface MetadataRecord { @@ -34,15 +34,8 @@ export const entityLatestSchema = z .object({ entity: entityBaseSchema.merge( z.object({ - lastSeenTimestamp: z.string(), + last_seen_timestamp: z.string(), }) ), }) .and(entityMetadataSchema); - -export const entityHistorySchema = z - .object({ - '@timestamp': z.string(), - entity: entityBaseSchema, - }) - .and(entityMetadataSchema); diff --git a/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts b/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts index 5ca3da77d7eba..674e870c898bc 100644 --- a/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts +++ b/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts @@ -59,7 +59,7 @@ export const entityDefinitionRuntimePrivileges = { index: [ { names: [ENTITY_INTERNAL_INDICES_PATTERN], - privileges: ['create_index', 'index', 'create_doc', 'auto_configure', 'read'], + privileges: ['create_index', 'delete_index', 'index', 'create_doc', 'auto_configure', 'read'], }, { names: [...BUILT_IN_ALLOWED_INDICES, ENTITY_INTERNAL_INDICES_PATTERN], diff --git a/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts b/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts index 37c8b0f854dc8..fa40760e542aa 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/built_in/services_from_ecs_data.ts @@ -29,7 +29,7 @@ export const builtInServicesFromEcsEntityDefinition: EntityDefinition = identityFields: ['service.name'], displayNameTemplate: '{{service.name}}', metadata: [ - { source: '_index', destination: 'sourceIndex' }, + { source: '_index', destination: 'source_index' }, { source: 'data_stream.type', destination: 'source_data_stream.type', @@ -38,7 +38,7 @@ export const builtInServicesFromEcsEntityDefinition: EntityDefinition = source: 'data_stream.dataset', destination: 'source_data_stream.dataset', }, - { source: 'agent.name', aggregation: { type: 'terms', limit: 100 } }, + 'agent.name', 'service.environment', 'service.name', 'service.namespace', diff --git a/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts index 0b3900363c0c8..5511e50c36ab8 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts @@ -25,7 +25,7 @@ export async function createAndInstallIngestPipelines( id: latestId, processors: latestProcessors, _meta: { - definitionVersion: definition.version, + definition_version: definition.version, managed: definition.managed, }, }), diff --git a/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts index d40d9975a8820..491cd08e6d48c 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts @@ -14,11 +14,13 @@ export async function deleteIndices( definition: EntityDefinition, logger: Logger ) { + const index = generateLatestIndexName(definition); try { - const index = generateLatestIndexName(definition); await esClient.indices.delete({ index, ignore_unavailable: true }); } catch (e) { - logger.error(`Unable to remove entity definition index [${definition.id}}]`); + logger.error( + `Unable to remove entity definition index ${index} for definition [${definition.id}]` + ); throw e; } } diff --git a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap index 37f600f3a271f..429b5fdce9309 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap +++ b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap @@ -16,25 +16,25 @@ Array [ }, Object { "set": Object { - "field": "entity.definitionId", + "field": "entity.definition_id", "value": "builtin_mock_entity_definition", }, }, Object { "set": Object { - "field": "entity.definitionVersion", + "field": "entity.definition_version", "value": "1.0.0", }, }, Object { "set": Object { - "field": "entity.schemaVersion", + "field": "entity.schema_version", "value": "v1", }, }, Object { "set": Object { - "field": "entity.identityFields", + "field": "entity.identity_fields", "value": Array [ "log.logger", ], @@ -92,7 +92,7 @@ if (ctx.entity?.metadata?.sourceIndex?.data != null) { }, Object { "set": Object { - "field": "entity.displayName", + "field": "entity.display_name", "value": "{{log.logger}}", }, }, @@ -121,25 +121,25 @@ Array [ }, Object { "set": Object { - "field": "entity.definitionId", + "field": "entity.definition_id", "value": "admin-console-services", }, }, Object { "set": Object { - "field": "entity.definitionVersion", + "field": "entity.definition_version", "value": "1.0.0", }, }, Object { "set": Object { - "field": "entity.schemaVersion", + "field": "entity.schema_version", "value": "v1", }, }, Object { "set": Object { - "field": "entity.identityFields", + "field": "entity.identity_fields", "value": Array [ "log.logger", ], @@ -197,7 +197,7 @@ if (ctx.entity?.metadata?.sourceIndex?.data != null) { }, Object { "set": Object { - "field": "entity.displayName", + "field": "entity.display_name", "value": "{{log.logger}}", }, }, diff --git a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts index 787633246dede..335c135448b10 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts @@ -117,25 +117,25 @@ export function generateLatestProcessors(definition: EntityDefinition) { }, { set: { - field: 'entity.definitionId', + field: 'entity.definition_id', value: definition.id, }, }, { set: { - field: 'entity.definitionVersion', + field: 'entity.definition_version', value: definition.version, }, }, { set: { - field: 'entity.schemaVersion', + field: 'entity.schema_version', value: ENTITY_SCHEMA_VERSION_V1, }, }, { set: { - field: 'entity.identityFields', + field: 'entity.identity_fields', value: definition.identityFields.map((identityField) => identityField.field), }, }, @@ -173,7 +173,7 @@ export function generateLatestProcessors(definition: EntityDefinition) { // This must happen AFTER we lift the identity fields into the root of the document { set: { - field: 'entity.displayName', + field: 'entity.display_name', value: definition.displayNameTemplate, }, }, diff --git a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts index e07670c58fd9b..4633885b51387 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts @@ -74,7 +74,7 @@ const assertHasCreatedDefinition = ( id: generateLatestIngestPipelineId(definition), processors: expect.anything(), _meta: { - definitionVersion: definition.version, + definition_version: definition.version, managed: definition.managed, }, }); @@ -112,7 +112,7 @@ const assertHasUpgradedDefinition = ( id: generateLatestIngestPipelineId(definition), processors: expect.anything(), _meta: { - definitionVersion: definition.version, + definition_version: definition.version, managed: definition.managed, }, }); @@ -260,7 +260,7 @@ describe('install_entity_definition', () => { describe('installBuiltInEntityDefinitions', () => { it('should install definition when not found', async () => { const builtInDefinitions = [mockEntityDefinition]; - const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + const clusterClient = elasticsearchClientMock.createScopedClusterClient(); const soClient = savedObjectsClientMock.create(); soClient.find.mockResolvedValue({ saved_objects: [], total: 0, page: 1, per_page: 10 }); soClient.update.mockResolvedValue({ @@ -271,18 +271,19 @@ describe('install_entity_definition', () => { }); await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions: builtInDefinitions, logger: loggerMock.create(), }); - assertHasCreatedDefinition(mockEntityDefinition, soClient, esClient); + assertHasCreatedDefinition(mockEntityDefinition, soClient, clusterClient.asSecondaryAuthUser); }); it('should reinstall when partial state found', async () => { const builtInDefinitions = [mockEntityDefinition]; - const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + const clusterClient = elasticsearchClientMock.createScopedClusterClient(); + const esClient = clusterClient.asInternalUser; // mock partially installed definition esClient.ingest.getPipeline.mockResolvedValue({}); esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 }); @@ -314,14 +315,18 @@ describe('install_entity_definition', () => { }); await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions: builtInDefinitions, logger: loggerMock.create(), }); - assertHasDeletedTransforms(mockEntityDefinition, esClient); - assertHasUpgradedDefinition(mockEntityDefinition, soClient, esClient); + assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser); + assertHasUpgradedDefinition( + mockEntityDefinition, + soClient, + clusterClient.asSecondaryAuthUser + ); }); it('should reinstall when outdated version', async () => { @@ -329,7 +334,8 @@ describe('install_entity_definition', () => { ...mockEntityDefinition, version: semver.inc(mockEntityDefinition.version, 'major') ?? '0.0.0', }; - const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + const clusterClient = elasticsearchClientMock.createScopedClusterClient(); + const esClient = clusterClient.asInternalUser; esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 }); const soClient = savedObjectsClientMock.create(); @@ -359,14 +365,14 @@ describe('install_entity_definition', () => { }); await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions: [updatedDefinition], logger: loggerMock.create(), }); - assertHasDeletedTransforms(mockEntityDefinition, esClient); - assertHasUpgradedDefinition(updatedDefinition, soClient, esClient); + assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser); + assertHasUpgradedDefinition(updatedDefinition, soClient, clusterClient.asSecondaryAuthUser); }); it('should reinstall when stale upgrade', async () => { @@ -374,7 +380,8 @@ describe('install_entity_definition', () => { ...mockEntityDefinition, version: semver.inc(mockEntityDefinition.version, 'major') ?? '0.0.0', }; - const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + const clusterClient = elasticsearchClientMock.createScopedClusterClient(); + const esClient = clusterClient.asInternalUser; esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 }); const soClient = savedObjectsClientMock.create(); @@ -406,18 +413,19 @@ describe('install_entity_definition', () => { }); await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions: [updatedDefinition], logger: loggerMock.create(), }); - assertHasDeletedTransforms(mockEntityDefinition, esClient); - assertHasUpgradedDefinition(updatedDefinition, soClient, esClient); + assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser); + assertHasUpgradedDefinition(updatedDefinition, soClient, clusterClient.asSecondaryAuthUser); }); it('should reinstall when failed installation', async () => { - const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + const clusterClient = elasticsearchClientMock.createScopedClusterClient(); + const esClient = clusterClient.asInternalUser; esClient.transform.getTransformStats.mockResolvedValue({ transforms: [], count: 0 }); const soClient = savedObjectsClientMock.create(); @@ -448,14 +456,18 @@ describe('install_entity_definition', () => { }); await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions: [mockEntityDefinition], logger: loggerMock.create(), }); - assertHasDeletedTransforms(mockEntityDefinition, esClient); - assertHasUpgradedDefinition(mockEntityDefinition, soClient, esClient); + assertHasDeletedTransforms(mockEntityDefinition, clusterClient.asSecondaryAuthUser); + assertHasUpgradedDefinition( + mockEntityDefinition, + soClient, + clusterClient.asSecondaryAuthUser + ); }); }); }); diff --git a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts index b4adedaf10374..bfc37ac52e2c1 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts @@ -6,7 +6,7 @@ */ import semver from 'semver'; -import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; +import { ElasticsearchClient, IScopedClusterClient } from '@kbn/core-elasticsearch-server'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { EntityDefinition, EntityDefinitionUpdate } from '@kbn/entities-schema'; import { Logger } from '@kbn/logging'; @@ -29,6 +29,7 @@ import { mergeEntityDefinitionUpdate } from './helpers/merge_definition_update'; import { EntityDefinitionWithState } from './types'; import { stopLatestTransform, stopTransforms } from './stop_transforms'; import { deleteLatestTransform, deleteTransforms } from './delete_transforms'; +import { deleteIndices } from './delete_index'; export interface InstallDefinitionParams { esClient: ElasticsearchClient; @@ -49,10 +50,7 @@ export async function installEntityDefinition({ validateDefinitionCanCreateValidTransformIds(definition); if (await entityDefinitionExists(soClient, definition.id)) { - throw new EntityIdConflict( - `Entity definition with [${definition.id}] already exists.`, - definition - ); + throw new EntityIdConflict(`Entity definition [${definition.id}] already exists.`, definition); } try { @@ -65,7 +63,7 @@ export async function installEntityDefinition({ return await install({ esClient, soClient, logger, definition: entityDefinition }); } catch (e) { - logger.error(`Failed to install entity definition ${definition.id}: ${e}`); + logger.error(`Failed to install entity definition [${definition.id}]: ${e}`); await stopLatestTransform(esClient, definition, logger); await deleteLatestTransform(esClient, definition, logger); @@ -90,28 +88,32 @@ export async function installEntityDefinition({ } export async function installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, logger, definitions, -}: Omit & { +}: Omit & { + clusterClient: IScopedClusterClient; definitions: EntityDefinition[]; }): Promise { if (definitions.length === 0) return []; - logger.debug(`Starting installation of ${definitions.length} built-in definitions`); + logger.info(`Checking installation of ${definitions.length} built-in definitions`); const installPromises = definitions.map(async (builtInDefinition) => { const installedDefinition = await findEntityDefinitionById({ - esClient, soClient, + esClient: clusterClient.asInternalUser, id: builtInDefinition.id, includeState: true, }); if (!installedDefinition) { + // clean data from previous installation + await deleteIndices(clusterClient.asCurrentUser, builtInDefinition, logger); + return await installEntityDefinition({ definition: builtInDefinition, - esClient, + esClient: clusterClient.asSecondaryAuthUser, soClient, logger, }); @@ -127,15 +129,16 @@ export async function installBuiltInEntityDefinitions({ return installedDefinition; } - logger.debug( + logger.info( `Detected failed or outdated installation of definition [${installedDefinition.id}] v${installedDefinition.version}, installing v${builtInDefinition.version}` ); return await reinstallEntityDefinition({ soClient, - esClient, + clusterClient, logger, definition: installedDefinition, definitionUpdate: builtInDefinition, + deleteData: true, }); }); @@ -150,22 +153,16 @@ async function install({ definition, logger, }: InstallDefinitionParams): Promise { - logger.debug( - () => - `Installing definition ${definition.id} v${definition.version}\n${JSON.stringify( - definition, - null, - 2 - )}` - ); + logger.info(`Installing definition [${definition.id}] v${definition.version}`); + logger.debug(() => JSON.stringify(definition, null, 2)); - logger.debug(`Installing index templates for definition ${definition.id}`); + logger.debug(`Installing index templates for definition [${definition.id}]`); const templates = await createAndInstallTemplates(esClient, definition, logger); - logger.debug(`Installing ingest pipelines for definition ${definition.id}`); + logger.debug(`Installing ingest pipelines for definition [${definition.id}]`); const pipelines = await createAndInstallIngestPipelines(esClient, definition, logger); - logger.debug(`Installing transforms for definition ${definition.id}`); + logger.debug(`Installing transforms for definition [${definition.id}]`); const transforms = await createAndInstallTransforms(esClient, definition, logger); const updatedProps = await updateEntityDefinition(soClient, definition.id, { @@ -177,20 +174,23 @@ async function install({ // stop and delete the current transforms and reinstall all the components export async function reinstallEntityDefinition({ - esClient, + clusterClient, soClient, definition, definitionUpdate, logger, -}: InstallDefinitionParams & { + deleteData = false, +}: Omit & { + clusterClient: IScopedClusterClient; definitionUpdate: EntityDefinitionUpdate; + deleteData?: boolean; }): Promise { try { const updatedDefinition = mergeEntityDefinitionUpdate(definition, definitionUpdate); logger.debug( () => - `Reinstalling definition ${definition.id} from v${definition.version} to v${ + `Reinstalling definition [${definition.id}] from v${definition.version} to v${ definitionUpdate.version }\n${JSON.stringify(updatedDefinition, null, 2)}` ); @@ -201,13 +201,17 @@ export async function reinstallEntityDefinition({ installStartedAt: new Date().toISOString(), }); - logger.debug(`Deleting transforms for definition ${definition.id} v${definition.version}`); - await stopAndDeleteTransforms(esClient, definition, logger); + logger.debug(`Deleting transforms for definition [${definition.id}] v${definition.version}`); + await stopAndDeleteTransforms(clusterClient.asSecondaryAuthUser, definition, logger); + + if (deleteData) { + await deleteIndices(clusterClient.asCurrentUser, definition, logger); + } return await install({ - esClient, soClient, logger, + esClient: clusterClient.asSecondaryAuthUser, definition: updatedDefinition, }); } catch (err) { diff --git a/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap index 94303584c45dc..86978b1b4df95 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap +++ b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap @@ -3,7 +3,7 @@ exports[`generateLatestTransform(definition) should generate a valid latest transform 1`] = ` Object { "_meta": Object { - "definitionVersion": "1.0.0", + "definition_version": "1.0.0", "managed": false, }, "defer_validation": true, @@ -42,7 +42,7 @@ Object { }, }, }, - "entity.lastSeenTimestamp": Object { + "entity.last_seen_timestamp": Object { "max": Object { "field": "@timestamp", }, diff --git a/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts index c273469e3d3e3..c9d8cd9deef9b 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts @@ -69,7 +69,7 @@ const generateTransformPutRequest = ({ return { transform_id: transformId, _meta: { - definitionVersion: definition.version, + definition_version: definition.version, managed: definition.managed, }, defer_validation: true, @@ -113,7 +113,7 @@ const generateTransformPutRequest = ({ aggs: { ...generateLatestMetricAggregations(definition), ...generateLatestMetadataAggregations(definition), - 'entity.lastSeenTimestamp': { + 'entity.last_seen_timestamp': { max: { field: definition.latest.timestampField, }, diff --git a/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts index a4d44cd45ee17..66bc6da96619b 100644 --- a/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts +++ b/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts @@ -35,18 +35,20 @@ export async function upgradeBuiltInEntityDefinitions({ ); } - const { esClient, soClient } = getClientsFromAPIKey({ apiKey, server }); + const { clusterClient, soClient } = getClientsFromAPIKey({ apiKey, server }); logger.debug(`Starting built-in definitions upgrade`); const upgradedDefinitions = await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, definitions, logger, }); await Promise.all( - upgradedDefinitions.map((definition) => startTransforms(esClient, definition, logger)) + upgradedDefinitions.map((definition) => + startTransforms(clusterClient.asSecondaryAuthUser, definition, logger) + ) ); return { success: true, definitions: upgradedDefinitions }; diff --git a/x-pack/plugins/entity_manager/server/lib/entity_client.ts b/x-pack/plugins/entity_manager/server/lib/entity_client.ts index dcb3dfab8f328..67e9f52e32bf5 100644 --- a/x-pack/plugins/entity_manager/server/lib/entity_client.ts +++ b/x-pack/plugins/entity_manager/server/lib/entity_client.ts @@ -40,6 +40,9 @@ export class EntityClient { definition: EntityDefinition; installOnly?: boolean; }) { + this.options.logger.info( + `Creating definition [${definition.id}] v${definition.version} (installOnly=${installOnly})` + ); const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser; const installedDefinition = await installEntityDefinition({ definition, @@ -62,16 +65,15 @@ export class EntityClient { id: string; definitionUpdate: EntityDefinitionUpdate; }) { - const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser; const definition = await findEntityDefinitionById({ id, soClient: this.options.soClient, - esClient: secondaryAuthClient, + esClient: this.options.clusterClient.asInternalUser, includeState: true, }); if (!definition) { - const message = `Unable to find entity definition with [${id}]`; + const message = `Unable to find entity definition [${id}]`; this.options.logger.error(message); throw new EntityDefinitionNotFound(message); } @@ -86,37 +88,46 @@ export class EntityClient { definition as EntityDefinitionWithState ).state.components.transforms.some((transform) => transform.running); + this.options.logger.info( + `Updating definition [${definition.id}] from v${definition.version} to v${definitionUpdate.version}` + ); const updatedDefinition = await reinstallEntityDefinition({ definition, definitionUpdate, soClient: this.options.soClient, - esClient: secondaryAuthClient, + clusterClient: this.options.clusterClient, logger: this.options.logger, }); if (shouldRestartTransforms) { - await startTransforms(secondaryAuthClient, updatedDefinition, this.options.logger); + await startTransforms( + this.options.clusterClient.asSecondaryAuthUser, + updatedDefinition, + this.options.logger + ); } return updatedDefinition; } async deleteEntityDefinition({ id, deleteData = false }: { id: string; deleteData?: boolean }) { - const secondaryAuthClient = this.options.clusterClient.asSecondaryAuthUser; const definition = await findEntityDefinitionById({ id, - esClient: secondaryAuthClient, + esClient: this.options.clusterClient.asInternalUser, soClient: this.options.soClient, }); if (!definition) { - const message = `Unable to find entity definition with [${id}]`; + const message = `Unable to find entity definition [${id}]`; this.options.logger.error(message); throw new EntityDefinitionNotFound(message); } + this.options.logger.info( + `Uninstalling definition [${definition.id}] v${definition.version} (deleteData=${deleteData})` + ); await uninstallEntityDefinition({ definition, - esClient: secondaryAuthClient, + esClient: this.options.clusterClient.asSecondaryAuthUser, soClient: this.options.soClient, logger: this.options.logger, }); @@ -148,7 +159,7 @@ export class EntityClient { builtIn?: boolean; }) { const definitions = await findEntityDefinitions({ - esClient: this.options.clusterClient.asSecondaryAuthUser, + esClient: this.options.clusterClient.asInternalUser, soClient: this.options.soClient, page, perPage, @@ -162,6 +173,7 @@ export class EntityClient { } async startEntityDefinition(definition: EntityDefinition) { + this.options.logger.info(`Starting transforms for definition [${definition.id}]`); return startTransforms( this.options.clusterClient.asSecondaryAuthUser, definition, @@ -170,6 +182,7 @@ export class EntityClient { } async stopEntityDefinition(definition: EntityDefinition) { + this.options.logger.info(`Stopping transforms for definition [${definition.id}]`); return stopTransforms( this.options.clusterClient.asSecondaryAuthUser, definition, diff --git a/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts b/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts index ffa58cd9c0145..704c240e0c424 100644 --- a/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts +++ b/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts @@ -11,7 +11,6 @@ import { IndicesPutIndexTemplateRequest, } from '@elastic/elasticsearch/lib/api/types'; import { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { entitiesHistoryBaseComponentTemplateConfig } from '../templates/components/base_history'; import { entitiesLatestBaseComponentTemplateConfig } from '../templates/components/base_latest'; import { entitiesEntityComponentTemplateConfig } from '../templates/components/entity'; import { entitiesEventComponentTemplateConfig } from '../templates/components/event'; @@ -38,11 +37,6 @@ export const installEntityManagerTemplates = async ({ logger: Logger; }) => { await Promise.all([ - upsertComponent({ - esClient, - logger, - component: entitiesHistoryBaseComponentTemplateConfig, - }), upsertComponent({ esClient, logger, diff --git a/x-pack/plugins/entity_manager/server/lib/utils.ts b/x-pack/plugins/entity_manager/server/lib/utils.ts index aec8ffa940437..dfe14dcf20abd 100644 --- a/x-pack/plugins/entity_manager/server/lib/utils.ts +++ b/x-pack/plugins/entity_manager/server/lib/utils.ts @@ -5,7 +5,7 @@ * 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'; @@ -17,9 +17,9 @@ 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).asSecondaryAuthUser; + const clusterClient = server.core.elasticsearch.client.asScoped(fakeRequest); const soClient = server.core.savedObjects.getScopedClient(fakeRequest); - return { esClient, soClient }; + return { clusterClient, soClient }; }; diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/check.ts b/x-pack/plugins/entity_manager/server/routes/enablement/check.ts index d0e2a572cb6f5..1c67643c5c902 100644 --- a/x-pack/plugins/entity_manager/server/routes/enablement/check.ts +++ b/x-pack/plugins/entity_manager/server/routes/enablement/check.ts @@ -61,13 +61,13 @@ 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 entityDiscoveryState = await Promise.all( builtInDefinitions.map(async (builtInDefinition) => { const definitions = await findEntityDefinitions({ - esClient, soClient, + esClient: clusterClient.asSecondaryAuthUser, id: builtInDefinition.id, includeState: true, }); diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts index f8629fe46497b..01208fe19d7a0 100644 --- a/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts +++ b/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts @@ -67,12 +67,13 @@ export const disableEntityDiscoveryRoute = createEntityManagerServerRoute({ includedHiddenTypes: [EntityDiscoveryApiKeyType.name], }); + logger.info('Disabling managed entity discovery'); await uninstallBuiltInEntityDefinitions({ entityClient, deleteData: params.query.deleteData, }); - server.logger.debug('reading entity discovery API key from saved object'); + logger.debug('reading entity discovery API key from saved object'); const apiKey = await readEntityDiscoveryAPIKey(server); // api key could be deleted outside of the apis, it does not affect the // disablement flow @@ -82,6 +83,7 @@ export const disableEntityDiscoveryRoute = createEntityManagerServerRoute({ ids: [apiKey.id], }); } + logger.info('Managed entity discovery is disabled'); return response.ok({ body: { success: true } }); } catch (err) { diff --git a/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts index 1002c1e716df2..9a851e08b5673 100644 --- a/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts +++ b/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts @@ -93,6 +93,7 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({ }); } + logger.info(`Enabling managed entity discovery (installOnly=${params.query.installOnly})`); const soClient = core.savedObjects.getClient({ includedHiddenTypes: [EntityDiscoveryApiKeyType.name], }); @@ -119,9 +120,9 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({ await saveEntityDiscoveryAPIKey(soClient, apiKey); - const esClient = core.elasticsearch.client.asSecondaryAuthUser; + const clusterClient = core.elasticsearch.client; const installedDefinitions = await installBuiltInEntityDefinitions({ - esClient, + clusterClient, soClient, logger, definitions: builtInDefinitions, @@ -130,10 +131,11 @@ export const enableEntityDiscoveryRoute = createEntityManagerServerRoute({ if (!params.query.installOnly) { await Promise.all( installedDefinitions.map((installedDefinition) => - startTransforms(esClient, installedDefinition, logger) + startTransforms(clusterClient.asSecondaryAuthUser, installedDefinition, logger) ) ); } + logger.info('Managed entity discovery is enabled'); return response.ok({ body: { success: true } }); } catch (err) { diff --git a/x-pack/plugins/entity_manager/server/routes/entities/update.ts b/x-pack/plugins/entity_manager/server/routes/entities/update.ts index 9cf72a9298d42..3b7ea8a03830d 100644 --- a/x-pack/plugins/entity_manager/server/routes/entities/update.ts +++ b/x-pack/plugins/entity_manager/server/routes/entities/update.ts @@ -5,21 +5,13 @@ * 2.0. */ -import { - createEntityDefinitionQuerySchema, - entityDefinitionUpdateSchema, -} from '@kbn/entities-schema'; +import { entityDefinitionUpdateSchema } from '@kbn/entities-schema'; import { z } from '@kbn/zod'; import { EntitySecurityException } from '../../lib/entities/errors/entity_security_exception'; import { InvalidTransformError } from '../../lib/entities/errors/invalid_transform_error'; -import { findEntityDefinitionById } from '../../lib/entities/find_entity_definition'; -import { startTransforms } from '../../lib/entities/start_transforms'; -import { - installationInProgress, - reinstallEntityDefinition, -} from '../../lib/entities/install_entity_definition'; - import { createEntityManagerServerRoute } from '../create_entity_manager_server_route'; +import { EntityDefinitionNotFound } from '../../lib/entities/errors/entity_not_found'; +import { EntityDefinitionUpdateConflict } from '../../lib/entities/errors/entity_definition_update_conflict'; /** * @openapi @@ -29,13 +21,12 @@ import { createEntityManagerServerRoute } from '../create_entity_manager_server_ * tags: * - definitions * parameters: - * - in: query - * name: installOnly - * description: If true, the definition transforms will not be started - * required: false + * - in: path + * name: id + * description: The entity definition ID * schema: - * type: boolean - * default: false + * type: string + * required: true * requestBody: * description: The definition properties to update * required: true @@ -63,58 +54,37 @@ export const updateEntityDefinitionRoute = createEntityManagerServerRoute({ endpoint: 'PATCH /internal/entities/definition/{id}', params: z.object({ path: z.object({ id: z.string() }), - query: createEntityDefinitionQuerySchema, body: entityDefinitionUpdateSchema, }), - handler: async ({ context, response, params, logger }) => { - const core = await context.core; - const soClient = core.savedObjects.client; - const esClient = core.elasticsearch.client.asCurrentUser; + handler: async ({ request, response, params, logger, getScopedClient }) => { + const entityClient = await getScopedClient({ request }); try { - const installedDefinition = await findEntityDefinitionById({ - soClient, - esClient, + const updatedDefinition = await entityClient.updateEntityDefinition({ id: params.path.id, + definitionUpdate: params.body, }); - if (!installedDefinition) { + return response.ok({ body: updatedDefinition }); + } catch (e) { + logger.error(e); + + if (e instanceof EntityDefinitionNotFound) { return response.notFound({ body: { message: `Entity definition [${params.path.id}] not found` }, }); } - if (installedDefinition.managed) { - return response.forbidden({ - body: { message: `Managed definition cannot be modified` }, - }); - } - - if (installationInProgress(installedDefinition)) { + if (e instanceof EntityDefinitionUpdateConflict) { return response.conflict({ body: { message: `Entity definition [${params.path.id}] has changes in progress` }, }); } - const updatedDefinition = await reinstallEntityDefinition({ - soClient, - esClient, - logger, - definition: installedDefinition, - definitionUpdate: params.body, - }); - - if (!params.query.installOnly) { - await startTransforms(esClient, updatedDefinition, logger); - } - - return response.ok({ body: updatedDefinition }); - } catch (e) { - logger.error(e); - if (e instanceof EntitySecurityException || e instanceof InvalidTransformError) { return response.customError({ body: e, statusCode: 400 }); } + return response.customError({ body: e, statusCode: 500 }); } }, diff --git a/x-pack/plugins/entity_manager/server/templates/components/base_history.ts b/x-pack/plugins/entity_manager/server/templates/components/base_history.ts deleted file mode 100644 index d0bdaa76152ec..0000000000000 --- a/x-pack/plugins/entity_manager/server/templates/components/base_history.ts +++ /dev/null @@ -1,36 +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 { ClusterPutComponentTemplateRequest } from '@elastic/elasticsearch/lib/api/types'; -import { ENTITY_HISTORY_BASE_COMPONENT_TEMPLATE_V1 } from '../../../common/constants_entities'; - -export const entitiesHistoryBaseComponentTemplateConfig: ClusterPutComponentTemplateRequest = { - name: ENTITY_HISTORY_BASE_COMPONENT_TEMPLATE_V1, - _meta: { - description: - "Component template for the ECS fields used in the Elastic Entity Model's entity discovery framework's history data set", - documentation: 'https://www.elastic.co/guide/en/ecs/current/ecs-base.html', - ecs_version: '8.0.0', - managed: true, - }, - template: { - mappings: { - properties: { - '@timestamp': { - type: 'date', - }, - labels: { - type: 'object', - }, - tags: { - ignore_above: 1024, - type: 'keyword', - }, - }, - }, - }, -}; diff --git a/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts b/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts index 6ee48b37bff1d..ef97a6fda3a3b 100644 --- a/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts +++ b/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts @@ -22,7 +22,7 @@ export const entitiesLatestBaseComponentTemplateConfig: ClusterPutComponentTempl properties: { entity: { properties: { - displayName: { + display_name: { type: 'text', fields: { keyword: { @@ -31,9 +31,6 @@ export const entitiesLatestBaseComponentTemplateConfig: ClusterPutComponentTempl }, }, }, - firstSeenTimestamp: { - type: 'date', - }, }, }, labels: { diff --git a/x-pack/plugins/entity_manager/server/templates/components/entity.ts b/x-pack/plugins/entity_manager/server/templates/components/entity.ts index db93d0db77abf..fbd57ba66fc97 100644 --- a/x-pack/plugins/entity_manager/server/templates/components/entity.ts +++ b/x-pack/plugins/entity_manager/server/templates/components/entity.ts @@ -29,22 +29,22 @@ export const entitiesEntityComponentTemplateConfig: ClusterPutComponentTemplateR ignore_above: 1024, type: 'keyword', }, - definitionId: { + definition_id: { ignore_above: 1024, type: 'keyword', }, - definitionVersion: { + definition_version: { ignore_above: 1024, type: 'keyword', }, - schemaVersion: { + schema_version: { ignore_above: 1024, type: 'keyword', }, - lastSeenTimestamp: { + last_seen_timestamp: { type: 'date', }, - identityFields: { + identity_fields: { type: 'keyword', }, }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts index 5713c0a2b67fb..833e565ec00ef 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/types.ts @@ -26,7 +26,6 @@ export interface EntityLatestServiceRaw { interface Entity { id: string; - lastSeenTimestamp: string; - firstSeenTimestamp: string; - identityFields: string[]; + last_seen_timestamp: string; + identity_fields: string[]; } diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts index bb5c4f48b4125..e3dd0ef5e0d4e 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.test.ts @@ -20,9 +20,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['metrics', 'logs'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:test', }, }, @@ -49,9 +48,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['foo'] }, entity: { - firstSeenTimestamp: '2024-03-05T10:34:40.810Z', - lastSeenTimestamp: '2024-03-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-03-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:env-service-1', }, }, @@ -63,9 +61,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['bar'] }, entity: { - firstSeenTimestamp: '2024-03-05T10:34:40.810Z', - lastSeenTimestamp: '2024-03-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-03-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'apm-only-1:synthtrace-env-2', }, }, @@ -77,9 +74,8 @@ describe('mergeEntities', () => { agent: { name: ['java'] }, source_data_stream: { type: ['baz'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-2:env-service-3', }, }, @@ -91,9 +87,8 @@ describe('mergeEntities', () => { agent: { name: ['java'] }, source_data_stream: { type: ['baz'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-2:env-service-3', }, }, @@ -127,9 +122,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['metrics', 'logs'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:test', }, }, @@ -141,9 +135,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['metrics', 'logs'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:test', }, }, @@ -155,9 +148,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['foo'] }, entity: { - firstSeenTimestamp: '2024-23-05T10:34:40.810Z', - lastSeenTimestamp: '2024-23-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-23-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:prod', }, }, @@ -183,9 +175,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -209,9 +200,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -222,9 +212,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -250,9 +239,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -276,9 +264,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -289,9 +276,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: [] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name'], id: 'service-1:test', }, }, @@ -318,9 +304,8 @@ describe('mergeEntities', () => { agent: { name: ['nodejs'] }, source_data_stream: { type: ['metrics'] }, entity: { - firstSeenTimestamp: '2024-06-05T10:34:40.810Z', - lastSeenTimestamp: '2024-06-05T10:34:40.810Z', - identityFields: ['service.name', 'service.environment'], + last_seen_timestamp: '2024-06-05T10:34:40.810Z', + identity_fields: ['service.name', 'service.environment'], id: 'service-1:test', }, }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts index e2ccc270b2a86..2f33c4728bd1a 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/utils/merge_entities.ts @@ -40,7 +40,7 @@ function mergeFunc(entity: EntityLatestServiceRaw, existingEntity?: MergedServic const commonEntityFields = { serviceName: entity.service.name, agentName: entity.agent.name[0], - lastSeenTimestamp: entity.entity.lastSeenTimestamp, + lastSeenTimestamp: entity.entity.last_seen_timestamp, }; if (!existingEntity) { diff --git a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts index c4b48410456f8..b8d6219e6cd46 100644 --- a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts +++ b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts @@ -26,7 +26,7 @@ describe('parseIdentityFieldValuesToKql', () => { it('should return the value when identityFields is a single string', () => { const entity: ServiceEntity = { 'agent.name': 'node', - 'entity.identityFields': 'service.name', + 'entity.identity_fields': 'service.name', 'service.name': 'my-service', 'entity.type': 'service', ...commonEntityFields, @@ -39,7 +39,7 @@ describe('parseIdentityFieldValuesToKql', () => { it('should return values when identityFields is an array of strings', () => { const entity: ServiceEntity = { 'agent.name': 'node', - 'entity.identityFields': ['service.name', 'service.environment'], + 'entity.identity_fields': ['service.name', 'service.environment'], 'service.name': 'my-service', 'entity.type': 'service', 'service.environment': 'staging', @@ -53,7 +53,7 @@ describe('parseIdentityFieldValuesToKql', () => { it('should return an empty string if identityFields is empty string', () => { const entity: ServiceEntity = { 'agent.name': 'node', - 'entity.identityFields': '', + 'entity.identity_fields': '', 'service.name': 'my-service', 'entity.type': 'service', ...commonEntityFields, @@ -65,7 +65,7 @@ describe('parseIdentityFieldValuesToKql', () => { it('should return an empty array if identityFields is empty array', () => { const entity: ServiceEntity = { 'agent.name': 'node', - 'entity.identityFields': [], + 'entity.identity_fields': [], 'service.name': 'my-service', 'entity.type': 'service', ...commonEntityFields, @@ -77,7 +77,7 @@ describe('parseIdentityFieldValuesToKql', () => { it('should ignore fields that are not present in the entity', () => { const entity: HostEntity = { - 'entity.identityFields': ['host.name', 'foo.bar'], + 'entity.identity_fields': ['host.name', 'foo.bar'], 'host.name': 'my-host', 'entity.type': 'host', 'cloud.provider': null, diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx index c60490c8a12b1..fc73e490d4d05 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx @@ -28,13 +28,13 @@ describe('AlertsBadge', () => { it('render alerts badge for a host entity', () => { const entity: HostEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'host', - 'entity.displayName': 'foo', - 'entity.identityFields': 'host.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'host.name', 'host.name': 'foo', - 'entity.definitionId': 'host', + 'entity.definition_id': 'host', 'cloud.provider': null, alertsCount: 1, }; @@ -46,14 +46,14 @@ describe('AlertsBadge', () => { }); it('render alerts badge for a service entity', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'agent.name': 'node', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': 'service.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'service.name', 'service.name': 'bar', - 'entity.definitionId': 'host', + 'entity.definition_id': 'host', 'cloud.provider': null, alertsCount: 5, }; @@ -65,15 +65,15 @@ describe('AlertsBadge', () => { }); it('render alerts badge for a service entity with multiple identity fields', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'agent.name': 'node', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': ['service.name', 'service.environment'], + 'entity.display_name': 'foo', + 'entity.identity_fields': ['service.name', 'service.environment'], 'service.name': 'bar', 'service.environment': 'prod', - 'entity.definitionId': 'host', + 'entity.definition_id': 'host', 'cloud.provider': null, alertsCount: 2, }; diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx index 36aad3d8e3a97..865e185eaa945 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx @@ -41,13 +41,13 @@ describe('EntityName', () => { it('returns host link', () => { const entity: HostEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'host', - 'entity.displayName': 'foo', - 'entity.identityFields': 'host.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'host.name', 'host.name': 'foo', - 'entity.definitionId': 'host', + 'entity.definition_id': 'host', 'cloud.provider': null, }; render(); @@ -59,13 +59,13 @@ describe('EntityName', () => { it('returns container link', () => { const entity: ContainerEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'container', - 'entity.displayName': 'foo', - 'entity.identityFields': 'container.id', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'container.id', 'container.id': 'foo', - 'entity.definitionId': 'container', + 'entity.definition_id': 'container', 'cloud.provider': null, }; render(); @@ -77,13 +77,13 @@ describe('EntityName', () => { it('returns service link without environment', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': 'service.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'service.name', 'service.name': 'foo', - 'entity.definitionId': 'service', + 'entity.definition_id': 'service', 'agent.name': 'bar', }; render(); @@ -95,13 +95,13 @@ describe('EntityName', () => { it('returns service link with environment', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': 'service.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'service.name', 'service.name': 'foo', - 'entity.definitionId': 'service', + 'entity.definition_id': 'service', 'agent.name': 'bar', 'service.environment': 'baz', }; @@ -114,13 +114,13 @@ describe('EntityName', () => { it('returns service link with first environment when it is an array', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': 'service.name', + 'entity.display_name': 'foo', + 'entity.identity_fields': 'service.name', 'service.name': 'foo', - 'entity.definitionId': 'service', + 'entity.definition_id': 'service', 'agent.name': 'bar', 'service.environment': ['baz', 'bar', 'foo'], }; @@ -133,13 +133,13 @@ describe('EntityName', () => { it('returns service link identity fields is an array', () => { const entity: ServiceEntity = { - 'entity.lastSeenTimestamp': 'foo', + 'entity.last_seen_timestamp': 'foo', 'entity.id': '1', 'entity.type': 'service', - 'entity.displayName': 'foo', - 'entity.identityFields': ['service.name', 'service.environment'], + 'entity.display_name': 'foo', + 'entity.identity_fields': ['service.name', 'service.environment'], 'service.name': 'foo', - 'entity.definitionId': 'service', + 'entity.definition_id': 'service', 'agent.name': 'bar', 'service.environment': 'baz', }; diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts index 90bf2967b894d..0e6c663a00890 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts @@ -29,14 +29,14 @@ describe('getIdentityFields', () => { it('should return a Map with unique entity types and their respective identity fields', () => { const serviceEntity: ServiceEntity = { 'agent.name': 'node', - 'entity.identityFields': ['service.name', 'service.environment'], + 'entity.identity_fields': ['service.name', 'service.environment'], 'service.name': 'my-service', 'entity.type': 'service', ...commonEntityFields, }; const hostEntity: HostEntity = { - 'entity.identityFields': ['host.name'], + 'entity.identity_fields': ['host.name'], 'host.name': 'my-host', 'entity.type': 'host', 'cloud.provider': null, @@ -44,7 +44,7 @@ describe('getIdentityFields', () => { }; const containerEntity: ContainerEntity = { - 'entity.identityFields': 'container.id', + 'entity.identity_fields': 'container.id', 'host.name': 'my-host', 'entity.type': 'container', 'cloud.provider': null, diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx index 2dc76d49c282f..f63cbb9c01618 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/assistant_hypothesis/assistant_hypothesis.tsx @@ -114,7 +114,7 @@ const formatEntityMetrics = (entity: EntityWithSource): string => { .join(', '); const entitySources = entity.sources.map((source) => source.dataStream).join(', '); return dedent(` - Entity name: ${entity.displayName}; + Entity name: ${entity.display_name}; Entity type: ${entity.type}; Entity metrics: ${entityMetrics}; Entity data streams: ${entitySources} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts index 00151f2029d21..0aa5d674702e3 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_entities.ts @@ -22,7 +22,7 @@ import { } from '../clients/create_entities_es_client'; // the official types do not explicitly define sourceIndex in the schema, but it is present in the data at the time of writing this -type EntitiesLatest = z.infer & { sourceIndex: string[] }; +type EntitiesLatest = z.infer & { source_index: string[] }; export async function getEntitiesWithSource({ serviceEnvironment, @@ -51,21 +51,21 @@ export async function getEntitiesWithSource({ for (const response of entityResponses) { const processedEntities = await Promise.all( response.map(async (entity: EntitiesLatest) => { - const sourceIndex = entity?.sourceIndex; + const sourceIndex = entity?.source_index; if (!sourceIndex || !sourceIndex.length) return null; const indices = await esClient.indices.get({ index: sourceIndex }); const sources = await fetchSources(indices); return { - identityFields: entity?.entity.identityFields, + identity_fields: entity?.entity.identity_fields, id: entity?.entity.id, - definitionId: entity?.entity.definitionId, - lastSeenTimestamp: entity?.entity.lastSeenTimestamp, - displayName: entity?.entity.displayName, + definition_id: entity?.entity.definition_id, + last_seen_timestamp: entity?.entity.last_seen_timestamp, + display_name: entity?.entity.display_name, metrics: entity?.entity.metrics, - schemaVersion: entity?.entity.schemaVersion, - definitionVersion: entity?.entity.definitionVersion, + schema_version: entity?.entity.schema_version, + definition_version: entity?.entity.definition_version, type: entity?.entity.type, sources, }; @@ -104,7 +104,7 @@ const getFetchEntitiesPromises = ({ hostName?: string; containerId?: string; serviceEnvironment?: string; -}): Array>> => { +}): Array>> => { const shouldFilterForServiceEnvironment = serviceEnvironment && serviceName && @@ -139,7 +139,7 @@ const getFetchEntitiesPromises = ({ return [containersPromise, hostsPromise, servicesPromise].filter( (promise) => promise !== null - ) as Array>>; + ) as Array>>; }; const getFetchEntityPromise = ({ @@ -152,10 +152,10 @@ const getFetchEntityPromise = ({ shouldFetch: boolean; shouldMatch: QueryDslQueryContainer[]; entitiesEsClient: EntitiesESClient; -}): Promise> | null => { +}): Promise> | null => { return shouldFetch ? entitiesEsClient - .search<{ sourceIndex: string[]; entity: EntitiesLatest['entity'] }>(index, { + .search<{ source_index: string[]; entity: EntitiesLatest['entity'] }>(index, { body: { query: { bool: { @@ -167,7 +167,7 @@ const getFetchEntityPromise = ({ }) .then((response) => { return response.hits.hits.map((hit) => { - return { sourceIndex: hit?._source.sourceIndex, entity: hit._source.entity }; + return { source_index: hit?._source.source_index, entity: hit._source.entity }; }); }) : null; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts b/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts index 5652671a87281..e703cd487259c 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/field_names/elasticsearch.ts @@ -149,9 +149,9 @@ export const PROFILE_INUSE_SPACE = 'profile.inuse_space.bytes'; export const ENTITY = 'entity'; export const ENTITY_ID = 'entity.id'; export const ENTITY_TYPE = 'entity.type'; -export const ENTITY_LAST_SEEN = 'entity.lastSeenTimestamp'; -export const ENTITY_FIRST_SEEN = 'entity.firstSeenTimestamp'; -export const ENTITY_DISPLAY_NAME = 'entity.displayName'; -export const ENTITY_DEFINITION_ID = 'entity.definitionId'; -export const ENTITY_IDENTITY_FIELDS = 'entity.identityFields'; +export const ENTITY_LAST_SEEN = 'entity.last_seen_timestamp'; +export const ENTITY_FIRST_SEEN = 'entity.first_seen_timestamp'; +export const ENTITY_DISPLAY_NAME = 'entity.display_name'; +export const ENTITY_DEFINITION_ID = 'entity.definition_id'; +export const ENTITY_IDENTITY_FIELDS = 'entity.identity_fields'; export const SOURCE_DATA_STREAM_TYPE = 'source_data_stream.type'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/entities_list.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/entities_list.tsx index 1b7c77ceda123..67276e53795ca 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/entities_list.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/entities_list.tsx @@ -34,7 +34,7 @@ export const EntitiesList: React.FC = () => { const [limit, setLimit] = useState(10); const { toggleStatus } = useQueryToggle(ENTITIES_LIST_TABLE_ID); const [sorting, setSorting] = useState({ - field: 'entity.lastSeenTimestamp', + field: 'entity.last_seen_timestamp', direction: Direction.desc, }); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts index 58e78b5983fa0..c2a5bff51f830 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_pipeline.ts @@ -67,7 +67,7 @@ const buildIngestPipeline = ({ { set: { field: '@timestamp', - value: '{{entity.lastSeenTimestamp}}', + value: '{{entity.last_seen_timestamp}}', }, }, { diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts index ad6a459f7ae80..96677a9c8a9b2 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/elasticsearch_assets/ingest_processor_steps/remove_entity_definition_fields_step.ts @@ -15,13 +15,12 @@ export const removeEntityDefinitionFieldsStep = (): IngestProcessorContainer => remove: { ignore_failure: true, field: [ - 'entity.lastSeenTimestamp', - 'entity.schemaVersion', - 'entity.definitionVersion', - 'entity.identityFields', - 'entity.definitionId', - 'entity.displayName', - 'entity.firstSeenTimestamp', + 'entity.last_seen_timestamp', + 'entity.schema_version', + 'entity.definition_version', + 'entity.identity_fields', + 'entity.definition_id', + 'entity.display_name', ], }, }); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/entities/list.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/entities/list.ts index 6aaab39656e7d..c702eaf2ab676 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/entities/list.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/entities/list.ts @@ -53,7 +53,7 @@ export const listEntitiesRoute = (router: EntityAnalyticsRoutesDeps['router'], l const { page = 1, per_page: perPage = 10, - sort_field: sortField = 'entity.lastSeenTimestamp', + sort_field: sortField = 'entity.last_seen_timestamp', sort_order: sortOrder = 'desc', entities_types: entityTypes, filterQuery, diff --git a/x-pack/test/api_integration/apis/entity_manager/definitions.ts b/x-pack/test/api_integration/apis/entity_manager/definitions.ts index 468e53767b4e8..1a68169f6f386 100644 --- a/x-pack/test/api_integration/apis/entity_manager/definitions.ts +++ b/x-pack/test/api_integration/apis/entity_manager/definitions.ts @@ -101,26 +101,6 @@ export default function ({ getService }: FtrProviderContext) { await uninstallDefinition(supertest, { id: mockDefinition.id }); }); - - it('rejects updates to managed definitions', async () => { - await installDefinition(supertest, { - definition: { ...mockDefinition, managed: true }, - installOnly: true, - }); - - await updateDefinition(supertest, { - id: mockDefinition.id, - update: { - version: '1.0.0', - latest: { - timestampField: '@updatedTimestampField', - }, - }, - expectedCode: 403, - }); - - await uninstallDefinition(supertest, { id: mockDefinition.id }); - }); }); describe('entity data', () => { diff --git a/x-pack/test/functional/es_archives/security_solution/entity_store/data.json b/x-pack/test/functional/es_archives/security_solution/entity_store/data.json index a7804bd132d20..529aa6020dce7 100644 --- a/x-pack/test/functional/es_archives/security_solution/entity_store/data.json +++ b/x-pack/test/functional/es_archives/security_solution/entity_store/data.json @@ -17,17 +17,16 @@ "hash": [] }, "entity": { - "lastSeenTimestamp": "2024-09-11T11:24:15.588Z", - "schemaVersion": "v1", - "definitionVersion": "1.0.0", - "displayName": "hinamatsumoto", - "identityFields": [ + "last_seen_timestamp": "2024-09-11T11:24:15.588Z", + "schema_version": "v1", + "definition_version": "1.0.0", + "display_name": "hinamatsumoto", + "identity_fields": [ "user.name" ], "id": "LBQAgKHGmpup0Kg9nlKmeQ==", "type": "node", - "firstSeenTimestamp": "2024-09-11T10:46:00.000Z", - "definitionId": "security_user_default" + "definition_id": "security_user_default" } } } @@ -68,18 +67,17 @@ ] }, "entity": { - "lastSeenTimestamp": "2024-09-11T11:24:15.591Z", - "schemaVersion": "v1", - "definitionVersion": "1.0.0", - "displayName": "ali-ubuntu-server", - "identityFields": [ + "last_seen_timestamp": "2024-09-11T11:24:15.591Z", + "schema_version": "v1", + "definition_version": "1.0.0", + "display_name": "ali-ubuntu-server", + "identity_fields": [ "host.name" ], "id": "ZXKm6GEcUJY6NHkMgPPmGQ==", "type": "node", - "firstSeenTimestamp": "2024-09-11T10:46:00.000Z", - "definitionId": "security_host_default" + "definition_id": "security_host_default" } } } -} \ No newline at end of file +} diff --git a/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json b/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json index bb0df169f6588..641f825896ffd 100644 --- a/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json +++ b/x-pack/test/functional/es_archives/security_solution/entity_store/mappings.json @@ -35,15 +35,15 @@ "properties": { "entity": { "properties": { - "definitionId": { + "definition_id": { "type": "keyword", "ignore_above": 1024 }, - "definitionVersion": { + "definition_version": { "type": "keyword", "ignore_above": 1024 }, - "displayName": { + "display_name": { "type": "text", "fields": { "keyword": { @@ -52,20 +52,17 @@ } } }, - "firstSeenTimestamp": { - "type": "date" - }, "id": { "type": "keyword", "ignore_above": 1024 }, - "identityFields": { + "identity_fields": { "type": "keyword" }, - "lastSeenTimestamp": { + "last_seen_timestamp": { "type": "date" }, - "schemaVersion": { + "schema_version": { "type": "keyword", "ignore_above": 1024 }, @@ -196,15 +193,15 @@ "properties": { "entity": { "properties": { - "definitionId": { + "definition_id": { "type": "keyword", "ignore_above": 1024 }, - "definitionVersion": { + "definition_version": { "type": "keyword", "ignore_above": 1024 }, - "displayName": { + "display_name": { "type": "text", "fields": { "keyword": { @@ -213,20 +210,17 @@ } } }, - "firstSeenTimestamp": { - "type": "date" - }, "id": { "type": "keyword", "ignore_above": 1024 }, - "identityFields": { + "identity_fields": { "type": "keyword" }, - "lastSeenTimestamp": { + "last_seen_timestamp": { "type": "date" }, - "schemaVersion": { + "schema_version": { "type": "keyword", "ignore_above": 1024 }, @@ -300,4 +294,4 @@ } } } -} \ No newline at end of file +}