diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts index 4faef85afbdc8..61bcd222b1b1e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts @@ -58,6 +58,7 @@ describe('EndpointList store concerns', () => { patternsError: undefined, isAutoRefreshEnabled: true, autoRefreshInterval: DEFAULT_POLL_INTERVAL, + queryStrategyVersion: undefined, }); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts index 7673702f54370..7872c8824a8ee 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts @@ -17,6 +17,7 @@ import { nonExistingPolicies, patterns, searchBarQuery, + isTransformEnabled, } from './selectors'; import { EndpointState, PolicyIds } from '../types'; import { @@ -70,24 +71,6 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory HostResultList = (options = {}) => { const { total = 1, request_page_size: requestPageSize = 10, request_page_index: requestPageIndex = 0, + query_strategy_version: queryStrategyVersion = MetadataQueryStrategyVersions.VERSION_2, } = options; // Skip any that are before the page we're on @@ -50,7 +52,7 @@ export const mockEndpointResultList: (options?: { hosts.push({ metadata: generator.generateHostMetadata(), host_status: HostStatus.ERROR, - query_strategy_version: MetadataQueryStrategyVersions.VERSION_2, + query_strategy_version: queryStrategyVersion, }); } const mock: HostResultList = { @@ -58,7 +60,7 @@ export const mockEndpointResultList: (options?: { total, request_page_size: requestPageSize, request_page_index: requestPageIndex, - query_strategy_version: MetadataQueryStrategyVersions.VERSION_2, + query_strategy_version: queryStrategyVersion, }; return mock; }; @@ -84,6 +86,7 @@ const endpointListApiPathHandlerMocks = ({ endpointPackagePolicies = [], policyResponse = generator.generatePolicyResponse(), agentPolicy = generator.generateAgentPolicy(), + queryStrategyVersion = MetadataQueryStrategyVersions.VERSION_2, }: { /** route handlers will be setup for each individual host in this array */ endpointsResults?: HostResultList['hosts']; @@ -91,6 +94,7 @@ const endpointListApiPathHandlerMocks = ({ endpointPackagePolicies?: GetPolicyListResponse['items']; policyResponse?: HostPolicyResponse; agentPolicy?: GetAgentPoliciesResponseItem; + queryStrategyVersion?: MetadataQueryStrategyVersions; } = {}) => { const apiHandlers = { // endpoint package info @@ -107,7 +111,7 @@ const endpointListApiPathHandlerMocks = ({ request_page_size: 10, request_page_index: 0, total: endpointsResults?.length || 0, - query_strategy_version: MetadataQueryStrategyVersions.VERSION_2, + query_strategy_version: queryStrategyVersion, }; }, @@ -164,11 +168,16 @@ export const setEndpointListApiMockImplementation: ( apiResponses?: Parameters[0] ) => void = ( mockedHttpService, - { endpointsResults = mockEndpointResultList({ total: 3 }).hosts, ...pathHandlersOptions } = {} + { + endpointsResults = mockEndpointResultList({ total: 3 }).hosts, + queryStrategyVersion = MetadataQueryStrategyVersions.VERSION_2, + ...pathHandlersOptions + } = {} ) => { const apiHandlers = endpointListApiPathHandlerMocks({ ...pathHandlersOptions, endpointsResults, + queryStrategyVersion, }); mockedHttpService.post diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts index 99a1df7eb4002..0f948f74a48e4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts @@ -36,6 +36,7 @@ export const initialEndpointListState: Immutable = { patternsError: undefined, isAutoRefreshEnabled: true, autoRefreshInterval: DEFAULT_POLL_INTERVAL, + queryStrategyVersion: undefined, }; /* eslint-disable-next-line complexity */ @@ -49,6 +50,7 @@ export const endpointListReducer: ImmutableReducer = ( total, request_page_size: pageSize, request_page_index: pageIndex, + query_strategy_version: queryStrategyVersion, } = action.payload; return { ...state, @@ -56,6 +58,7 @@ export const endpointListReducer: ImmutableReducer = ( total, pageSize, pageIndex, + queryStrategyVersion, loading: false, error: undefined, }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts index a3eee8063d6f7..fe47d60afc339 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts @@ -14,6 +14,7 @@ import { HostPolicyResponseAppliedAction, HostPolicyResponseConfiguration, HostPolicyResponseActionStatus, + MetadataQueryStrategyVersions, } from '../../../../../common/endpoint/types'; import { EndpointState, EndpointIndexUIQueryParams } from '../types'; import { extractListPaginationParams } from '../../../common/routing'; @@ -54,11 +55,18 @@ export const isAutoRefreshEnabled = (state: Immutable) => state.i export const autoRefreshInterval = (state: Immutable) => state.autoRefreshInterval; +const queryStrategyVersion = (state: Immutable) => state.queryStrategyVersion; + export const endpointPackageVersion = createSelector( endpointPackageInfo, (info) => info?.version ?? undefined ); +export const isTransformEnabled = createSelector( + queryStrategyVersion, + (version) => version !== MetadataQueryStrategyVersions.VERSION_1 +); + /** * Returns the index patterns for the SearchBar to use for autosuggest */ diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts index 77f21243ea120..bdd0d5e942cef 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts @@ -11,6 +11,7 @@ import { HostPolicyResponse, AppLocation, PolicyData, + MetadataQueryStrategyVersions, } from '../../../../common/endpoint/types'; import { ServerApiError } from '../../../common/types'; import { GetPackagesResponse } from '../../../../../ingest_manager/common'; @@ -65,6 +66,8 @@ export interface EndpointState { isAutoRefreshEnabled: boolean; /** The current auto refresh interval for data in ms */ autoRefreshInterval: number; + /** The query strategy version that informs whether the transform for KQL is enabled or not */ + queryStrategyVersion?: MetadataQueryStrategyVersions; } /** diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index bd8344f41fe3a..51a6be18471aa 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -108,6 +108,31 @@ describe('when on the list page', () => { }); }); + describe('when loading data with the query_strategy_version is `v1`', () => { + beforeEach(() => { + reactTestingLibrary.act(() => { + const mockedEndpointListData = mockEndpointResultList({ + total: 4, + query_strategy_version: MetadataQueryStrategyVersions.VERSION_1, + }); + setEndpointListApiMockImplementation(coreStart.http, { + endpointsResults: mockedEndpointListData.hosts, + queryStrategyVersion: mockedEndpointListData.query_strategy_version, + }); + }); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('should not display the KQL bar', async () => { + const renderResult = render(); + await reactTestingLibrary.act(async () => { + await middlewareSpy.waitForAction('serverReturnedEndpointList'); + }); + expect(renderResult.queryByTestId('adminSearchBar')).toBeNull(); + }); + }); + describe('when there is no selected host in the url', () => { it('should not show the flyout', () => { const renderResult = render(); @@ -123,7 +148,9 @@ describe('when on the list page', () => { let firstPolicyID: string; beforeEach(() => { reactTestingLibrary.act(() => { - const hostListData = mockEndpointResultList({ total: 4 }).hosts; + const mockedEndpointData = mockEndpointResultList({ total: 4 }); + const hostListData = mockedEndpointData.hosts; + const queryStrategyVersion = mockedEndpointData.query_strategy_version; firstPolicyID = hostListData[0].metadata.Endpoint.policy.applied.id; @@ -132,7 +159,7 @@ describe('when on the list page', () => { hostListData[index] = { metadata: hostListData[index].metadata, host_status: status, - query_strategy_version: MetadataQueryStrategyVersions.VERSION_2, + query_strategy_version: queryStrategyVersion, }; } ); @@ -682,11 +709,11 @@ describe('when on the list page', () => { let renderAndWaitForData: () => Promise>; const mockEndpointListApi = () => { - const { hosts } = mockEndpointResultList(); + const { hosts, query_strategy_version: queryStrategyVersion } = mockEndpointResultList(); hostInfo = { host_status: hosts[0].host_status, metadata: hosts[0].metadata, - query_strategy_version: MetadataQueryStrategyVersions.VERSION_2, + query_strategy_version: queryStrategyVersion, }; const packagePolicy = docGenerator.generatePolicyPackagePolicy(); packagePolicy.id = hosts[0].metadata.Endpoint.policy.applied.id; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index ecee2bee0c58b..3e1f08eee7b94 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -135,6 +135,7 @@ export const EndpointList = () => { autoRefreshInterval, isAutoRefreshEnabled, patternsError, + isTransformEnabled, } = useEndpointSelector(selector); const { formatUrl, search } = useFormatUrl(SecurityPageName.administration); @@ -532,8 +533,8 @@ export const EndpointList = () => { const hasListData = listData && listData.length > 0; const refreshStyle = useMemo(() => { - return { display: endpointsExist ? 'flex' : 'none', maxWidth: 200 }; - }, [endpointsExist]); + return { display: endpointsExist && isTransformEnabled ? 'flex' : 'none', maxWidth: 200 }; + }, [endpointsExist, isTransformEnabled]); const refreshIsPaused = useMemo(() => { return !endpointsExist ? false : hasSelectedEndpoint ? true : !isAutoRefreshEnabled; @@ -543,6 +544,10 @@ export const EndpointList = () => { return !endpointsExist ? DEFAULT_POLL_INTERVAL : autoRefreshInterval; }, [endpointsExist, autoRefreshInterval]); + const shouldShowKQLBar = useMemo(() => { + return endpointsExist && !patternsError && isTransformEnabled; + }, [endpointsExist, patternsError, isTransformEnabled]); + return ( { {hasSelectedEndpoint && } <> - {endpointsExist && !patternsError && ( + {shouldShowKQLBar && (