mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Security Solution] throttle package calls on initial security page load (#103570)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
428eba425d
commit
699731f25e
8 changed files with 62 additions and 25 deletions
|
@ -15,7 +15,6 @@ import {
|
|||
} from '../../../../../common/endpoint/types';
|
||||
import { ServerApiError } from '../../../../common/types';
|
||||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
import { GetPackagesResponse } from '../../../../../../fleet/common';
|
||||
import { EndpointIndexUIQueryParams, EndpointState } from '../types';
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/public';
|
||||
|
||||
|
@ -75,10 +74,9 @@ export interface ServerCancelledPolicyItemsLoading {
|
|||
type: 'serverCancelledPolicyItemsLoading';
|
||||
}
|
||||
|
||||
export interface ServerReturnedEndpointPackageInfo {
|
||||
type: 'serverReturnedEndpointPackageInfo';
|
||||
payload: GetPackagesResponse['response'][0];
|
||||
}
|
||||
export type EndpointPackageInfoStateChanged = Action<'endpointPackageInfoStateChanged'> & {
|
||||
payload: EndpointState['endpointPackageInfo'];
|
||||
};
|
||||
|
||||
export interface ServerReturnedEndpointNonExistingPolicies {
|
||||
type: 'serverReturnedEndpointNonExistingPolicies';
|
||||
|
@ -195,7 +193,7 @@ export type EndpointAction =
|
|||
| ServerCancelledEndpointListLoading
|
||||
| ServerReturnedEndpointExistValue
|
||||
| ServerCancelledPolicyItemsLoading
|
||||
| ServerReturnedEndpointPackageInfo
|
||||
| EndpointPackageInfoStateChanged
|
||||
| ServerReturnedMetadataPatterns
|
||||
| ServerFailedToReturnMetadataPatterns
|
||||
| AppRequestedEndpointList
|
||||
|
|
|
@ -41,7 +41,7 @@ export const initialEndpointPageState = (): Immutable<EndpointState> => {
|
|||
policyItems: [],
|
||||
selectedPolicyId: undefined,
|
||||
policyItemsLoading: false,
|
||||
endpointPackageInfo: undefined,
|
||||
endpointPackageInfo: createUninitialisedResourceState(),
|
||||
nonExistingPolicies: {},
|
||||
agentPolicies: {},
|
||||
endpointsExist: true,
|
||||
|
|
|
@ -64,7 +64,9 @@ describe('EndpointList store concerns', () => {
|
|||
policyItems: [],
|
||||
selectedPolicyId: undefined,
|
||||
policyItemsLoading: false,
|
||||
endpointPackageInfo: undefined,
|
||||
endpointPackageInfo: {
|
||||
type: 'UninitialisedResourceState',
|
||||
},
|
||||
nonExistingPolicies: {},
|
||||
agentPolicies: {},
|
||||
endpointsExist: true,
|
||||
|
|
|
@ -36,6 +36,8 @@ import {
|
|||
getLastLoadedActivityLogData,
|
||||
detailsData,
|
||||
getEndpointDetailsFlyoutView,
|
||||
getIsEndpointPackageInfoPending,
|
||||
getIsEndpointPackageInfoSuccessful,
|
||||
} from './selectors';
|
||||
import { AgentIdsPendingActions, EndpointState, PolicyIds } from '../types';
|
||||
import {
|
||||
|
@ -44,7 +46,7 @@ import {
|
|||
sendGetAgentPolicyList,
|
||||
sendGetFleetAgentsWithEndpoint,
|
||||
} from '../../policy/store/services/ingest';
|
||||
import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../../../../../../fleet/common';
|
||||
import { AGENT_POLICY_SAVED_OBJECT_TYPE, PackageListItem } from '../../../../../../fleet/common';
|
||||
import {
|
||||
ENDPOINT_ACTION_LOG_ROUTE,
|
||||
HOST_METADATA_GET_ROUTE,
|
||||
|
@ -61,7 +63,7 @@ import {
|
|||
import { isolateHost, unIsolateHost } from '../../../../common/lib/endpoint_isolation';
|
||||
import { AppAction } from '../../../../common/store/actions';
|
||||
import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables';
|
||||
import { ServerReturnedEndpointPackageInfo } from './action';
|
||||
import { EndpointPackageInfoStateChanged } from './action';
|
||||
import { fetchPendingActionsByAgentId } from '../../../../common/lib/endpoint_pending_actions';
|
||||
import { EndpointDetailsTabsTypes } from '../view/details/components/endpoint_details_tabs';
|
||||
|
||||
|
@ -593,20 +595,31 @@ const handleIsolateEndpointHost = async (
|
|||
|
||||
async function getEndpointPackageInfo(
|
||||
state: ImmutableObject<EndpointState>,
|
||||
dispatch: Dispatch<ServerReturnedEndpointPackageInfo>,
|
||||
dispatch: Dispatch<EndpointPackageInfoStateChanged>,
|
||||
coreStart: CoreStart
|
||||
) {
|
||||
if (endpointPackageInfo(state)) return;
|
||||
if (getIsEndpointPackageInfoPending(state) || getIsEndpointPackageInfoSuccessful(state)) return;
|
||||
|
||||
dispatch({
|
||||
type: 'endpointPackageInfoStateChanged',
|
||||
// Ignore will be fixed with when AsyncResourceState is refactored (#830)
|
||||
// @ts-ignore
|
||||
payload: createLoadingResourceState<PackageListItem>(endpointPackageInfo(state)),
|
||||
});
|
||||
|
||||
try {
|
||||
const packageInfo = await sendGetEndpointSecurityPackage(coreStart.http);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointPackageInfo',
|
||||
payload: packageInfo,
|
||||
type: 'endpointPackageInfoStateChanged',
|
||||
payload: createLoadedResourceState(packageInfo),
|
||||
});
|
||||
} catch (error) {
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
dispatch({
|
||||
type: 'endpointPackageInfoStateChanged',
|
||||
payload: createFailedResourceState(error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EndpointDetailsActivityLogChanged, EndpointPendingActionsStateChanged } from './action';
|
||||
import {
|
||||
EndpointDetailsActivityLogChanged,
|
||||
EndpointPackageInfoStateChanged,
|
||||
EndpointPendingActionsStateChanged,
|
||||
} from './action';
|
||||
import {
|
||||
isOnEndpointPage,
|
||||
hasSelectedEndpoint,
|
||||
|
@ -65,6 +69,16 @@ const handleEndpointPendingActionsStateChanged: CaseReducer<EndpointPendingActio
|
|||
return state;
|
||||
};
|
||||
|
||||
const handleEndpointPackageInfoStateChanged: CaseReducer<EndpointPackageInfoStateChanged> = (
|
||||
state,
|
||||
action
|
||||
) => {
|
||||
return {
|
||||
...state,
|
||||
endpointPackageInfo: action.payload,
|
||||
};
|
||||
};
|
||||
|
||||
/* eslint-disable-next-line complexity */
|
||||
export const endpointListReducer: StateReducer = (state = initialEndpointPageState(), action) => {
|
||||
if (action.type === 'serverReturnedEndpointList') {
|
||||
|
@ -231,11 +245,8 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta
|
|||
...state,
|
||||
policyItemsLoading: false,
|
||||
};
|
||||
} else if (action.type === 'serverReturnedEndpointPackageInfo') {
|
||||
return {
|
||||
...state,
|
||||
endpointPackageInfo: action.payload,
|
||||
};
|
||||
} else if (action.type === 'endpointPackageInfoStateChanged') {
|
||||
return handleEndpointPackageInfoStateChanged(state, action);
|
||||
} else if (action.type === 'serverReturnedEndpointExistValue') {
|
||||
return {
|
||||
...state,
|
||||
|
|
|
@ -69,6 +69,16 @@ export const policyItemsLoading = (state: Immutable<EndpointState>) => state.pol
|
|||
export const selectedPolicyId = (state: Immutable<EndpointState>) => state.selectedPolicyId;
|
||||
|
||||
export const endpointPackageInfo = (state: Immutable<EndpointState>) => state.endpointPackageInfo;
|
||||
export const getIsEndpointPackageInfoPending: (
|
||||
state: Immutable<EndpointState>
|
||||
) => boolean = createSelector(endpointPackageInfo, (packageInfo) =>
|
||||
isLoadingResourceState(packageInfo)
|
||||
);
|
||||
export const getIsEndpointPackageInfoSuccessful: (
|
||||
state: Immutable<EndpointState>
|
||||
) => boolean = createSelector(endpointPackageInfo, (packageInfo) =>
|
||||
isLoadedResourceState(packageInfo)
|
||||
);
|
||||
|
||||
export const isAutoRefreshEnabled = (state: Immutable<EndpointState>) => state.isAutoRefreshEnabled;
|
||||
|
||||
|
@ -86,9 +96,8 @@ export const agentsWithEndpointsTotalError = (state: Immutable<EndpointState>) =
|
|||
export const endpointsTotalError = (state: Immutable<EndpointState>) => state.endpointsTotalError;
|
||||
const queryStrategyVersion = (state: Immutable<EndpointState>) => state.queryStrategyVersion;
|
||||
|
||||
export const endpointPackageVersion = createSelector(
|
||||
endpointPackageInfo,
|
||||
(info) => info?.version ?? undefined
|
||||
export const endpointPackageVersion = createSelector(endpointPackageInfo, (info) =>
|
||||
isLoadedResourceState(info) ? info.data.version : undefined
|
||||
);
|
||||
|
||||
export const isTransformEnabled = createSelector(
|
||||
|
|
|
@ -70,7 +70,7 @@ export interface EndpointState {
|
|||
/** the selected policy ID in the onboarding flow */
|
||||
selectedPolicyId?: string;
|
||||
/** Endpoint package info */
|
||||
endpointPackageInfo?: GetPackagesResponse['response'][0];
|
||||
endpointPackageInfo: AsyncResourceState<GetPackagesResponse['response'][0]>;
|
||||
/** Tracks the list of policies IDs used in Host metadata that may no longer exist */
|
||||
nonExistingPolicies: PolicyIds['packagePolicy'];
|
||||
/** List of Package Policy Ids mapped to an associated Fleet Parent Agent Policy Id*/
|
||||
|
|
|
@ -762,8 +762,9 @@ describe('When on the Trusted Apps Page', () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
const priorMockImplementation = coreStart.http.get.getMockImplementation();
|
||||
// @ts-ignore
|
||||
coreStart.http.get.mockImplementation(async (path, options) => {
|
||||
coreStart.http.get.mockImplementation((path, options) => {
|
||||
if (path === TRUSTED_APPS_LIST_API) {
|
||||
const { page, per_page: perPage } = options.query as { page: number; per_page: number };
|
||||
|
||||
|
@ -773,6 +774,9 @@ describe('When on the Trusted Apps Page', () => {
|
|||
return releaseListResponse();
|
||||
}
|
||||
}
|
||||
if (priorMockImplementation) {
|
||||
return priorMockImplementation(path);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue