mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[SECURITY_SOLUTION] list UI is backwards compatible (#77956)
This commit is contained in:
parent
05df9efc91
commit
b778e9c0a9
8 changed files with 86 additions and 29 deletions
|
@ -58,6 +58,7 @@ describe('EndpointList store concerns', () => {
|
|||
patternsError: undefined,
|
||||
isAutoRefreshEnabled: true,
|
||||
autoRefreshInterval: DEFAULT_POLL_INTERVAL,
|
||||
queryStrategyVersion: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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<EndpointState
|
|||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
let endpointResponse;
|
||||
|
||||
// get index pattern and fields for search bar
|
||||
if (patterns(getState()).length === 0) {
|
||||
try {
|
||||
const indexPatterns = await fetchIndexPatterns();
|
||||
if (indexPatterns !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedMetadataPatterns',
|
||||
payload: indexPatterns,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnMetadataPatterns',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const decodedQuery: Query = searchBarQuery(getState());
|
||||
|
||||
|
@ -134,6 +117,24 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
|
|||
});
|
||||
}
|
||||
|
||||
// get index pattern and fields for search bar
|
||||
if (patterns(getState()).length === 0 && isTransformEnabled(getState())) {
|
||||
try {
|
||||
const indexPatterns = await fetchIndexPatterns();
|
||||
if (indexPatterns !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedMetadataPatterns',
|
||||
payload: indexPatterns,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnMetadataPatterns',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// No endpoints, so we should check to see if there are policies for onboarding
|
||||
if (endpointResponse && endpointResponse.hosts.length === 0) {
|
||||
const http = coreStart.http;
|
||||
|
|
|
@ -32,11 +32,13 @@ export const mockEndpointResultList: (options?: {
|
|||
total?: number;
|
||||
request_page_size?: number;
|
||||
request_page_index?: number;
|
||||
query_strategy_version?: MetadataQueryStrategyVersions;
|
||||
}) => 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<typeof endpointListApiPathHandlerMocks>[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
|
||||
|
|
|
@ -36,6 +36,7 @@ export const initialEndpointListState: Immutable<EndpointState> = {
|
|||
patternsError: undefined,
|
||||
isAutoRefreshEnabled: true,
|
||||
autoRefreshInterval: DEFAULT_POLL_INTERVAL,
|
||||
queryStrategyVersion: undefined,
|
||||
};
|
||||
|
||||
/* eslint-disable-next-line complexity */
|
||||
|
@ -49,6 +50,7 @@ export const endpointListReducer: ImmutableReducer<EndpointState, AppAction> = (
|
|||
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<EndpointState, AppAction> = (
|
|||
total,
|
||||
pageSize,
|
||||
pageIndex,
|
||||
queryStrategyVersion,
|
||||
loading: false,
|
||||
error: undefined,
|
||||
};
|
||||
|
|
|
@ -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<EndpointState>) => state.i
|
|||
|
||||
export const autoRefreshInterval = (state: Immutable<EndpointState>) => state.autoRefreshInterval;
|
||||
|
||||
const queryStrategyVersion = (state: Immutable<EndpointState>) => 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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<ReturnType<AppContextTestRender['render']>>;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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 (
|
||||
<AdministrationListPage
|
||||
data-test-subj="endpointPage"
|
||||
|
@ -563,7 +568,7 @@ export const EndpointList = () => {
|
|||
{hasSelectedEndpoint && <EndpointDetailsFlyout />}
|
||||
<>
|
||||
<EuiFlexGroup>
|
||||
{endpointsExist && !patternsError && (
|
||||
{shouldShowKQLBar && (
|
||||
<EuiFlexItem>
|
||||
<AdminSearchBar />
|
||||
</EuiFlexItem>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue