diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts index 36d7f8caf9601..db95dcf4155bc 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts @@ -55,9 +55,9 @@ export class K8sEntity extends Serializable { super({ ...fields, 'entity.type': entityTypeWithSchema, - 'entity.definitionId': `builtin_${entityTypeWithSchema}`, - 'entity.identityFields': identityFields, - 'entity.displayName': getDisplayName({ identityFields, fields }), + 'entity.definition_id': `builtin_${entityTypeWithSchema}`, + 'entity.identity_fields': identityFields, + 'entity.display_name': getDisplayName({ identityFields, fields }), }); } } diff --git a/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts b/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts index 9f349e4a7649b..1e85059707f9d 100644 --- a/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts +++ b/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts @@ -10,10 +10,10 @@ import { coreMock } from '@kbn/core/public/mocks'; const commonEntityFields: EntityLatest = { entity: { - lastSeenTimestamp: '2023-10-09T00:00:00Z', + last_seen_timestamp: '2023-10-09T00:00:00Z', id: '1', - displayName: 'entity_name', - definitionId: 'entity_definition_id', + display_name: 'entity_name', + definition_id: 'entity_definition_id', } as EntityLatest['entity'], }; @@ -25,11 +25,11 @@ describe('EntityClient', () => { }); describe('asKqlFilter', () => { - it('should return the value when identityFields is a single string', () => { + it('should return the value when indentity_fields is a single string', () => { const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['service.name', 'service.environment'], + identity_fields: ['service.name', 'service.environment'], type: 'service', }, service: { @@ -41,11 +41,11 @@ describe('EntityClient', () => { expect(result).toEqual('service.name: my-service'); }); - it('should return values when identityFields is an array of strings', () => { + it('should return values when indentity_fields is composed by multiple fields', () => { const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['service.name', 'service.environment'], + identity_fields: ['service.name', 'service.environment'], type: 'service', }, service: { @@ -58,6 +58,25 @@ describe('EntityClient', () => { expect(result).toEqual('(service.name: my-service AND service.environment: staging)'); }); + it('should return identity fields values when an indentity field value is an array', () => { + const entityLatest: EntityLatest = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + environment: ['prod', 'staging', 'dev'], + }, + }; + + const result = entityClient.asKqlFilter(entityLatest); + expect(result).toEqual( + '(service.name: my-service AND (service.environment: prod OR service.environment: staging OR service.environment: dev))' + ); + }); + it('should throw an error when identity fields are missing', () => { const entityLatest: EntityLatest = { ...commonEntityFields, @@ -70,7 +89,7 @@ describe('EntityClient', () => { const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['host.name', 'foo.bar'], + identity_fields: ['host.name', 'foo.bar'], }, host: { name: 'my-host', @@ -84,10 +103,10 @@ describe('EntityClient', () => { describe('getIdentityFieldsValue', () => { it('should return identity fields values', () => { - const serviceEntity: EntityLatest = { + const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['service.name', 'service.environment'], + identity_fields: ['service.name', 'service.environment'], type: 'service', }, service: { @@ -95,16 +114,16 @@ describe('EntityClient', () => { }, }; - expect(entityClient.getIdentityFieldsValue(serviceEntity)).toEqual({ + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ 'service.name': 'my-service', }); }); - it('should return identity fields values when indentity field is an array of string', () => { - const serviceEntity: EntityLatest = { + it('should return identity fields values when indentity_fields is composed by multiple fields', () => { + const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['service.name', 'service.environment'], + identity_fields: ['service.name', 'service.environment'], type: 'service', }, service: { @@ -113,23 +132,42 @@ describe('EntityClient', () => { }, }; - expect(entityClient.getIdentityFieldsValue(serviceEntity)).toEqual({ + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ 'service.name': 'my-service', 'service.environment': 'staging', }); }); + it('should return identity fields values when an indentity field value is an array', () => { + const entityLatest: EntityLatest = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + environment: ['prod', 'staging', 'dev'], + }, + }; + + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ + 'service.name': 'my-service', + 'service.environment': ['prod', 'staging', 'dev'], + }); + }); + it('should return identity fields when field is in the root', () => { - const serviceEntity: EntityLatest = { + const entityLatest: EntityLatest = { entity: { ...commonEntityFields.entity, - identityFields: ['name'], + identity_fields: ['name'], type: 'service', }, name: 'foo', }; - expect(entityClient.getIdentityFieldsValue(serviceEntity)).toEqual({ + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ name: 'foo', }); }); diff --git a/x-pack/plugins/entity_manager/public/lib/entity_client.ts b/x-pack/plugins/entity_manager/public/lib/entity_client.ts index 325a638cde973..15e7808dced22 100644 --- a/x-pack/plugins/entity_manager/public/lib/entity_client.ts +++ b/x-pack/plugins/entity_manager/public/lib/entity_client.ts @@ -93,9 +93,15 @@ export class EntityClient { asKqlFilter(entityLatest: EntityLatest) { const identityFieldsValue = this.getIdentityFieldsValue(entityLatest); - const nodes: KueryNode[] = Object.entries(identityFieldsValue).map(([identityField, value]) => - nodeTypes.function.buildNode('is', identityField, value) - ); + const nodes: KueryNode[] = Object.entries(identityFieldsValue).map(([identityField, value]) => { + if (Array.isArray(value)) { + return nodeTypes.function.buildNode( + 'or', + value.map((v) => nodeTypes.function.buildNode('is', identityField, v)) + ); + } + return nodeTypes.function.buildNode('is', identityField, value); + }); if (nodes.length === 0) return ''; @@ -105,7 +111,7 @@ export class EntityClient { } getIdentityFieldsValue(entityLatest: EntityLatest) { - const { identityFields } = entityLatest.entity; + const { identity_fields: identityFields } = entityLatest.entity; if (!identityFields) { throw new Error('Identity fields are missing'); diff --git a/x-pack/plugins/observability_solution/apm/common/entities/types.ts b/x-pack/plugins/observability_solution/apm/common/entities/types.ts deleted file mode 100644 index 9775b1e32eae6..0000000000000 --- a/x-pack/plugins/observability_solution/apm/common/entities/types.ts +++ /dev/null @@ -1,12 +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 enum EntityDataStreamType { - METRICS = 'metrics', - TRACES = 'traces', - LOGS = 'logs', -} diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_entity_summary.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_entity_summary.ts index 349b8e13ae7ab..d723f6165500d 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_entity_summary.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_entity_summary.ts @@ -6,10 +6,13 @@ */ import * as z from '@kbn/zod'; -import { EntityDataStreamType, EntityType } from '@kbn/observability-shared-plugin/common'; +import { EntityDataStreamType, MANAGED_ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import { useFetcher } from '../../../hooks/use_fetcher'; -const EntityTypeSchema = z.union([z.literal(EntityType.HOST), z.literal(EntityType.CONTAINER)]); +const EntityTypeSchema = z.union([ + z.literal(MANAGED_ENTITY_TYPE.HOST), + z.literal(MANAGED_ENTITY_TYPE.CONTAINER), +]); const EntityDataStreamSchema = z.union([ z.literal(EntityDataStreamType.METRICS), z.literal(EntityDataStreamType.LOGS), diff --git a/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts index cb169f83f171d..9ec2b0530ec31 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { METRICS_APP_ID } from '@kbn/deeplinks-observability/constants'; import { entityCentricExperience } from '@kbn/observability-plugin/common'; import { createObservabilityEsClient } from '@kbn/observability-utils/es/client/create_observability_es_client'; +import { MANAGED_ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import { getInfraMetricsClient } from '../../lib/helpers/get_infra_metrics_client'; import { InfraBackendLibs } from '../../lib/infra_types'; import { getDataStreamTypes } from './get_data_stream_types'; @@ -22,7 +23,10 @@ export const initEntitiesConfigurationRoutes = (libs: InfraBackendLibs) => { path: '/api/infra/entities/{entityType}/{entityId}/summary', validate: { params: schema.object({ - entityType: schema.oneOf([schema.literal('host'), schema.literal('container')]), + entityType: schema.oneOf([ + schema.literal(MANAGED_ENTITY_TYPE.HOST), + schema.literal(MANAGED_ENTITY_TYPE.CONTAINER), + ]), entityId: schema.string(), }), }, diff --git a/x-pack/plugins/observability_solution/inventory/common/entities.ts b/x-pack/plugins/observability_solution/inventory/common/entities.ts index 8bccea2222000..3ae52ef8ff0c6 100644 --- a/x-pack/plugins/observability_solution/inventory/common/entities.ts +++ b/x-pack/plugins/observability_solution/inventory/common/entities.ts @@ -5,7 +5,7 @@ * 2.0. */ import { z } from '@kbn/zod'; -import { ENTITY_LATEST, entitiesAliasPattern, entityLatestSchema } from '@kbn/entities-schema'; +import { entityLatestSchema } from '@kbn/entities-schema'; import { ENTITY_DEFINITION_ID, ENTITY_DISPLAY_NAME, @@ -30,10 +30,11 @@ export const defaultEntitySortField: EntityColumnIds = 'alertsCount'; export const MAX_NUMBER_OF_ENTITIES = 500; -export const ENTITIES_LATEST_ALIAS = entitiesAliasPattern({ - type: '*', - dataset: ENTITY_LATEST, -}); +export const ENTITIES_LATEST_ALIAS = '.entities.v1.latest*'; +// entitiesAliasPattern({ +// type: '*', +// dataset: ENTITY_LATEST, +// }); const entityArrayRt = t.array(t.string); export const entityTypesRt = new t.Type( 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 2e4f0c319edfc..d5d08ed415a40 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 @@ -5,148 +5,65 @@ * 2.0. */ -import { type KibanaReactContextValue } from '@kbn/kibana-react-plugin/public'; -import * as useKibana from '../../../hooks/use_kibana'; -import { EntityName } from '.'; -import type { Entity } from '../../../../common/entities'; -import { render, screen } from '@testing-library/react'; import React from 'react'; -import { ASSET_DETAILS_LOCATOR_ID } from '@kbn/observability-shared-plugin/common/locators/infra/asset_details_locator'; +import { render, screen } from '@testing-library/react'; +import { EntityName } from '.'; +import { useDetailViewRedirect } from '../../../hooks/use_detail_view_redirect'; +import { Entity } from '../../../../common/entities'; +import { + ENTITY_DEFINITION_ID, + ENTITY_DISPLAY_NAME, + ENTITY_ID, + ENTITY_IDENTITY_FIELDS, + ENTITY_LAST_SEEN, + ENTITY_TYPE, +} from '@kbn/observability-shared-plugin/common'; + +jest.mock('../../../hooks/use_detail_view_redirect'); + +const useDetailViewRedirectMock = useDetailViewRedirect as jest.Mock; describe('EntityName', () => { - jest.spyOn(useKibana, 'useKibana').mockReturnValue({ - services: { - share: { - url: { - locators: { - get: (locatorId: string) => { - return { - getRedirectUrl: (params: { [key: string]: any }) => { - if (locatorId === ASSET_DETAILS_LOCATOR_ID) { - return `assets_url/${params.assetType}/${params.assetId}`; - } - return `services_url/${params.serviceName}?environment=${params.environment}`; - }, - }; - }, - }, - }, - }, - }, - } as unknown as KibanaReactContextValue); + const mockEntity: Entity = { + [ENTITY_LAST_SEEN]: '2023-10-09T00:00:00Z', + [ENTITY_ID]: '1', + [ENTITY_DISPLAY_NAME]: 'entity_name', + [ENTITY_DEFINITION_ID]: 'entity_definition_id', + [ENTITY_IDENTITY_FIELDS]: ['service.name', 'service.environment'], + [ENTITY_TYPE]: 'service', + }; - afterAll(() => { + beforeEach(() => { jest.clearAllMocks(); }); - it('returns host link', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'host', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'host.name', - 'host.name': 'foo', - 'entity.definition_id': 'host', - 'cloud.provider': null, - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'assets_url/host/foo' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + it('should render the entity name correctly', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue(null), + }); - it('returns container link', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'container', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'container.id', - 'container.id': 'foo', - 'entity.definition_id': 'container', - 'cloud.provider': null, - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'assets_url/container/foo' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + render(); - it('returns service link without environment', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=undefined' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + expect(screen.getByText('entity_name')).toBeInTheDocument(); }); - it('returns service link with environment', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': 'baz', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + it('should a link when getEntityRedirectUrl returns a URL', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue('http://foo.bar'), + }); - it('returns service link with first environment when it is an array', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': ['baz', 'bar', 'foo'], - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + render(); + + expect(screen.getByRole('link')).toHaveAttribute('href', 'http://foo.bar'); }); - it('returns service link identity fields is an array', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': ['service.name', 'service.environment'], - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': 'baz', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + it('should not render a link when getEntityRedirectUrl returns null', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue(null), + }); + + render(); + + expect(screen.queryByRole('link')).not.toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx index a62f0026ddfa0..5206f65f45820 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx @@ -6,7 +6,12 @@ */ import React from 'react'; -import { AGENT_NAME, CLOUD_PROVIDER, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { + AGENT_NAME, + CLOUD_PROVIDER, + ENTITY_TYPE, + MANAGED_ENTITY_TYPE, +} from '@kbn/observability-shared-plugin/common'; import { type CloudProvider, CloudProviderIcon, AgentIcon } from '@kbn/custom-icons'; import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; import type { AgentName } from '@kbn/elastic-agent-utils'; @@ -27,7 +32,7 @@ export function EntityIcon({ entity }: EntityIconProps) { const entityType = entity[ENTITY_TYPE]; const defaultIconSize = euiThemeVars.euiSizeL; - if (entityType === 'host' || entityType === 'container') { + if (entityType === MANAGED_ENTITY_TYPE.HOST || entityType === MANAGED_ENTITY_TYPE.CONTAINER) { const cloudProvider = getSingleValue( entity[CLOUD_PROVIDER] as NotNullableCloudProvider | NotNullableCloudProvider[] ); @@ -49,7 +54,7 @@ export function EntityIcon({ entity }: EntityIconProps) { ); } - if (entityType === 'service') { + if (entityType === MANAGED_ENTITY_TYPE.SERVICE) { const agentName = getSingleValue(entity[AGENT_NAME] as AgentName | AgentName[]); return ; } diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts index 039e87d95cf21..c822ae2d8fe23 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts @@ -19,6 +19,7 @@ import { ENTITY_LAST_SEEN, ENTITY_TYPE, HOST_NAME, + MANAGED_ENTITY_TYPE, SERVICE_ENVIRONMENT, SERVICE_NAME, } from '@kbn/observability-shared-plugin/common'; @@ -133,14 +134,23 @@ describe('useDetailViewRedirect', () => { }); [ - ['kubernetes_cluster_ecs', 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c'], - ['kubernetes_cron_job_ecs', 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_daemon_set_ecs', 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_deployment_ecs', 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_job_ecs', 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_node_ecs', 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_pod_ecs', 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013'], - ['kubernetes_stateful_set_ecs', 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013'], + [MANAGED_ENTITY_TYPE.KUBERNETES.CLUSTER.ECS, 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c'], + [MANAGED_ENTITY_TYPE.KUBERNETES.CRONJOB.ECS, 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013'], + [ + MANAGED_ENTITY_TYPE.KUBERNETES.DAEMONSET.ECS, + 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013', + ], + [ + MANAGED_ENTITY_TYPE.KUBERNETES.DEPLOYMENT.ECS, + 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013', + ], + [MANAGED_ENTITY_TYPE.KUBERNETES.JOB.ECS, 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013'], + [MANAGED_ENTITY_TYPE.KUBERNETES.NODE.ECS, 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013'], + [MANAGED_ENTITY_TYPE.KUBERNETES.POD.ECS, 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013'], + [ + MANAGED_ENTITY_TYPE.KUBERNETES.STATEFULSET.ECS, + 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013', + ], ].forEach(([entityType, dashboardId]) => { it(`getEntityRedirectUrl should return the correct URL for ${entityType} entity`, () => { const entity: Entity = { diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts index 5dce846be2124..bc4924cc4330d 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts @@ -9,6 +9,7 @@ import { AssetDetailsLocatorParams, ENTITY_IDENTITY_FIELDS, ENTITY_TYPE, + MANAGED_ENTITY_TYPE, SERVICE_ENVIRONMENT, SERVICE_OVERVIEW_LOCATOR_ID, ServiceOverviewParams, @@ -23,14 +24,16 @@ import { unflattenEntity } from '../../common/utils/unflatten_entity'; import { useKibana } from './use_kibana'; const KUBERNETES_DASHBOARDS_IDS: Record = { - kubernetes_cluster_ecs: 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c', - kubernetes_cron_job_ecs: 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_daemon_set_ecs: 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_deployment_ecs: 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_job_ecs: 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_node_ecs: 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_pod_ecs: 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013', - kubernetes_stateful_set_ecs: 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.CLUSTER.ECS]: 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c', + [MANAGED_ENTITY_TYPE.KUBERNETES.CRONJOB.ECS]: 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.DAEMONSET.ECS]: 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.DEPLOYMENT.ECS]: + 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.JOB.ECS]: 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.NODE.ECS]: 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.POD.ECS]: 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013', + [MANAGED_ENTITY_TYPE.KUBERNETES.STATEFULSET.ECS]: + 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013', }; export const useDetailViewRedirect = () => { @@ -66,8 +69,8 @@ export const useDetailViewRedirect = () => { const identityValue = getSingleIdentityFieldValue(entity); switch (type) { - case 'host': - case 'container': + case MANAGED_ENTITY_TYPE.HOST: + case MANAGED_ENTITY_TYPE.CONTAINER: return assetDetailsLocator?.getRedirectUrl({ assetId: identityValue, assetType: type, diff --git a/x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts b/x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts index d801cc214ecaf..227188d359509 100644 --- a/x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts +++ b/x-pack/plugins/observability_solution/metrics_data_access/common/constants.ts @@ -9,5 +9,6 @@ export const TIMESTAMP_FIELD = '@timestamp'; export const HOST_FIELD = 'host.name'; export const CONTAINER_FIELD = 'container.id'; export const POD_FIELD = 'kubernetes.pod.uid'; +export const KUBENRNETES_CONTAINER_FIELD = 'kubernetes.container.id'; export const METRICS_EXPLORER_API_MAX_METRICS = 20; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts b/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts index b905f542d3473..fdd5b9b5ed957 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts @@ -5,7 +5,25 @@ * 2.0. */ -export enum EntityType { - HOST = 'host', - CONTAINER = 'container', -} +const createKubernetesEntity = (base: T) => ({ + ECS: `kubernetes_${base}_ecs` as const, + SEMCONV: `kubernetes_${base}_semconv` as const, +}); + +export const MANAGED_ENTITY_TYPE = { + HOST: 'host', + CONTAINER: 'container', + SERVICE: 'service', + KUBERNETES: { + CLUSTER: createKubernetesEntity('cluster'), + CONTAINER: createKubernetesEntity('container'), + CRONJOB: createKubernetesEntity('cron_job'), + DAEMONSET: createKubernetesEntity('daemon_set'), + DEPLOYMENT: createKubernetesEntity('deployment'), + JOB: createKubernetesEntity('job'), + NAMESPACE: createKubernetesEntity('namespace'), + NODE: createKubernetesEntity('node'), + POD: createKubernetesEntity('pod'), + STATEFULSET: createKubernetesEntity('stateful_set'), + }, +} as const; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts index 27bef43d5ff7a..8d8fac054f471 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export { EntityType } from './entity_types'; +export { MANAGED_ENTITY_TYPE } from './entity_types'; export { EntityDataStreamType } from './entity_data_stream_types'; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/index.ts index b673b5d12e862..dcfefc09bdbf1 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/index.ts @@ -219,4 +219,4 @@ export { export { COMMON_OBSERVABILITY_GROUPING } from './embeddable_grouping'; -export { EntityType, EntityDataStreamType } from './entity'; +export { MANAGED_ENTITY_TYPE, EntityDataStreamType } from './entity';