Skip to content

Commit

Permalink
Merge branch 'main' into feature/darkmode_discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
kc13greiner authored Apr 25, 2023
2 parents 0aa3a56 + 672e992 commit 0a4cb6d
Show file tree
Hide file tree
Showing 47 changed files with 442 additions and 110 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@
"whatwg-fetch": "^3.0.0",
"xml2js": "^0.4.22",
"xstate": "^4.35.2",
"xterm": "^5.0.0",
"xterm": "^5.1.0",
"yauzl": "^2.10.0",
"yazl": "^2.5.1"
},
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-securitysolution-ecs/src/process/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface ProcessSessionData {
entity_id?: string[];
pid?: string[];
name?: string[];
start?: string[];
}

export interface ProcessHashData {
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-securitysolution-ecs/src/signal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ export type SignalEcsAAD = Exclude<SignalEcs, 'rule' | 'status'> & {
suppression?: {
docs_count: string[];
};
ancestors?: {
index?: string;
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/

export interface SessionViewConfig {
processIndex: string;
sessionEntityId: string;
sessionStartTime: string;
jumpToEntityId?: string;
jumpToCursor?: string;
investigatedAlertId?: string;
Expand Down
5 changes: 2 additions & 3 deletions x-pack/plugins/kubernetes_security/server/routes/agent_id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import type { ElasticsearchClient } from '@kbn/core/server';
import { PROCESS_EVENTS_INDEX } from '@kbn/session-view-plugin/common/constants';
import { AGENT_ID_ROUTE } from '../../common/constants';

export const registerAgentIdRoute = (router: IRouter) => {
Expand All @@ -34,10 +33,10 @@ export const registerAgentIdRoute = (router: IRouter) => {
);
};

export const getAgentId = async (client: ElasticsearchClient, query: string, index?: string) => {
export const getAgentId = async (client: ElasticsearchClient, query: string, index: string) => {
const queryDSL = JSON.parse(query);
const search = await client.search({
index: [index || PROCESS_EVENTS_INDEX],
index: [index],
body: {
query: queryDSL,
size: 1,
Expand Down
9 changes: 4 additions & 5 deletions x-pack/plugins/kubernetes_security/server/routes/aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type { SortCombinations } from '@elastic/elasticsearch/lib/api/typesWithB
import { schema } from '@kbn/config-schema';
import type { ElasticsearchClient } from '@kbn/core/server';
import { IRouter } from '@kbn/core/server';
import { PROCESS_EVENTS_INDEX } from '@kbn/session-view-plugin/common/constants';
import {
AGGREGATE_ROUTE,
AGGREGATE_PAGE_SIZE,
Expand All @@ -26,12 +25,12 @@ export const registerAggregateRoute = (router: IRouter) => {
path: AGGREGATE_ROUTE,
validate: {
query: schema.object({
index: schema.string(),
query: schema.string(),
countBy: schema.maybe(schema.string()),
groupBy: schema.string(),
page: schema.number(),
perPage: schema.maybe(schema.number()),
index: schema.maybe(schema.string()),
sortByCount: schema.maybe(schema.string()),
}),
},
Expand All @@ -43,11 +42,11 @@ export const registerAggregateRoute = (router: IRouter) => {
try {
const body = await doSearch(
client,
index,
query,
groupBy,
page,
perPage,
index,
countBy,
sortByCount
);
Expand All @@ -62,11 +61,11 @@ export const registerAggregateRoute = (router: IRouter) => {

export const doSearch = async (
client: ElasticsearchClient,
index: string,
query: string,
groupBy: string,
page: number, // zero based
perPage = AGGREGATE_PAGE_SIZE,
index?: string,
countBy?: string,
sortByCount?: string
): Promise<AggregateBucketPaginationResult> => {
Expand All @@ -88,7 +87,7 @@ export const doSearch = async (
}

const search = await client.search({
index: [index || PROCESS_EVENTS_INDEX],
index: [index],
body: {
query: queryDSL,
size: 0,
Expand Down
11 changes: 5 additions & 6 deletions x-pack/plugins/kubernetes_security/server/routes/count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { schema } from '@kbn/config-schema';
import type { ElasticsearchClient } from '@kbn/core/server';
import { IRouter } from '@kbn/core/server';
import { PROCESS_EVENTS_INDEX } from '@kbn/session-view-plugin/common/constants';
import { COUNT_ROUTE } from '../../common/constants';

export const registerCountRoute = (router: IRouter) => {
Expand All @@ -16,9 +15,9 @@ export const registerCountRoute = (router: IRouter) => {
path: COUNT_ROUTE,
validate: {
query: schema.object({
index: schema.string(),
query: schema.string(),
field: schema.string(),
index: schema.maybe(schema.string()),
}),
},
},
Expand All @@ -27,7 +26,7 @@ export const registerCountRoute = (router: IRouter) => {
const { query, field, index } = request.query;

try {
const body = await doCount(client, query, field, index);
const body = await doCount(client, index, query, field);

return response.ok({ body });
} catch (err) {
Expand All @@ -39,14 +38,14 @@ export const registerCountRoute = (router: IRouter) => {

export const doCount = async (
client: ElasticsearchClient,
index: string,
query: string,
field: string,
index?: string
field: string
) => {
const queryDSL = JSON.parse(query);

const search = await client.search({
index: [index || PROCESS_EVENTS_INDEX],
index: [index],
body: {
query: queryDSL,
size: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { schema } from '@kbn/config-schema';
import type { ElasticsearchClient } from '@kbn/core/server';
import { IRouter } from '@kbn/core/server';
import { PROCESS_EVENTS_INDEX } from '@kbn/session-view-plugin/common/constants';
import { MULTI_TERMS_AGGREGATE_ROUTE, AGGREGATE_PAGE_SIZE } from '../../common/constants';
import {
MultiTermsAggregateGroupBy,
Expand All @@ -20,6 +19,7 @@ export const registerMultiTermsAggregateRoute = (router: IRouter) => {
path: MULTI_TERMS_AGGREGATE_ROUTE,
validate: {
query: schema.object({
index: schema.string(),
query: schema.string(),
countBy: schema.maybe(schema.string()),
groupBys: schema.arrayOf(
Expand All @@ -31,7 +31,6 @@ export const registerMultiTermsAggregateRoute = (router: IRouter) => {
),
page: schema.number(),
perPage: schema.maybe(schema.number()),
index: schema.maybe(schema.string()),
}),
},
},
Expand All @@ -40,7 +39,7 @@ export const registerMultiTermsAggregateRoute = (router: IRouter) => {
const { query, countBy, groupBys, page, perPage, index } = request.query;

try {
const body = await doSearch(client, query, groupBys, page, perPage, index, countBy);
const body = await doSearch(client, index, query, groupBys, page, perPage, countBy);

return response.ok({ body });
} catch (err) {
Expand All @@ -52,11 +51,11 @@ export const registerMultiTermsAggregateRoute = (router: IRouter) => {

export const doSearch = async (
client: ElasticsearchClient,
index: string,
query: string,
groupBys: MultiTermsAggregateGroupBy[],
page: number, // zero based
perPage = AGGREGATE_PAGE_SIZE,
index?: string,
countBy?: string
): Promise<MultiTermsAggregateBucketPaginationResult> => {
const queryDSL = JSON.parse(query);
Expand All @@ -72,7 +71,7 @@ export const doSearch = async (
: undefined;

const search = await client.search({
index: [index || PROCESS_EVENTS_INDEX],
index: [index],
body: {
query: queryDSL,
size: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/

export interface SessionViewConfig {
processIndex: string;
sessionEntityId: string;
sessionStartTime: string;
jumpToEntityId?: string;
jumpToCursor?: string;
investigatedAlertId?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ describe('Actions', () => {
...mockTimelineData[0].ecs,
event: { kind: ['alert'] },
agent: { type: ['endpoint'] },
process: { entry_leader: { entity_id: ['test_id'] } },
process: { entry_leader: { entity_id: ['test_id'], start: ['2022-05-08T13:44:00.13Z'] } },
_index: '.ds-logs-endpoint.events.process-default',
};

const wrapper = mount(
Expand All @@ -400,7 +401,8 @@ describe('Actions', () => {
...mockTimelineData[0].ecs,
event: { kind: ['alert'] },
agent: { type: ['endpoint'] },
process: { entry_leader: { entity_id: ['test_id'] } },
process: { entry_leader: { entity_id: ['test_id'], start: ['2022-05-08T13:44:00.13Z'] } },
_index: '.ds-logs-endpoint.events.process-default',
};

const wrapper = mount(
Expand All @@ -425,7 +427,8 @@ describe('Actions', () => {
...mockTimelineData[0].ecs,
event: { kind: ['alert'] },
agent: { type: ['endpoint'] },
process: { entry_leader: { entity_id: ['test_id'] } },
process: { entry_leader: { entity_id: ['test_id'], start: ['2022-05-08T13:44:00.13Z'] } },
_index: '.ds-logs-endpoint.events.process-default',
};

const wrapper = mount(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { useTourContext } from '../guided_onboarding_tour';
import { AlertsCasesTourSteps, SecurityStepId } from '../guided_onboarding_tour/tour_config';
import { isDetectionsAlertsTable } from '../top_n/helpers';
import { GuidedOnboardingTourStep } from '../guided_onboarding_tour/tour_step';
import { DEFAULT_ACTION_BUTTON_WIDTH, isAlert } from './helpers';
import { DEFAULT_ACTION_BUTTON_WIDTH, isAlert, getSessionViewProcessIndex } from './helpers';

const ActionsContainer = styled.div`
align-items: center;
Expand Down Expand Up @@ -149,10 +149,16 @@ const ActionsComponent: React.FC<ActionProps> = ({
]);

const sessionViewConfig = useMemo(() => {
const { process, _id, timestamp } = ecsData;
const { process, _id, _index, timestamp, kibana } = ecsData;
const sessionEntityId = process?.entry_leader?.entity_id?.[0];
const sessionStartTime = process?.entry_leader?.start?.[0];
const processIndex = getSessionViewProcessIndex(kibana?.alert?.ancestors?.index?.[0] || _index);

if (sessionEntityId === undefined) {
if (
processIndex === undefined ||
sessionEntityId === undefined ||
sessionStartTime === undefined
) {
return null;
}

Expand All @@ -162,7 +168,9 @@ const ActionsComponent: React.FC<ActionProps> = ({
(investigatedAlertId && ecsData.kibana?.alert.original_time?.[0]) || timestamp;

return {
processIndex,
sessionEntityId,
sessionStartTime,
jumpToEntityId,
jumpToCursor,
investigatedAlertId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
*/

import { euiThemeVars } from '@kbn/ui-theme';
import { DEFAULT_ACTION_BUTTON_WIDTH, getActionsColumnWidth, isAlert } from './helpers';
import {
DEFAULT_ACTION_BUTTON_WIDTH,
getActionsColumnWidth,
isAlert,
getSessionViewProcessIndex,
} from './helpers';

describe('isAlert', () => {
test('it returns true when the eventType is an alert', () => {
Expand Down Expand Up @@ -48,3 +53,67 @@ describe('getActionsColumnWidth', () => {
);
});
});

describe('getSessionViewProcessIndex', () => {
test('it returns process index for cloud_defend alert event index', () => {
const result = getSessionViewProcessIndex(
'.ds-logs-cloud_defend.alerts-default-2023.04.25-000001'
);

expect(result).toEqual('logs-cloud_defend.process*');
});

test('it returns process index for cloud_defend file event index', () => {
const result = getSessionViewProcessIndex(
'.ds-logs-cloud_defend.file-default-2023.04.25-000001'
);

expect(result).toEqual('logs-cloud_defend.process*');
});

test('it returns process index for cloud_defend process event index', () => {
const result = getSessionViewProcessIndex(
'.ds-logs-cloud_defend.process-default-2023.04.25-000001'
);

expect(result).toEqual('logs-cloud_defend.process*');
});

test('it returns process index for cloud_defend that includes cluster', () => {
const result = getSessionViewProcessIndex(
'aws_ec2:.ds-logs-cloud_defend.process-default-2023.04.25-000001'
);

expect(result).toEqual('aws_ec2:logs-cloud_defend.process*');
});

test('it returns process index for endpoint file index', () => {
const result = getSessionViewProcessIndex(
'.ds-logs-endpoint.events.file-default-2023.04.25-000001'
);

expect(result).toEqual('logs-endpoint.events.process*');
});

test('it returns process index for endpoint alerts index', () => {
const result = getSessionViewProcessIndex('.ds-logs-endpoint.alerts-default-2023.04.25-000001');

expect(result).toEqual('logs-endpoint.events.process*');
});

test('it returns process index for endpoint process index', () => {
const result = getSessionViewProcessIndex(
'.ds-logs-endpoint.events.process-default-2023.04.25-000001'
);

expect(result).toEqual('logs-endpoint.events.process*');
});

test('it returns process index for endpoint that includes cluster', () => {
const result = getSessionViewProcessIndex(
'azure-01:.ds-logs-endpoint.events.process-default-2023.04.25-000001'
);

expect(result).toEqual('azure-01:logs-endpoint.events.process*');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,23 @@ export const getActionsColumnWidth = (actionButtonCount: number): number => {

return contentWidth + leftRightCellPadding;
};

// Currently both logs-endpoint.events.process* and logs-cloud_defend.process* are valid sources for session data.
// To avoid cross cluster searches, the original index of the event is used to infer the index to find data for the
// rest of the session.
export const getSessionViewProcessIndex = (eventIndex?: string | null) => {
if (!eventIndex) {
return;
}

const match = eventIndex.match(/([a-z0-9_-]+:)?\.ds-logs-(endpoint|cloud_defend)/i);
const cluster = match?.[1];
const clusterStr = cluster ? `${cluster}` : '';
const service = match?.[2];

if (service === 'endpoint') {
return `${clusterStr}logs-endpoint.events.process*`;
} else if (service === 'cloud_defend') {
return `${clusterStr}logs-cloud_defend.process*`;
}
};
Loading

0 comments on commit 0a4cb6d

Please sign in to comment.