Skip to content

Commit

Permalink
[Security Solution] Use Agent.id for endpoint pivot ID (#74272)
Browse files Browse the repository at this point in the history
* switch endpoint meta query to use agent.id

* update policy route to use agent ID

* update policy unit test, with schema change

* security front-end use agent.id as identifier

* update test to check the right field

* update SIEM to get endpoint data by agent.id

* fix type in test, but need to fix data, will still fail

* test: pull agent ID from esarchive data

* magnets, how do they work?

* cleanup

* apparently this test works differently now

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
pzl and kibanamachine authored Oct 14, 2020
1 parent 4120f1a commit 5514eca
Show file tree
Hide file tree
Showing 27 changed files with 164 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import { schema } from '@kbn/config-schema';

export const GetPolicyResponseSchema = {
query: schema.object({
hostId: schema.string(),
agentId: schema.string(),
}),
};
27 changes: 27 additions & 0 deletions x-pack/plugins/security_solution/public/graphql/introspection.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "",
Expand Down Expand Up @@ -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",
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/security_solution/public/graphql/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ export interface HostsEdges {
export interface HostItem {
_id?: Maybe<string>;

agent?: Maybe<AgentFields>;

cloud?: Maybe<CloudFields>;

endpoint?: Maybe<EndpointFields>;
Expand All @@ -501,6 +503,10 @@ export interface HostItem {
lastSeen?: Maybe<string>;
}

export interface AgentFields {
id?: Maybe<string>;
}

export interface CloudFields {
instance?: Maybe<CloudInstance>;

Expand Down Expand Up @@ -1728,6 +1734,8 @@ export namespace GetHostOverviewQuery {

_id: Maybe<string>;

agent: Maybe<Agent>;

host: Maybe<Host>;

cloud: Maybe<Cloud>;
Expand All @@ -1737,6 +1745,12 @@ export namespace GetHostOverviewQuery {
endpoint: Maybe<Endpoint>;
};

export type Agent = {
__typename?: 'AgentFields';

id: Maybe<string>;
}

export type Host = {
__typename?: 'HostEcsFields';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export const HostOverviewQuery = gql`
id
HostOverview(hostName: $hostName, timerange: $timerange, defaultIndex: $defaultIndex) {
_id
agent {
id
}
host {
architecture
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
// call the policy response api
try {
const policyResponse = await coreStart.http.get(`/api/endpoint/policy_response`, {
query: { hostId: selectedEndpoint },
query: { agentId: selectedEndpoint },
});
dispatch({
type: 'serverReturnedEndpointPolicyResponse',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const endpointListApiPathHandlerMocks = ({
if (endpointsResults) {
endpointsResults.forEach((host) => {
// @ts-expect-error
apiHandlers[`/api/endpoint/metadata/${host.metadata.host.id}`] = () => host;
apiHandlers[`/api/endpoint/metadata/${host.metadata.agent.id}`] = () => host;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;
Expand All @@ -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,
}),
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'] => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ReturnType<AppContextTestRender['render']>>;
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();
Expand All @@ -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;
Expand Down Expand Up @@ -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`
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('query builder v1', () => {
match_all: {},
},
collapse: {
field: 'host.id',
field: 'agent.id',
inner_hits: {
name: 'most_recent',
size: 1,
Expand All @@ -41,7 +41,7 @@ describe('query builder v1', () => {
aggs: {
total: {
cardinality: {
field: 'host.id',
field: 'agent.id',
},
},
},
Expand Down Expand Up @@ -92,7 +92,7 @@ describe('query builder v1', () => {
},
},
collapse: {
field: 'host.id',
field: 'agent.id',
inner_hits: {
name: 'most_recent',
size: 1,
Expand All @@ -102,7 +102,7 @@ describe('query builder v1', () => {
aggs: {
total: {
cardinality: {
field: 'host.id',
field: 'agent.id',
},
},
},
Expand Down Expand Up @@ -165,7 +165,7 @@ describe('query builder v1', () => {
},
},
collapse: {
field: 'host.id',
field: 'agent.id',
inner_hits: {
name: 'most_recent',
size: 1,
Expand All @@ -175,7 +175,7 @@ describe('query builder v1', () => {
aggs: {
total: {
cardinality: {
field: 'host.id',
field: 'agent.id',
},
},
},
Expand Down Expand Up @@ -251,7 +251,7 @@ describe('query builder v1', () => {
},
},
collapse: {
field: 'host.id',
field: 'agent.id',
inner_hits: {
name: 'most_recent',
size: 1,
Expand All @@ -261,7 +261,7 @@ describe('query builder v1', () => {
aggs: {
total: {
cardinality: {
field: 'host.id',
field: 'agent.id',
},
},
},
Expand Down Expand Up @@ -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,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy {
return {
index: metadataIndexPattern,
elasticAgentIdProperty: 'elastic.agent.id',
hostIdProperty: 'host.id',
hostIdProperty: 'agent.id',
sortProperty: [
{
'event.created': {
Expand All @@ -33,7 +33,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy {
],
extraBodyProperties: {
collapse: {
field: 'host.id',
field: 'agent.id',
inner_hits: {
name: 'most_recent',
size: 1,
Expand All @@ -43,7 +43,7 @@ export function metadataQueryStrategyV1(): MetadataQueryStrategy {
aggs: {
total: {
cardinality: {
field: 'host.id',
field: 'agent.id',
},
},
},
Expand Down Expand Up @@ -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': {
Expand Down
Loading

0 comments on commit 5514eca

Please sign in to comment.