Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Defend Workflows] Common response actions tab in alert Flyout #155362

Merged
merged 68 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
cad6b3e
init commit with common tab
tomsonpl Apr 20, 2023
f619fae
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 20, 2023
460149a
remove unused translations
tomsonpl Apr 20, 2023
e64ee6d
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl Apr 20, 2023
ca47f2d
fix tests
tomsonpl Apr 20, 2023
7e1abb9
fix tests
tomsonpl Apr 21, 2023
0023975
fix tests
tomsonpl Apr 21, 2023
1837cf2
add empty prompt to result
tomsonpl Apr 21, 2023
c77bbda
eslint fix
tomsonpl Apr 21, 2023
61f72b8
Merge branch 'main' into response-actions-common-tab
tomsonpl Apr 24, 2023
40ba3d0
hide common tab behind a feature flag
tomsonpl Apr 24, 2023
00039a4
i18n
tomsonpl Apr 24, 2023
7fa7096
i18n
tomsonpl Apr 24, 2023
5991b3d
add export
tomsonpl Apr 24, 2023
9e1b4f0
fix test
tomsonpl Apr 24, 2023
14304af
[CI] Auto-commit changed files from 'node scripts/precommit_hook.js -…
kibanamachine Apr 24, 2023
452bb38
small adjustments
tomsonpl Apr 24, 2023
e772a54
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl Apr 24, 2023
9bf6bc0
Merge branch 'main' into response-actions-common-tab
tomsonpl Apr 25, 2023
fa62c61
Merge branch 'main' into response-actions-common-tab
tomsonpl May 9, 2023
f7d7c28
fix not showing error
tomsonpl May 9, 2023
262cec6
add translation
tomsonpl May 9, 2023
cf07c5a
Merge branch 'main' into response-actions-common-tab
tomsonpl May 9, 2023
e17b89a
Merge branch 'main' into response-actions-common-tab
tomsonpl May 9, 2023
7827b43
remove endpoint results tab, show osquery or combined instead
tomsonpl May 9, 2023
d8a3934
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 9, 2023
493f2eb
move response actions results away
tomsonpl May 10, 2023
8ab4d21
fix interface and get proper wasSuccesful etc values
tomsonpl May 10, 2023
670a3a6
Merge branch 'main' into response-actions-common-tab
tomsonpl May 10, 2023
f4ef4c1
fix e2e
tomsonpl May 10, 2023
6dd2606
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 10, 2023
68eacfa
Merge branch 'main' into response-actions-common-tab
tomsonpl May 11, 2023
9c3705a
rbac permission denied
tomsonpl May 11, 2023
ed178fa
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 11, 2023
3fdaaec
fix i18n
tomsonpl May 11, 2023
61f8c57
adjust with_automated toggle to other toggles regarding isflyout beha…
tomsonpl May 11, 2023
d43e991
apply comments
tomsonpl May 16, 2023
31d3e9d
fix import
tomsonpl May 16, 2023
487ec34
fix i18n
tomsonpl May 16, 2023
d6ac239
Merge branch 'main' into response-actions-common-tab
tomsonpl May 16, 2023
279d7ab
move status calculation to response and check for isLive to refetch data
tomsonpl May 16, 2023
66fb27c
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 16, 2023
b6d4fa1
Update x-pack/plugins/security_solution/common/experimental_features.ts
tomsonpl May 16, 2023
6b3f72d
fix tests
tomsonpl May 16, 2023
96a6ff5
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 16, 2023
37ed2eb
add comments
tomsonpl May 16, 2023
c172de5
remove agents and agent_ids
tomsonpl May 16, 2023
9fa4cfd
Merge branch 'main' into response-actions-common-tab
tomsonpl May 17, 2023
c3a6da7
add hostname to action
tomsonpl May 17, 2023
ce01f16
fix types
tomsonpl May 17, 2023
73f8457
fix test
tomsonpl May 17, 2023
18259d9
fix tests
tomsonpl May 17, 2023
39939f6
remove skip
tomsonpl May 17, 2023
9b31959
move osquery things outside of security_solution
tomsonpl May 18, 2023
ef32196
change search strategy types
tomsonpl May 18, 2023
f346611
revert flag
tomsonpl May 18, 2023
ab5a6fc
fix test
tomsonpl May 18, 2023
9aebc25
add eui spacer
tomsonpl May 18, 2023
315b522
Merge branch 'main' of github.com:elastic/kibana into response-action…
patrykkopycinski May 21, 2023
66bcee6
remove unused translations
tomsonpl May 22, 2023
798396e
remove todo
tomsonpl May 22, 2023
e25e8d4
Merge branch 'main' into response-actions-common-tab
tomsonpl May 23, 2023
1f37906
move hosts to endpointdata.data, change skip to enabled, some const r…
tomsonpl May 23, 2023
ae58edf
Merge remote-tracking branch 'origin/response-actions-common-tab' int…
tomsonpl May 23, 2023
b7af36e
fix flag
tomsonpl May 23, 2023
ac2be61
remove sortfield
tomsonpl May 23, 2023
fa070de
apply comments, handle multiple hosts in ui
tomsonpl May 24, 2023
49d7c4f
add internal state to automated filter, change url based on flyout
tomsonpl May 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion x-pack/plugins/osquery/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export const DEFAULT_MAX_TABLE_QUERY_SIZE = 10000;
export const DEFAULT_DARK_MODE = 'theme:darkMode';
export const OSQUERY_INTEGRATION_NAME = 'osquery_manager';
export const BASE_PATH = '/app/osquery';
export const ACTIONS_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.actions`;

export const OSQUERY_LOGS_BASE = `.logs-${OSQUERY_INTEGRATION_NAME}`;
export const ACTIONS_INDEX = `${OSQUERY_LOGS_BASE}.actions`;
export const RESULTS_INDEX = `${OSQUERY_LOGS_BASE}.results`;
export const OSQUERY_ACTIONS_INDEX = `${ACTIONS_INDEX}-*`;

export const ACTION_RESPONSES_INDEX = `.logs-${OSQUERY_INTEGRATION_NAME}.action.responses`;

export const DEFAULT_PLATFORM = 'linux,windows,darwin';
Expand Down
26 changes: 26 additions & 0 deletions x-pack/plugins/osquery/common/types/osquery_action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 interface LogsOsqueryAction {
'@timestamp': string;
action_id: string;
alert_ids: string[];
expiration: string;
input_type: 'osquery';
queries: Array<{
action_id: string;
id: string;
query: string;
agents: string[];
ecs_mapping?: unknown;
version?: string;
platform?: string;
saved_query_id?: string;
expiration?: string;
}>;
type: 'INPUT_ACTION';
}
7 changes: 7 additions & 0 deletions x-pack/plugins/osquery/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Storage } from '@kbn/kibana-utils-plugin/public';
import { useAllLiveQueries } from './actions/use_all_live_queries';
import { getLazyOsqueryResponseActionTypeForm } from './shared_components/lazy_osquery_action_params_form';
import { useFetchStatus } from './fleet_integration/use_fetch_status';
import { getLazyOsqueryResult } from './shared_components/lazy_osquery_result';
import { getLazyOsqueryResults } from './shared_components/lazy_osquery_results';
import type {
OsqueryPluginSetup,
Expand Down Expand Up @@ -122,6 +123,12 @@ export class OsqueryPlugin implements Plugin<OsqueryPluginSetup, OsqueryPluginSt
...core,
...plugins,
}),
OsqueryResult: getLazyOsqueryResult({
...core,
...plugins,
storage: this.storage,
kibanaVersion: this.kibanaVersion,
}),
OsqueryResults: getLazyOsqueryResults({
...core,
...plugins,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 React from 'react';
import { EuiCode, EuiEmptyPrompt } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { PERMISSION_DENIED } from '../../shared_components/osquery_action/translations';

const EmptyPromptComponent = () => (
<EuiEmptyPrompt
iconType="logoOsquery"
title={<h2>{PERMISSION_DENIED}</h2>}
titleSize="xs"
body={
<FormattedMessage
id="xpack.osquery.results.permissionDenied"
defaultMessage="To access these results, ask your administrator for {osquery} Kibana
privileges."
// eslint-disable-next-line react-perf/jsx-no-new-object-as-prop
values={{
osquery: <EuiCode>osquery</EuiCode>,
}}
/>
}
/>
);

export const EmptyPrompt = React.memo(EmptyPromptComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@
*/

import React, { lazy, Suspense } from 'react';
import { EuiCode, EuiEmptyPrompt } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { OsqueryIcon } from '../../components/osquery_icon';
import { useKibana } from '../../common/lib/kibana';
import type { ServicesWrapperProps } from '../services_wrapper';
import ServicesWrapper from '../services_wrapper';
import { PERMISSION_DENIED } from '../osquery_action/translations';
import { EmptyPrompt } from '../../routes/components/empty_prompt';

export interface IExternalReferenceMetaDataProps {
externalReferenceMetadata: {
Expand All @@ -35,24 +32,7 @@ export const getLazyExternalContent =
} = useKibana();

if (!osquery.read) {
return (
<EuiEmptyPrompt
icon={<OsqueryIcon />}
title={<h2>{PERMISSION_DENIED}</h2>}
titleSize="xs"
body={
<FormattedMessage
id="xpack.osquery.cases.permissionDenied"
defaultMessage=" To access these results, ask your administrator for {osquery} Kibana
privileges."
// eslint-disable-next-line react-perf/jsx-no-new-object-as-prop
values={{
osquery: <EuiCode>osquery</EuiCode>,
}}
/>
}
/>
);
return <EmptyPrompt />;
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

export { getLazyOsqueryResult } from './lazy_osquery_result';
export { getLazyOsqueryResults } from './lazy_osquery_results';
export { getLazyOsqueryAction } from './lazy_osquery_action';
export { getLazyLiveQueryField } from './lazy_live_query_field';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 React, { lazy, Suspense } from 'react';
import type { OsqueryActionResultProps } from './osquery_results/types';
import type { StartServices } from '../types';

interface BigServices extends StartServices {
kibanaVersion: string;
storage: unknown;
}

const OsqueryResult = lazy(() => import('./osquery_results/osquery_result_wrapper'));

export const getLazyOsqueryResult =
// eslint-disable-next-line react/display-name
(services: BigServices) => (props: OsqueryActionResultProps) =>
(
<Suspense fallback={null}>
<OsqueryResult services={services} {...props} />
</Suspense>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
);
);
getLazyOsqueryResult.displayName = 'LazyOsQueryResult';

Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
*/

import React, { lazy, Suspense } from 'react';
import type { OsqueryActionResultsProps } from './osquery_results/types';
import type { StartServices } from '../types';
import type { OsqueryActionResultsProps } from './osquery_results/types';

interface BigServices extends StartServices {
kibanaVersion: string;
storage: unknown;
}

const OsqueryResults = lazy(() => import('./osquery_results'));
const OsqueryResults = lazy(() => import('./osquery_results/osquery_results'));

export const getLazyOsqueryResults =
// eslint-disable-next-line react/display-name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { queryClient } from '../../query_client';
import { useKibana } from '../../common/lib/kibana';
import * as useLiveQueryDetails from '../../actions/use_live_query_details';
import { PERMISSION_DENIED } from '../osquery_action/translations';
import { OsqueryResult } from './osquery_result';
import { OsqueryActionResult } from './osquery_result_wrapper';
import {
defaultLiveQueryDetails,
DETAILS_ID,
Expand All @@ -29,6 +29,7 @@ const useKibanaMock = useKibana as jest.MockedFunction<typeof useKibana>;

const defaultPermissions = {
osquery: {
read: true,
runSavedQueries: true,
readSavedQueries: true,
},
Expand Down Expand Up @@ -67,7 +68,7 @@ describe('Osquery Results', () => {

it('return results table', async () => {
const { getByText, queryByText, getByTestId } = renderWithContext(
<OsqueryResult {...defaultProps} />
<OsqueryActionResult {...defaultProps} />
);
expect(queryByText(PERMISSION_DENIED)).not.toBeInTheDocument();
expect(getByTestId('osquery-results-comment'));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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 { EuiComment, EuiErrorBoundary, EuiSpacer } from '@elastic/eui';
import React, { useState, useEffect } from 'react';
import { FormattedRelative } from '@kbn/i18n-react';

import type { CoreStart } from '@kbn/core-lifecycle-browser';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { QueryClientProvider } from '@tanstack/react-query';
import { EmptyPrompt } from '../../routes/components/empty_prompt';
import { useKibana } from '../../common/lib/kibana';
import type { StartPlugins } from '../../types';
import { queryClient } from '../../query_client';
import { AlertAttachmentContext } from '../../common/contexts';
import { PackQueriesStatusTable } from '../../live_queries/form/pack_queries_status_table';
import { ATTACHED_QUERY } from '../../agents/translations';
import { useLiveQueryDetails } from '../../actions/use_live_query_details';
import type { OsqueryActionResultProps } from './types';

const OsqueryResultComponent = React.memo<OsqueryActionResultProps>(
({ actionId, ruleName, startDate, ecsData }) => {
const { read } = useKibana().services.application.capabilities.osquery;

const [isLive, setIsLive] = useState(false);
const { data } = useLiveQueryDetails({
actionId,
isLive,
skip: !read,
});

useEffect(() => {
setIsLive(() => !(data?.status === 'completed'));
}, [data?.status]);

return (
<AlertAttachmentContext.Provider value={ecsData}>
<EuiSpacer size="s" />
<EuiComment
username={ruleName && ruleName[0]}
timestamp={<FormattedRelative value={startDate} />}
event={ATTACHED_QUERY}
data-test-subj={'osquery-results-comment'}
>
{!read ? (
<EmptyPrompt />
) : (
<PackQueriesStatusTable
actionId={actionId}
data={data?.queries}
startDate={data?.['@timestamp']}
expirationDate={data?.expiration}
agentIds={data?.agents}
/>
)}
</EuiComment>
<EuiSpacer size="s" />
</AlertAttachmentContext.Provider>
);
}
);

export const OsqueryActionResult = React.memo(OsqueryResultComponent);
type OsqueryActionResultsWrapperProps = {
services: CoreStart & StartPlugins;
} & OsqueryActionResultProps;

const OsqueryActionResultWrapperComponent: React.FC<OsqueryActionResultsWrapperProps> = ({
services,
...restProps
}) => (
<KibanaThemeProvider theme$={services.theme.theme$}>
<KibanaContextProvider services={services}>
<EuiErrorBoundary>
<QueryClientProvider client={queryClient}>
<OsqueryActionResult {...restProps} />
</QueryClientProvider>
</EuiErrorBoundary>
</KibanaContextProvider>
</KibanaThemeProvider>
);

const OsqueryActionResultWrapper = React.memo(OsqueryActionResultWrapperComponent);

// eslint-disable-next-line import/no-default-export
export { OsqueryActionResultWrapper as default };
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import { render } from '@testing-library/react';
import { QueryClientProvider } from '@tanstack/react-query';

import { OsqueryActionResults } from '.';
import { OsqueryActionResults } from './osquery_results';
import { queryClient } from '../../query_client';
import { useKibana } from '../../common/lib/kibana';
import * as useLiveQueryDetails from '../../actions/use_live_query_details';
Expand Down Expand Up @@ -52,6 +52,7 @@ const defaultProps: OsqueryActionResultsProps = {

const defaultPermissions = {
osquery: {
read: true,
runSavedQueries: false,
readSavedQueries: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import React from 'react';
import { QueryClientProvider } from '@tanstack/react-query';
import type { CoreStart } from '@kbn/core/public';

import { KibanaContextProvider } from '../../common/lib/kibana';
import { EmptyPrompt } from '../../routes/components/empty_prompt';
import { KibanaContextProvider, useKibana } from '../../common/lib/kibana';

import { queryClient } from '../../query_client';
import { KibanaThemeProvider } from '../../shared_imports';
Expand All @@ -22,27 +23,33 @@ const OsqueryActionResultsComponent: React.FC<OsqueryActionResultsProps> = ({
ruleName,
actionItems,
ecsData,
}) => (
<div data-test-subj={'osquery-results'}>
{actionItems?.map((item) => {
const actionId = item.fields?.action_id?.[0];
const queryId = item.fields?.['queries.action_id']?.[0];
const startDate = item.fields?.['@timestamp'][0];
}) => {
const { read } = useKibana().services.application.capabilities.osquery;

return (
<OsqueryResult
key={actionId}
actionId={actionId}
queryId={queryId}
startDate={startDate}
ruleName={ruleName}
ecsData={ecsData}
/>
);
})}
<EuiSpacer size="s" />
</div>
);
return !read ? (
<EmptyPrompt />
) : (
<div data-test-subj={'osquery-results'}>
{actionItems?.map((item) => {
const actionId = item.fields?.action_id?.[0];
const queryId = item.fields?.['queries.action_id']?.[0];
const startDate = item.fields?.['@timestamp'][0];

return (
<OsqueryResult
key={actionId}
actionId={actionId}
queryId={queryId}
startDate={startDate}
ruleName={ruleName}
ecsData={ecsData}
/>
);
})}
<EuiSpacer size="s" />
</div>
);
};

export const OsqueryActionResults = React.memo(OsqueryActionResultsComponent);

Expand Down
Loading