diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts index 17d0cdff57ee..35ba1266066e 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts @@ -7,6 +7,6 @@ import { schema } from '@kbn/config-schema'; export const GetPolicyResponseSchema = { query: schema.object({ - hostId: schema.string(), + agentId: schema.string(), }), }; diff --git a/x-pack/plugins/security_solution/public/graphql/introspection.json b/x-pack/plugins/security_solution/public/graphql/introspection.json index cc91d2390581..30dec34ab39b 100644 --- a/x-pack/plugins/security_solution/public/graphql/introspection.json +++ b/x-pack/plugins/security_solution/public/graphql/introspection.json @@ -1412,6 +1412,14 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "agent", + "description": "", + "args": [], + "type": { "kind": "OBJECT", "name": "AgentFields", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "cloud", "description": "", @@ -1458,6 +1466,25 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "AgentFields", + "description": "", + "fields": [ + { + "name": "id", + "description": "", + "args": [], + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "CloudFields", diff --git a/x-pack/plugins/security_solution/public/graphql/types.ts b/x-pack/plugins/security_solution/public/graphql/types.ts index 52598b5f4494..17f8e19a6055 100644 --- a/x-pack/plugins/security_solution/public/graphql/types.ts +++ b/x-pack/plugins/security_solution/public/graphql/types.ts @@ -490,6 +490,8 @@ export interface HostsEdges { export interface HostItem { _id?: Maybe; + agent?: Maybe; + cloud?: Maybe; endpoint?: Maybe; @@ -501,6 +503,10 @@ export interface HostItem { lastSeen?: Maybe; } +export interface AgentFields { + id?: Maybe; +} + export interface CloudFields { instance?: Maybe; @@ -1728,6 +1734,8 @@ export namespace GetHostOverviewQuery { _id: Maybe; + agent: Maybe; + host: Maybe; cloud: Maybe; @@ -1737,6 +1745,12 @@ export namespace GetHostOverviewQuery { endpoint: Maybe; }; + export type Agent = { + __typename?: 'AgentFields'; + + id: Maybe; + } + export type Host = { __typename?: 'HostEcsFields'; diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/details/host_overview.gql_query.ts b/x-pack/plugins/security_solution/public/hosts/containers/hosts/details/host_overview.gql_query.ts index 89937d0adf81..c0724ea3dd41 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/details/host_overview.gql_query.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/details/host_overview.gql_query.ts @@ -18,6 +18,9 @@ export const HostOverviewQuery = gql` id HostOverview(hostName: $hostName, timerange: $timerange, defaultIndex: $defaultIndex) { _id + agent { + id + } host { architecture id diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts index 17e0101426b0..80b2d2b0192f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts @@ -314,7 +314,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory { // @ts-expect-error - apiHandlers[`/api/endpoint/metadata/${host.metadata.host.id}`] = () => host; + apiHandlers[`/api/endpoint/metadata/${host.metadata.agent.id}`] = () => host; }); } diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx index 47f4fbb8830a..c0763a21f094 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details.tsx @@ -89,16 +89,16 @@ export const EndpointDetails = memo(({ details }: { details: HostMetadata }) => getEndpointDetailsPath({ name: 'endpointPolicyResponse', ...currentUrlParams, - selected_endpoint: details.host.id, + selected_endpoint: details.agent.id, }) ), getEndpointDetailsPath({ name: 'endpointPolicyResponse', ...currentUrlParams, - selected_endpoint: details.host.id, + selected_endpoint: details.agent.id, }), ]; - }, [details.host.id, formatUrl, queryParams]); + }, [details.agent.id, formatUrl, queryParams]); const agentDetailsWithFlyoutPath = `${agentDetailsAppPath}${openReassignFlyoutSearch}`; const agentDetailsWithFlyoutUrl = `${agentDetailsUrl}${openReassignFlyoutSearch}`; @@ -112,7 +112,7 @@ export const EndpointDetails = memo(({ details }: { details: HostMetadata }) => { path: getEndpointDetailsPath({ name: 'endpointDetails', - selected_endpoint: details.host.id, + selected_endpoint: details.agent.id, }), }, ], diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx index 43d3b39474fc..6bc3445c8e74 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx @@ -131,16 +131,16 @@ const PolicyResponseFlyoutPanel = memo<{ getEndpointListPath({ name: 'endpointList', ...queryParams, - selected_endpoint: hostMeta.host.id, + selected_endpoint: hostMeta.agent.id, }) ), getEndpointListPath({ name: 'endpointList', ...queryParams, - selected_endpoint: hostMeta.host.id, + selected_endpoint: hostMeta.agent.id, }), ], - [hostMeta.host.id, formatUrl, queryParams] + [hostMeta.agent.id, formatUrl, queryParams] ); const backToDetailsClickHandler = useNavigateByRouterEventHandler(detailsRoutePath); const backButtonProp = useMemo((): FlyoutSubHeaderProps['backButton'] => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index debdde901407..12a76ae0772a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -397,13 +397,13 @@ describe('when on the list page', () => { describe('when there is a selected host in the url', () => { let hostDetails: HostInfo; - let agentId: string; + let elasticAgentId: string; let renderAndWaitForData: () => Promise>; const mockEndpointListApi = (mockedPolicyResponse?: HostPolicyResponse) => { const { // eslint-disable-next-line @typescript-eslint/naming-convention host_status, - metadata: { host, ...details }, + metadata: { agent, ...details }, // eslint-disable-next-line @typescript-eslint/naming-convention query_strategy_version, } = mockEndpointDetailsApiResult(); @@ -412,15 +412,15 @@ describe('when on the list page', () => { host_status, metadata: { ...details, - host: { - ...host, + agent: { + ...agent, id: '1', }, }, query_strategy_version, }; - agentId = hostDetails.metadata.elastic.agent.id; + elasticAgentId = hostDetails.metadata.elastic.agent.id; const policy = docGenerator.generatePolicyPackagePolicy(); policy.id = hostDetails.metadata.Endpoint.policy.applied.id; @@ -618,7 +618,7 @@ describe('when on the list page', () => { expect(linkToReassign).not.toBeNull(); expect(linkToReassign.textContent).toEqual('Reassign Policy'); expect(linkToReassign.getAttribute('href')).toEqual( - `/app/ingestManager#/fleet/agents/${agentId}/activity?openReassignFlyout=true` + `/app/ingestManager#/fleet/agents/${elasticAgentId}/activity?openReassignFlyout=true` ); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index b514707da6f6..36c5b0d1037e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -261,11 +261,11 @@ export const EndpointList = () => { return [ { - field: 'metadata.host', + field: 'metadata', name: i18n.translate('xpack.securitySolution.endpoint.list.hostname', { defaultMessage: 'Hostname', }), - render: ({ hostname, id }: HostInfo['metadata']['host']) => { + render: ({ host: { hostname }, agent: { id } }: HostInfo['metadata']) => { const toRoutePath = getEndpointDetailsPath( { ...queryParams, @@ -342,7 +342,7 @@ export const EndpointList = () => { const toRoutePath = getEndpointDetailsPath({ name: 'endpointPolicyResponse', ...queryParams, - selected_endpoint: item.metadata.host.id, + selected_endpoint: item.metadata.agent.id, }); const toRouteUrl = formatUrl(toRoutePath); return ( diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts index cc371f9120ba..c8e0292e8d93 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts @@ -255,11 +255,11 @@ async function enrichHostMetadata( const log = metadataRequestContext.logger; try { /** - * Get agent status by elastic agent id if available or use the host id. + * Get agent status by elastic agent id if available or use the endpoint-agent id. */ if (!elasticAgentId) { - elasticAgentId = hostMetadata.host.id; + elasticAgentId = hostMetadata.agent.id; log.warn(`Missing elastic agent id, using host id instead ${elasticAgentId}`); } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts index cb79263ef6b3..ac1de377124f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts @@ -230,7 +230,7 @@ describe('query builder', () => { expect(query).toEqual({ body: { - query: { match: { 'HostDetails.host.id': mockID } }, + query: { match: { 'HostDetails.agent.id': mockID } }, sort: [{ 'HostDetails.event.created': { order: 'desc' } }], size: 1, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts index 0b166e097af9..7980fc83358b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts @@ -116,14 +116,14 @@ function buildQueryBody( } export function getESQueryHostMetadataByID( - hostID: string, + agentID: string, metadataQueryStrategy: MetadataQueryStrategy ) { return { body: { query: { match: { - [metadataQueryStrategy.hostIdProperty]: hostID, + [metadataQueryStrategy.hostIdProperty]: agentID, }, }, sort: metadataQueryStrategy.sortProperty, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders_v1.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders_v1.test.ts index 899fe4b880ac..ca65d18bb9f6 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders_v1.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders_v1.test.ts @@ -31,7 +31,7 @@ describe('query builder v1', () => { match_all: {}, }, collapse: { - field: 'host.id', + field: 'agent.id', inner_hits: { name: 'most_recent', size: 1, @@ -41,7 +41,7 @@ describe('query builder v1', () => { aggs: { total: { cardinality: { - field: 'host.id', + field: 'agent.id', }, }, }, @@ -92,7 +92,7 @@ describe('query builder v1', () => { }, }, collapse: { - field: 'host.id', + field: 'agent.id', inner_hits: { name: 'most_recent', size: 1, @@ -102,7 +102,7 @@ describe('query builder v1', () => { aggs: { total: { cardinality: { - field: 'host.id', + field: 'agent.id', }, }, }, @@ -165,7 +165,7 @@ describe('query builder v1', () => { }, }, collapse: { - field: 'host.id', + field: 'agent.id', inner_hits: { name: 'most_recent', size: 1, @@ -175,7 +175,7 @@ describe('query builder v1', () => { aggs: { total: { cardinality: { - field: 'host.id', + field: 'agent.id', }, }, }, @@ -251,7 +251,7 @@ describe('query builder v1', () => { }, }, collapse: { - field: 'host.id', + field: 'agent.id', inner_hits: { name: 'most_recent', size: 1, @@ -261,7 +261,7 @@ describe('query builder v1', () => { aggs: { total: { cardinality: { - field: 'host.id', + field: 'agent.id', }, }, }, @@ -289,7 +289,7 @@ describe('query builder v1', () => { expect(query).toEqual({ body: { - query: { match: { 'host.id': mockID } }, + query: { match: { 'agent.id': mockID } }, sort: [{ 'event.created': { order: 'desc' } }], size: 1, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/query_strategies.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/query_strategies.ts index df4c37726246..f1614cc19e8c 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/query_strategies.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/query_strategies.ts @@ -23,7 +23,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy { return { index: metadataIndexPattern, elasticAgentIdProperty: 'elastic.agent.id', - hostIdProperty: 'host.id', + hostIdProperty: 'agent.id', sortProperty: [ { 'event.created': { @@ -33,7 +33,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy { ], extraBodyProperties: { collapse: { - field: 'host.id', + field: 'agent.id', inner_hits: { name: 'most_recent', size: 1, @@ -43,7 +43,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy { aggs: { total: { cardinality: { - field: 'host.id', + field: 'agent.id', }, }, }, @@ -78,7 +78,7 @@ export function metadataQueryStrategyV2(): MetadataQueryStrategy { return { index: metadataCurrentIndexPattern, elasticAgentIdProperty: 'HostDetails.elastic.agent.id', - hostIdProperty: 'HostDetails.host.id', + hostIdProperty: 'HostDetails.agent.id', sortProperty: [ { 'HostDetails.event.created': { diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 8d4524e06c49..7dddc357fe53 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -51,7 +51,7 @@ describe('test policy response handler', () => { mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response)); const mockRequest = httpServerMock.createKibanaRequest({ - params: { hostId: 'id' }, + params: { agentId: 'id' }, }); await hostPolicyResponseHandler( @@ -62,7 +62,7 @@ describe('test policy response handler', () => { expect(mockResponse.ok).toBeCalled(); const result = mockResponse.ok.mock.calls[0][0]?.body as GetHostPolicyResponse; - expect(result.policy_response.host.id).toEqual(response.hits.hits[0]._source.host.id); + expect(result.policy_response.agent.id).toEqual(response.hits.hits[0]._source.agent.id); }); it('should return not found when there is no response policy for host', async () => { @@ -77,7 +77,7 @@ describe('test policy response handler', () => { ); const mockRequest = httpServerMock.createKibanaRequest({ - params: { hostId: 'id' }, + params: { agentId: 'id' }, }); await hostPolicyResponseHandler( diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index fd685efb94aa..f3a7b08a4cd4 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -8,16 +8,16 @@ import { TypeOf } from '@kbn/config-schema'; import { policyIndexPattern } from '../../../../common/endpoint/constants'; import { GetPolicyResponseSchema } from '../../../../common/endpoint/schema/policy'; import { EndpointAppContext } from '../../types'; -import { getPolicyResponseByHostId } from './service'; +import { getPolicyResponseByAgentId } from './service'; export const getHostPolicyResponseHandler = function ( endpointAppContext: EndpointAppContext ): RequestHandler, undefined> { return async (context, request, response) => { try { - const doc = await getPolicyResponseByHostId( + const doc = await getPolicyResponseByAgentId( policyIndexPattern, - request.query.hostId, + request.query.agentId, context.core.elasticsearch.legacy.client ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.test.ts index f05d9ef5b821..40a691c1ddbd 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.test.ts @@ -5,13 +5,13 @@ */ import { GetPolicyResponseSchema } from '../../../../common/endpoint/schema/policy'; -import { getESQueryPolicyResponseByHostID } from './service'; +import { getESQueryPolicyResponseByAgentID } from './service'; describe('test policy handlers schema', () => { it('validate that get policy response query schema', async () => { expect( GetPolicyResponseSchema.query.validate({ - hostId: 'id', + agentId: 'id', }) ).toBeTruthy(); @@ -21,13 +21,13 @@ describe('test policy handlers schema', () => { describe('test policy query', () => { it('queries for the correct host', async () => { - const hostID = 'f757d3c0-e874-11ea-9ad9-015510b487f4'; - const query = getESQueryPolicyResponseByHostID(hostID, 'anyindex'); - expect(query.body.query.bool.filter.term).toEqual({ 'host.id': hostID }); + const agentId = 'f757d3c0-e874-11ea-9ad9-015510b487f4'; + const query = getESQueryPolicyResponseByAgentID(agentId, 'anyindex'); + expect(query.body.query.bool.filter.term).toEqual({ 'agent.id': agentId }); }); it('filters out initial policy by ID', async () => { - const query = getESQueryPolicyResponseByHostID( + const query = getESQueryPolicyResponseByAgentID( 'f757d3c0-e874-11ea-9ad9-015510b487f4', 'anyindex' ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts index 1b3d232f9421..0019c97a6cce 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts @@ -9,14 +9,14 @@ import { ILegacyScopedClusterClient } from 'kibana/server'; import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; import { INITIAL_POLICY_ID } from './index'; -export function getESQueryPolicyResponseByHostID(hostID: string, index: string) { +export function getESQueryPolicyResponseByAgentID(agentID: string, index: string) { return { body: { query: { bool: { filter: { term: { - 'host.id': hostID, + 'agent.id': agentID, }, }, must_not: { @@ -39,12 +39,12 @@ export function getESQueryPolicyResponseByHostID(hostID: string, index: string) }; } -export async function getPolicyResponseByHostId( +export async function getPolicyResponseByAgentId( index: string, - hostId: string, + agentID: string, dataClient: ILegacyScopedClusterClient ): Promise { - const query = getESQueryPolicyResponseByHostID(hostId, index); + const query = getESQueryPolicyResponseByAgentID(agentID, index); const response = (await dataClient.callAsCurrentUser('search', query)) as SearchResponse< HostPolicyResponse >; diff --git a/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts index 48bb0cbe37af..4623fa6514e7 100644 --- a/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts @@ -26,6 +26,10 @@ export const hostsSchema = gql` type: String } + type AgentFields { + id: String + } + type CloudInstance { id: [String] } @@ -55,6 +59,7 @@ export const hostsSchema = gql` type HostItem { _id: String + agent: AgentFields cloud: CloudFields endpoint: EndpointFields host: HostEcsFields diff --git a/x-pack/plugins/security_solution/server/graphql/types.ts b/x-pack/plugins/security_solution/server/graphql/types.ts index 7730cea2b984..bda0fed494a6 100644 --- a/x-pack/plugins/security_solution/server/graphql/types.ts +++ b/x-pack/plugins/security_solution/server/graphql/types.ts @@ -492,6 +492,8 @@ export interface HostsEdges { export interface HostItem { _id?: Maybe; + agent?: Maybe; + cloud?: Maybe; endpoint?: Maybe; @@ -503,6 +505,10 @@ export interface HostItem { lastSeen?: Maybe; } +export interface AgentFields { + id?: Maybe; +} + export interface CloudFields { instance?: Maybe; @@ -2268,6 +2274,8 @@ export namespace HostItemResolvers { export interface Resolvers { _id?: _IdResolver, TypeParent, TContext>; + agent?: AgentResolver, TypeParent, TContext>; + cloud?: CloudResolver, TypeParent, TContext>; endpoint?: EndpointResolver, TypeParent, TContext>; @@ -2284,6 +2292,11 @@ export namespace HostItemResolvers { Parent, TContext >; + export type AgentResolver< + R = Maybe, + Parent = HostItem, + TContext = SiemContext + > = Resolver; export type CloudResolver< R = Maybe, Parent = HostItem, @@ -2311,6 +2324,19 @@ export namespace HostItemResolvers { > = Resolver; } +export namespace AgentFieldsResolvers { + export interface Resolvers { + id?: IdResolver, TypeParent, TContext>; + } + + export type IdResolver< + R = Maybe, + Parent = AgentFields, + TContext = SiemContext + > = Resolver; +} + + export namespace CloudFieldsResolvers { export interface Resolvers { instance?: InstanceResolver, TypeParent, TContext>; @@ -6043,6 +6069,7 @@ export type IResolvers = { HostsData?: HostsDataResolvers.Resolvers; HostsEdges?: HostsEdgesResolvers.Resolvers; HostItem?: HostItemResolvers.Resolvers; + AgentFields?: AgentFieldsResolvers.Resolvers; CloudFields?: CloudFieldsResolvers.Resolvers; CloudInstance?: CloudInstanceResolvers.Resolvers; CloudMachine?: CloudMachineResolvers.Resolvers; diff --git a/x-pack/plugins/security_solution/server/lib/ecs_fields/index.ts b/x-pack/plugins/security_solution/server/lib/ecs_fields/index.ts index d1c8290b3462..099160b7e4d6 100644 --- a/x-pack/plugins/security_solution/server/lib/ecs_fields/index.ts +++ b/x-pack/plugins/security_solution/server/lib/ecs_fields/index.ts @@ -85,6 +85,7 @@ export const processFieldsMap: Readonly> = { export const agentFieldsMap: Readonly> = { 'agent.type': 'agent.type', + 'agent.id': 'agent.id', }; export const userFieldsMap: Readonly> = { diff --git a/x-pack/plugins/security_solution/server/lib/hosts/elasticsearch_adapter.ts b/x-pack/plugins/security_solution/server/lib/hosts/elasticsearch_adapter.ts index ff2796e6852d..36244ecbff72 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/elasticsearch_adapter.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/elasticsearch_adapter.ts @@ -95,19 +95,19 @@ export class ElasticsearchHostsAdapter implements HostsAdapter { response: [inspectStringifyObject(response)], }; const formattedHostItem = formatHostItem(options.fields, aggregations); - const hostId = - formattedHostItem.host && formattedHostItem.host.id - ? Array.isArray(formattedHostItem.host.id) - ? formattedHostItem.host.id[0] - : formattedHostItem.host.id + const ident = // endpoint-generated ID, NOT elastic-agent-id + formattedHostItem.agent && formattedHostItem.agent.id + ? Array.isArray(formattedHostItem.agent.id) + ? formattedHostItem.agent.id[0] + : formattedHostItem.agent.id : null; - const endpoint: EndpointFields | null = await this.getHostEndpoint(request, hostId); + const endpoint: EndpointFields | null = await this.getHostEndpoint(request, ident); return { inspect, _id: options.hostName, ...formattedHostItem, endpoint }; } public async getHostEndpoint( request: FrameworkRequest, - hostId: string | null + id: string | null ): Promise { const logger = this.endpointContext.logFactory.get('metadata'); try { @@ -121,8 +121,8 @@ export class ElasticsearchHostsAdapter implements HostsAdapter { requestHandlerContext: request.context, }; const endpointData = - hostId != null && metadataRequestContext.endpointAppContextService.getAgentService() != null - ? await getHostData(metadataRequestContext, hostId) + id != null && metadataRequestContext.endpointAppContextService.getAgentService() != null + ? await getHostData(metadataRequestContext, id) : null; return endpointData != null && endpointData.metadata ? { diff --git a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts index 97aa68c0f9bb..e9dcee35005d 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts @@ -299,6 +299,7 @@ export const mockGetHostOverviewOptions: HostOverviewRequestOptions = { defaultIndex: DEFAULT_INDEX_PATTERN, fields: [ '_id', + 'agent.id', 'host.architecture', 'host.id', 'host.ip', @@ -328,7 +329,7 @@ export const mockGetHostOverviewRequest = { operationName: 'GetHostOverviewQuery', variables: { sourceId: 'default', hostName: 'siem-es' }, query: - 'query GetHostOverviewQuery($sourceId: ID!, $hostName: String!, $timerange: TimerangeInput!) {\n source(id: $sourceId) {\n id\n HostOverview(hostName: $hostName, timerange: $timerange) {\n _id\n host {\n architecture\n id\n ip\n mac\n name\n os {\n family\n name\n platform\n version\n __typename\n }\n type\n __typename\n }\n cloud {\n instance {\n id\n __typename\n }\n machine {\n type\n __typename\n }\n provider\n region\n __typename\n }\n __typename\n }\n __typename\n }\n}\n', + 'query GetHostOverviewQuery($sourceId: ID!, $hostName: String!, $timerange: TimerangeInput!) {\n source(id: $sourceId) {\n id\n HostOverview(hostName: $hostName, timerange: $timerange) {\n _id\n agent {\n id\n }\n host {\n architecture\n id\n ip\n mac\n name\n os {\n family\n name\n platform\n version\n __typename\n }\n type\n __typename\n }\n cloud {\n instance {\n id\n __typename\n }\n machine {\n type\n __typename\n }\n provider\n region\n __typename\n }\n __typename\n }\n __typename\n }\n}\n', }, }; @@ -461,6 +462,17 @@ export const mockGetHostOverviewResponse = { }, ], }, + agent_id: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: '9f48a9ab-749a-4ff0-b4e2-7e53910a985', + doc_count: 611894, + timestamp: { value: 1554826117972, value_as_string: '2019-04-09T16:08:37.972Z' }, + }, + ], + }, }, }; @@ -474,6 +486,9 @@ export const mockGetHostOverviewResult = { response: [JSON.stringify(mockGetHostOverviewResponse, null, 2)], }, _id: 'siem-es', + agent: { + id: '9f48a9ab-749a-4ff0-b4e2-7e53910a985', + }, host: { architecture: 'x86_64', id: 'b6d5264e4b9c8880ad1053841067a4a6', diff --git a/x-pack/plugins/security_solution/server/lib/hosts/query.detail_host.dsl.ts b/x-pack/plugins/security_solution/server/lib/hosts/query.detail_host.dsl.ts index 10dcb7ee7e74..00769b75a8ce 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/query.detail_host.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/query.detail_host.dsl.ts @@ -5,7 +5,7 @@ */ import { reduceFields } from '../../utils/build_query/reduce_fields'; -import { cloudFieldsMap, hostFieldsMap } from '../ecs_fields'; +import { cloudFieldsMap, hostFieldsMap, agentFieldsMap } from '../ecs_fields'; import { buildFieldsTermAggregation } from './helpers'; import { HostOverviewRequestOptions } from './types'; @@ -19,7 +19,7 @@ export const buildHostOverviewQuery = ({ }, timerange: { from, to }, }: HostOverviewRequestOptions) => { - const esFields = reduceFields(fields, { ...hostFieldsMap, ...cloudFieldsMap }); + const esFields = reduceFields(fields, { ...hostFieldsMap, ...cloudFieldsMap, ...agentFieldsMap }); const filter = [ { term: { 'host.name': hostName } }, diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index 5b5949821580..0b018cdb37cc 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -162,7 +162,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe.skip("has a url with an endpoint host's id", () => { before(async () => { await pageObjects.endpoint.navigateToEndpointList( - 'selected_host=fc0ff548-feba-41b6-8367-65e8790d0eaf' + 'selected_endpoint=3838df35-a095-4af4-8fce-0b6d78793f2e' ); }); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/policy.ts b/x-pack/test/security_solution_endpoint_api_int/apis/policy.ts index 66bcc0e75991..1a4e69267f9c 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/policy.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/policy.ts @@ -19,20 +19,20 @@ export default function ({ getService }: FtrProviderContext) { // to do it manually after(async () => await deletePolicyStream(getService)); - it('should return one policy response for host', async () => { - const expectedHostId = '4f3b9858-a96d-49d8-a326-230d7763d767'; + it('should return one policy response for an id', async () => { + const expectedAgentId = 'a10ac658-a3bc-4ac6-944a-68d9bd1c5a5e'; const { body } = await supertest - .get(`/api/endpoint/policy_response?hostId=${expectedHostId}`) + .get(`/api/endpoint/policy_response?agentId=${expectedAgentId}`) .send() .expect(200); - expect(body.policy_response.host.id).to.eql(expectedHostId); + expect(body.policy_response.agent.id).to.eql(expectedAgentId); expect(body.policy_response.Endpoint.policy).to.not.be(undefined); }); it('should return not found if host has no policy response', async () => { const { body } = await supertest - .get(`/api/endpoint/policy_response?hostId=bad_host_id`) + .get(`/api/endpoint/policy_response?agentId=bad_id`) .send() .expect(404);