From 1e5c067039fb4747f3a0e618247e6d7798bcb981 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Tue, 2 Jan 2024 17:53:12 +0100 Subject: [PATCH 1/3] [Security Solution] Adds feature flag to enable/disable ESQL in timeline (#174029) ## Summary This PR introduces a feature flag `timelineEsqlTabDisabled` which is by default `false`. This gives customer ability to disable the esql tab by enabling this experimental feature flag as below in `kibana.yml` ```yaml xpack.securitySolution.enableExperimental: - timelineEsqlTabDisabled ``` The availability of ESQL Tab in timeline also affects `AI Assistant` as it facilities re-directing user to timeline with an esql query. That `redirect` button should not be available for `esql` query if ESQL Tab is disabled. ## Desk Testing 1. ESQL Tab Presence - timelineEsqlTabDisabled : true - If Tab is disabled, `ESQL` Tab should not show when timeline is open. Timeline should also not fire any `bsearch` requests with `esql` strategy. - ESQL tab is enabled i.e. `timelineEsqlTabDisabled : true` is present in kibana.dev.yml - User should be able to use ESQL queries without any issue. Below should be the default query in both `8.12` and `8.11.4` ```esql from .alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,traces-apm*,winlogbeat-*,-*elastic-cloud-logs-* | limit 10 | keep @timestamp, message, event.category, event.action, host.name, source.ip, destination.ip, user.name ``` 2. Open ESQL Tab from URL 1. Enable ESQL tab and Activate it when in timeline 2. Now change `kibana.dev.yml` to add experimental flag `timelineEsqlTabDisabled` to disable ESQL Tab. 3. Restart kibana server 4. Refresh the page in step 1 where `ESQL` tab was active 5. User should automatically be redirected to `Query` tab. 3. AI Assistant Today AI Assistant can help user add an ESQL query to the timeline as shown in below video. We need to make sure that `Send to timeline` button is not available only for `esql` queries when above experimental flag is enabled. https://github.com/elastic/kibana/assets/7485038/e452a6c6-cf97-462e-a5dc-bd8c0fd38d58 --------- Co-authored-by: Gloria Hornero Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> (cherry picked from commit da0370eafb49f15fe655d0e2b8d254e09c9f814a) # Conflicts: # x-pack/plugins/security_solution/common/experimental_features.ts # x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx --- .../common/experimental_features.ts | 6 ++ .../assistant/send_to_timeline/index.tsx | 10 +++ .../timeline/use_init_timeline_url_param.ts | 11 +++- .../timeline/tabs_content/index.tsx | 61 +++++++++++-------- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 90346011c23e5..c1612e0469a98 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -113,6 +113,12 @@ export const allowedExperimentalValues = Object.freeze({ * Enables Protection Updates tab in the Endpoint Policy Details page */ protectionUpdatesEnabled: true, + + /* + * Disables discover esql tab within timeline + * + */ + timelineEsqlTabDisabled: false, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx index 114d5deb5f3ec..b544e6f90e52a 100644 --- a/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/send_to_timeline/index.tsx @@ -36,6 +36,7 @@ import { } from '../../timelines/store/timeline/actions'; import { useDiscoverInTimelineContext } from '../../common/components/discover_in_timeline/use_discover_in_timeline_context'; import { useShowTimeline } from '../../common/utils/timeline/use_show_timeline'; +import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; export interface SendToTimelineButtonProps { asEmptyButton: boolean; @@ -60,6 +61,8 @@ export const SendToTimelineButton: React.FunctionComponent sourcererSelectors.getSourcererDataViewsSelector(), [] @@ -226,6 +229,13 @@ export const SendToTimelineButton: React.FunctionComponent { const dispatch = useDispatch(); + const isEsqlTabDisabled = useIsExperimentalFeatureEnabled('timelineEsqlTabDisabled'); + const onInitialize = useCallback( (initialState: TimelineUrl | null) => { if (initialState != null) { queryTimelineById({ - activeTimelineTab: initialState.activeTab, + activeTimelineTab: + initialState.activeTab === TimelineTabs.esql && isEsqlTabDisabled + ? TimelineTabs.query + : initialState.activeTab, duplicate: false, graphEventId: initialState.graphEventId, timelineId: initialState.id, @@ -37,7 +44,7 @@ export const useInitTimelineFromUrlParam = () => { }); } }, - [dispatch] + [dispatch, isEsqlTabDisabled] ); useInitializeUrlParam(URL_PARAM_KEY.timeline, onInitialize); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx index 88eeea3a7df9e..efeb2641cba3a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx @@ -15,6 +15,8 @@ import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { useKibana } from '../../../../common/lib/kibana'; import { useAssistantTelemetry } from '../../../../assistant/use_assistant_telemetry'; import { useConversationStore } from '../../../../assistant/use_conversation_store'; import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability'; @@ -132,6 +134,7 @@ const ActiveTimelineTab = memo( setConversationId, showTimeline, }) => { + const isEsqlSettingEnabled = useKibana().services.configSettings.ESQLEnabled; const { hasAssistantPrivilege } = useAssistantAvailability(); const getTab = useCallback( (tab: TimelineTabs) => { @@ -179,12 +182,14 @@ const ActiveTimelineTab = memo( timelineId={timelineId} /> - - - + {showTimeline && isEsqlSettingEnabled && activeTimelineTab === TimelineTabs.esql && ( + + + + )} = ({ sessionViewConfig, timelineDescription, }) => { + const isEsqlTabInTimelineDisabled = useIsExperimentalFeatureEnabled('timelineEsqlTabDisabled'); + const isEsqlSettingEnabled = useKibana().services.configSettings.ESQLEnabled; const { hasAssistantPrivilege } = useAssistantAvailability(); const dispatch = useDispatch(); const getActiveTab = useMemo(() => getActiveTabSelector(), []); @@ -394,26 +401,28 @@ const TabsContentComponent: React.FC = ({ {i18n.QUERY_TAB} {showTimeline && } - - {i18n.DISCOVER_ESQL_IN_TIMELINE_TAB} - - } - /> - + {!isEsqlTabInTimelineDisabled && isEsqlSettingEnabled && ( + + {i18n.DISCOVER_ESQL_IN_TIMELINE_TAB} + + } + /> + + )} {timelineType === TimelineType.default && ( Date: Tue, 2 Jan 2024 11:10:53 -0700 Subject: [PATCH 2/3] Update index.tsx Resolving conflicts as detailed from https://github.com/elastic/kibana/pull/173640 --- .../timelines/components/timeline/tabs_content/index.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx index efeb2641cba3a..b11740ba8960a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx @@ -16,7 +16,6 @@ import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { useKibana } from '../../../../common/lib/kibana'; import { useAssistantTelemetry } from '../../../../assistant/use_assistant_telemetry'; import { useConversationStore } from '../../../../assistant/use_conversation_store'; import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability'; @@ -134,7 +133,6 @@ const ActiveTimelineTab = memo( setConversationId, showTimeline, }) => { - const isEsqlSettingEnabled = useKibana().services.configSettings.ESQLEnabled; const { hasAssistantPrivilege } = useAssistantAvailability(); const getTab = useCallback( (tab: TimelineTabs) => { @@ -182,7 +180,7 @@ const ActiveTimelineTab = memo( timelineId={timelineId} /> - {showTimeline && isEsqlSettingEnabled && activeTimelineTab === TimelineTabs.esql && ( + {showTimeline && activeTimelineTab === TimelineTabs.esql && ( = ({ timelineDescription, }) => { const isEsqlTabInTimelineDisabled = useIsExperimentalFeatureEnabled('timelineEsqlTabDisabled'); - const isEsqlSettingEnabled = useKibana().services.configSettings.ESQLEnabled; const { hasAssistantPrivilege } = useAssistantAvailability(); const dispatch = useDispatch(); const getActiveTab = useMemo(() => getActiveTabSelector(), []); @@ -401,7 +398,7 @@ const TabsContentComponent: React.FC = ({ {i18n.QUERY_TAB} {showTimeline && } - {!isEsqlTabInTimelineDisabled && isEsqlSettingEnabled && ( + {!isEsqlTabInTimelineDisabled && ( Date: Tue, 2 Jan 2024 16:43:49 -0600 Subject: [PATCH 3/3] skip Cypress test (currently skipped in main) --- .../timelines/esql/discover_timeline_state_integration.cy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/esql/discover_timeline_state_integration.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/esql/discover_timeline_state_integration.cy.ts index d1a446df25a5a..16af2800d1054 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/esql/discover_timeline_state_integration.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/esql/discover_timeline_state_integration.cy.ts @@ -60,7 +60,7 @@ const TIMELINE_RESPONSE_SAVED_OBJECT_ID_PATH = 'response.body.data.persistTimeline.timeline.savedObjectId'; const esqlQuery = 'from auditbeat-* | where ecs.version == "8.0.0"'; -describe( +describe.skip( 'Discover Timeline State Integration', { tags: ['@ess', '@brokenInServerless'],