Skip to content

Commit

Permalink
added back graph vis in flyout experimental feature
Browse files Browse the repository at this point in the history
  • Loading branch information
kfirpeled committed Dec 10, 2024
1 parent dc5bb1c commit 1f0bcec
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42544,6 +42544,7 @@
"xpack.securitySolution.uiSettings.enableCcsWarningDescription": "<p>Active les avertissements de vérification des privilèges dans les règles relatives aux index CCS</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedDescription": "<p>Active le fil d'actualités</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedLabel": "Fil d'actualités",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutDescription": "<em>[version d'évaluation technique]</em> Activez les visualisations (analyseur et visualiseur de session) dans le menu volant.",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutLabel": "Activer les visualisations dans le menu volant",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "Exclure les niveaux froids de l'analyseur",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "<p>Lorsque cette option est activée, les niveaux \"cold\" et \"frozen\" sont ignorés dans les requêtes de l'analyseur</p>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42402,6 +42402,7 @@
"xpack.securitySolution.uiSettings.enableCcsWarningDescription": "<p>CCSインデックスのルールで権限チェック警告を有効にします</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedDescription": "<p>ニュースフィードを有効にします</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedLabel": "ニュースフィード",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutDescription": "<em>[テクニカルプレビュー]</em>フライアウトで視覚化(アナライザーとセッションビューアー)を有効にします。",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutLabel": "フライアウトでビジュアライゼーションを有効化",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "アナライザーでコールドティアとフローズンティアを除外",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "<p>有効にすると、アナライザークエリーでコールドティアとフローズンティアがスキップされます</p>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41786,6 +41786,7 @@
"xpack.securitySolution.uiSettings.enableCcsWarningDescription": "<p>在规则中为 CCS 索引启用权限检查警告</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedDescription": "<p>启用新闻源</p>",
"xpack.securitySolution.uiSettings.enableNewsFeedLabel": "新闻源",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutDescription": "<em>[技术预览]</em> 在浮出控件中启用可视化(分析器和会话查看器)。",
"xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutLabel": "在浮出控件中启用可视化",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzer": "在分析器中排除冷层和冻结层",
"xpack.securitySolution.uiSettings.excludeColdAndFrozenTiersInAnalyzerDescription": "<p>启用后,将在分析器查询中跳过冷层和冻结层</p>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@ export const defineGraphRoute = (router: CspRouter) =>
},
async (context: CspRequestHandlerContext, request, response) => {
const cspContext = await context.csp;
const isGraphEnabled = await (
await context.core
).uiSettings.client.get(ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING);

cspContext.logger.debug(`isGraphEnabled: ${isGraphEnabled}`);

if (!isGraphEnabled) {
return response.notFound();
}

const { nodesLimit, showUnknownTarget = false } = request.body;
const { eventIds, start, end, esQuery } = request.body.query as GraphRequest['query'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ export const allowedExperimentalValues = Object.freeze({
*/
analyzerDatePickersAndSourcererDisabled: false,

/**
* Enables graph visualization in alerts flyout
*/
graphVisualizationInFlyoutEnabled: false,

/**
* Enables an ability to customize Elastic prebuilt rules.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { EuiButtonGroupOptionProps } from '@elastic/eui/src/components/butt
import { useExpandableFlyoutApi, useExpandableFlyoutState } from '@kbn/expandable-flyout';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { useDocumentDetailsContext } from '../../shared/context';
import { useWhichFlyout } from '../../shared/hooks/use_which_flyout';
import {
Expand All @@ -33,6 +34,7 @@ import { ALERTS_ACTIONS } from '../../../../common/lib/apm/user_actions';
import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction';
import { GraphVisualization } from '../components/graph_visualization';
import { useGraphPreview } from '../../shared/hooks/use_graph_preview';
import { GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE } from '../../shared/constants/experimental_features';

const visualizeButtons: EuiButtonGroupOptionProps[] = [
{
Expand Down Expand Up @@ -121,14 +123,18 @@ export const VisualizeTab = memo(() => {
}, [panels.left?.path?.subTab]);

// Decide whether to show the graph preview or not
const { isAuditLog: isGraphPreviewEnabled } = useGraphPreview({
const { isAuditLog } = useGraphPreview({
getFieldsData,
ecsData: dataAsNestedObject,
});

const isGraphFeatureEnabled = useIsExperimentalFeatureEnabled(
GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE
);

const options = [...visualizeButtons];

if (isGraphPreviewEnabled) {
if (isAuditLog && isGraphFeatureEnabled) {
options.push(graphVisualizationButton);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID,
EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID,
} from '../../../shared/components/test_ids';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';

const mockUseUiSetting = jest.fn().mockReturnValue([true]);
jest.mock('@kbn/kibana-react-plugin/public', () => {
Expand All @@ -31,6 +32,12 @@ jest.mock('@kbn/kibana-react-plugin/public', () => {
};
});

jest.mock('../../../../common/hooks/use_experimental_features', () => ({
useIsExperimentalFeatureEnabled: jest.fn(),
}));

const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock;

jest.mock('../../shared/hooks/use_graph_preview');
jest.mock('@kbn/cloud-security-posture-graph/src/hooks', () => ({
useFetchGraphData: jest.fn(),
Expand Down Expand Up @@ -58,6 +65,7 @@ describe('<GraphPreviewContainer />', () => {
});

it('should render component and link in header', async () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
mockUseFetchGraphData.mockReturnValue({
isLoading: false,
isError: false,
Expand Down Expand Up @@ -108,6 +116,7 @@ describe('<GraphPreviewContainer />', () => {
});

it('should render component and without link in header in preview panel', async () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
mockUseFetchGraphData.mockReturnValue({
isLoading: false,
isError: false,
Expand Down Expand Up @@ -161,6 +170,7 @@ describe('<GraphPreviewContainer />', () => {
});

it('should render component and without link in header in rule preview', async () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
mockUseFetchGraphData.mockReturnValue({
isLoading: false,
isError: false,
Expand Down Expand Up @@ -213,7 +223,8 @@ describe('<GraphPreviewContainer />', () => {
});
});

it('should not render when feature is not enabled', () => {
it('should not render when flyout feature is not enabled', () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
mockUseUiSetting.mockReturnValue([false]);

mockUseFetchGraphData.mockReturnValue({
Expand All @@ -233,7 +244,29 @@ describe('<GraphPreviewContainer />', () => {
).not.toBeInTheDocument();
});

it('should not render when experimental feature is not enabled', () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(false);
mockUseUiSetting.mockReturnValue([true]);

mockUseFetchGraphData.mockReturnValue({
isLoading: false,
isError: false,
data: undefined,
});

(useGraphPreview as jest.Mock).mockReturnValue({
isAuditLog: true,
});

const { queryByTestId } = renderGraphPreview();

expect(
queryByTestId(EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID(GRAPH_PREVIEW_TEST_ID))
).not.toBeInTheDocument();
});

it('should not render when graph data is not available', () => {
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);
mockUseFetchGraphData.mockReturnValue({
isLoading: false,
isError: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import { useUiSetting$ } from '@kbn/kibana-react-plugin/public';
import { EuiBetaBadge } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useFetchGraphData } from '@kbn/cloud-security-posture-graph/src/hooks';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING } from '../../../../../common/constants';
import { useDocumentDetailsContext } from '../../shared/context';
import { GRAPH_PREVIEW_TEST_ID } from './test_ids';
import { GraphPreview } from './graph_preview';
import { useGraphPreview } from '../../shared/hooks/use_graph_preview';
import { useNavigateToGraphVisualization } from '../../shared/hooks/use_navigate_to_graph_visualization';
import { ExpandablePanel } from '../../../shared/components/expandable_panel';
import { GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE } from '../../shared/constants/experimental_features';

/**
* Graph preview under Overview, Visualizations. It shows a graph representation of entities.
Expand All @@ -36,6 +38,9 @@ export const GraphPreviewContainer: React.FC = () => {
const [visualizationInFlyoutEnabled] = useUiSetting$<boolean>(
ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING
);
const isGraphFeatureEnabled = useIsExperimentalFeatureEnabled(
GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE
);

const allowFlyoutExpansion = !isPreviewMode && !isPreview;

Expand All @@ -55,6 +60,9 @@ export const GraphPreviewContainer: React.FC = () => {
ecsData: dataAsNestedObject,
});

const shouldShowGraphPreview =
visualizationInFlyoutEnabled && isGraphFeatureEnabled && isAuditLog;

// TODO: default start and end might not capture the original event
const { isLoading, isError, data } = useFetchGraphData({
req: {
Expand All @@ -71,8 +79,7 @@ export const GraphPreviewContainer: React.FC = () => {
});

return (
isAuditLog &&
visualizationInFlyoutEnabled && (
shouldShowGraphPreview && (
<ExpandablePanel
header={{
title: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { useExpandSection } from '../hooks/use_expand_section';
import { useInvestigateInTimeline } from '../../../../detections/components/alerts_table/timeline_actions/use_investigate_in_timeline';
import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
import { useGraphPreview } from '../../shared/hooks/use_graph_preview';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';

jest.mock('../hooks/use_expand_section');
jest.mock('../../shared/hooks/use_alert_prevalence_from_process_tree', () => ({
Expand All @@ -53,6 +54,12 @@ jest.mock(
'../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver'
);

jest.mock('../../../../common/hooks/use_experimental_features', () => ({
useIsExperimentalFeatureEnabled: jest.fn(),
}));

const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock;

const mockUseUiSetting = jest.fn().mockReturnValue([false]);
jest.mock('@kbn/kibana-react-plugin/public', () => {
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
Expand Down Expand Up @@ -132,6 +139,7 @@ describe('<VisualizationsSection />', () => {
(useIsInvestigateInResolverActionEnabled as jest.Mock).mockReturnValue(true);
(useExpandSection as jest.Mock).mockReturnValue(true);
mockUseUiSetting.mockReturnValue([false]);
useIsExperimentalFeatureEnabledMock.mockReturnValue(false);

const { getByTestId, queryByTestId } = renderVisualizationsSection();
expect(getByTestId(VISUALIZATIONS_SECTION_CONTENT_TEST_ID)).toBeVisible();
Expand All @@ -144,9 +152,30 @@ describe('<VisualizationsSection />', () => {
it('should render the graph preview component if the feature is enabled', () => {
(useExpandSection as jest.Mock).mockReturnValue(true);
mockUseUiSetting.mockReturnValue([true]);
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);

const { getByTestId } = renderVisualizationsSection();

expect(getByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).toBeInTheDocument();
});

it('should not render the graph preview component if the experimental feature is disabled', () => {
(useExpandSection as jest.Mock).mockReturnValue(true);
mockUseUiSetting.mockReturnValue([true]);
useIsExperimentalFeatureEnabledMock.mockReturnValue(false);

const { queryByTestId } = renderVisualizationsSection();

expect(queryByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).not.toBeInTheDocument();
});

it('should not render the graph preview component if the flyout feature is disabled', () => {
(useExpandSection as jest.Mock).mockReturnValue(true);
mockUseUiSetting.mockReturnValue([false]);
useIsExperimentalFeatureEnabledMock.mockReturnValue(true);

const { queryByTestId } = renderVisualizationsSection();

expect(queryByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import { VISUALIZATIONS_TEST_ID } from './test_ids';
import { GraphPreviewContainer } from './graph_preview_container';
import { useDocumentDetailsContext } from '../../shared/context';
import { useGraphPreview } from '../../shared/hooks/use_graph_preview';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING } from '../../../../../common/constants';
import { GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE } from '../../shared/constants/experimental_features';

const KEY = 'visualizations';

Expand All @@ -32,12 +34,19 @@ export const VisualizationsSection = memo(() => {
ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING
);

const isGraphFeatureEnabled = useIsExperimentalFeatureEnabled(
GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE
);

// Decide whether to show the graph preview or not
const { isAuditLog: isGraphPreviewEnabled } = useGraphPreview({
const { isAuditLog } = useGraphPreview({
getFieldsData,
ecsData: dataAsNestedObject,
});

const shouldShowGraphPreview =
visualizationInFlyoutEnabled && isGraphFeatureEnabled && isAuditLog;

return (
<ExpandableSection
expanded={expanded}
Expand All @@ -53,7 +62,7 @@ export const VisualizationsSection = memo(() => {
<SessionPreviewContainer />
<EuiSpacer />
<AnalyzerPreviewContainer />
{visualizationInFlyoutEnabled && isGraphPreviewEnabled && (
{shouldShowGraphPreview && (
<>
<EuiSpacer />
<GraphPreviewContainer />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

/** This security solution experimental feature allows user to enable/disable the graph visualization in Flyout feature (depends on securitySolution:enableVisualizationsInFlyout) */
export const GRAPH_VISUALIZATION_IN_FLYOUT_ENABLED_EXPERIMENTAL_FEATURE =
'graphVisualizationInFlyoutEnabled' as const;
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/server/ui_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export const initUiSettings = (
'xpack.securitySolution.uiSettings.enableVisualizationsInFlyoutDescription',
{
defaultMessage:
'<em>[technical preview]</em> Enable visualizations (analyzer, session viewer, and graph view) in flyout.',
'<em>[technical preview]</em> Enable visualizations (analyzer and session viewer) in flyout.',
values: { em: (chunks) => `<em>${chunks}</em>` },
}
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
...baseConfig.get('kbnTestServer'),
serverArgs: [
...baseConfig.get('kbnTestServer.serverArgs'),
`--uiSettings.overrides.securitySolution:enableVisualizationsInFlyout=false`, // Disables /graph API
`--logging.loggers=${JSON.stringify([
...getKibanaCliLoggers(baseConfig.get('kbnTestServer.serverArgs')),
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export default function (providerContext: FtrProviderContext) {
};

describe('POST /internal/cloud_security_posture/graph', () => {
describe('Feature flag', () => {
// TODO: fix once feature flag is enabled for the API
describe.skip('Feature flag', () => {
it('should return 404 when feature flag is not toggled', async () => {
await postGraph(supertest, {
query: {
Expand Down
1 change: 0 additions & 1 deletion x-pack/test/cloud_security_posture_api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
* 1. release a new package to EPR
* 2. merge the updated version number change to kibana
*/
`--uiSettings.overrides.securitySolution:enableVisualizationsInFlyout=true`, // Enables /graph API
`--xpack.fleet.packages.0.name=cloud_security_posture`,
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
// `--xpack.fleet.registryUrl=https://localhost:8080`,
Expand Down
3 changes: 3 additions & 0 deletions x-pack/test/cloud_security_posture_functional/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
* 2. merge the updated version number change to kibana
*/
`--uiSettings.overrides.securitySolution:enableVisualizationsInFlyout=true`,
`--xpack.securitySolution.enableExperimental=${JSON.stringify([
'graphVisualizationInFlyoutEnabled',
])}`,
`--xpack.fleet.packages.0.name=cloud_security_posture`,
`--xpack.fleet.packages.0.version=${CLOUD_SECURITY_PLUGIN_VERSION}`,
// `--xpack.fleet.registryUrl=https://localhost:8080`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,5 @@ export default createTestConfig({
'--xpack.dataUsage.autoops.api.url=http://localhost:9000',
`--xpack.dataUsage.autoops.api.tls.certificate=${KBN_CERT_PATH}`,
`--xpack.dataUsage.autoops.api.tls.key=${KBN_KEY_PATH}`,

`--uiSettings.overrides.securitySolution:enableVisualizationsInFlyout=true`, // Enables /graph API
],
});

0 comments on commit 1f0bcec

Please sign in to comment.