[Security Solution] Move endpointdetails into its own middleware function (#107632)
This commit is contained in:
parent
e7a05c0110
commit
417d093a29
|
@ -94,7 +94,6 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
|
|||
};
|
||||
return [indexPattern];
|
||||
}
|
||||
// eslint-disable-next-line complexity
|
||||
return (store) => (next) => async (action) => {
|
||||
next(action);
|
||||
|
||||
|
@ -108,270 +107,12 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
|
|||
isOnEndpointPage(getState()) &&
|
||||
hasSelectedEndpoint(getState()) !== true
|
||||
) {
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
let endpointResponse;
|
||||
|
||||
try {
|
||||
const decodedQuery: Query = searchBarQuery(getState());
|
||||
|
||||
endpointResponse = await coreStart.http.post<HostResultList>(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
filters: { kql: decodedQuery.query },
|
||||
}),
|
||||
});
|
||||
endpointResponse.request_page_index = Number(pageIndex);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: endpointResponse,
|
||||
});
|
||||
|
||||
loadEndpointsPendingActions(store);
|
||||
|
||||
try {
|
||||
const endpointsTotalCount = await endpointsTotal(coreStart.http);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointsTotal',
|
||||
payload: endpointsTotalCount,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointsTotal',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const agentsWithEndpoint = await sendGetFleetAgentsWithEndpoint(coreStart.http);
|
||||
dispatch({
|
||||
type: 'serverReturnedAgenstWithEndpointsTotal',
|
||||
payload: agentsWithEndpoint.total,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnAgenstWithEndpointsTotal',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
endpointResponse.hosts,
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies?.packagePolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
// 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// No endpoints, so we should check to see if there are policies for onboarding
|
||||
if (endpointResponse && endpointResponse.hosts.length === 0) {
|
||||
const http = coreStart.http;
|
||||
|
||||
// The original query to the list could have had an invalid param (ex. invalid page_size),
|
||||
// so we check first if endpoints actually do exist before pulling in data for the onboarding
|
||||
// messages.
|
||||
if (await doEndpointsExist(http)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointExistValue',
|
||||
payload: false,
|
||||
});
|
||||
|
||||
try {
|
||||
const policyDataResponse: GetPolicyListResponse = await sendGetEndpointSpecificPackagePolicies(
|
||||
http,
|
||||
{
|
||||
query: {
|
||||
perPage: 50, // Since this is an oboarding flow, we'll cap at 50 policies.
|
||||
page: 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedPoliciesForOnboarding',
|
||||
payload: {
|
||||
policyItems: policyDataResponse.items,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnPoliciesForOnboarding',
|
||||
payload: error.body ?? error,
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'serverCancelledPolicyItemsLoading',
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointExistValue',
|
||||
payload: true,
|
||||
});
|
||||
}
|
||||
endpointDetailsListMiddleware({ coreStart, store, fetchIndexPatterns });
|
||||
}
|
||||
|
||||
// Endpoint Details
|
||||
if (action.type === 'userChangedUrl' && hasSelectedEndpoint(getState()) === true) {
|
||||
dispatch({
|
||||
type: 'serverCancelledPolicyItemsLoading',
|
||||
});
|
||||
|
||||
// If user navigated directly to a endpoint details page, load the endpoint list
|
||||
if (listData(getState()).length === 0) {
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
try {
|
||||
const response = await coreStart.http.post(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
}),
|
||||
});
|
||||
response.request_page_index = Number(pageIndex);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
response.hosts,
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies?.packagePolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'serverCancelledEndpointListLoading',
|
||||
});
|
||||
}
|
||||
|
||||
// call the endpoint details api
|
||||
const { selected_endpoint: selectedEndpoint } = uiQueryParams(getState());
|
||||
try {
|
||||
const response = await coreStart.http.get<HostInfo>(
|
||||
resolvePathVariables(HOST_METADATA_GET_ROUTE, { id: selectedEndpoint as string })
|
||||
);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointDetails',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
[response],
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointDetails',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
loadEndpointsPendingActions(store);
|
||||
|
||||
// call the policy response api
|
||||
try {
|
||||
const policyResponse = await coreStart.http.get(BASE_POLICY_RESPONSE_ROUTE, {
|
||||
query: { agentId: selectedEndpoint },
|
||||
});
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointPolicyResponse',
|
||||
payload: policyResponse,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointPolicyResponse',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
endpointDetailsMiddleware({ store, coreStart });
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -379,32 +120,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
|
|||
hasSelectedEndpoint(getState()) === true &&
|
||||
getIsOnEndpointDetailsActivityLog(getState())
|
||||
) {
|
||||
// call the activity log api
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
// ts error to be fixed when AsyncResourceState is refactored (#830)
|
||||
// @ts-expect-error
|
||||
payload: createLoadingResourceState<ActivityLog>(getActivityLogData(getState())),
|
||||
});
|
||||
|
||||
try {
|
||||
const { page, pageSize } = getActivityLogDataPaging(getState());
|
||||
const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, {
|
||||
agent_id: selectedAgent(getState()),
|
||||
});
|
||||
const activityLog = await coreStart.http.get<ActivityLog>(route, {
|
||||
query: { page, page_size: pageSize },
|
||||
});
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(activityLog),
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createFailedResourceState<ActivityLog>(error.body ?? error),
|
||||
});
|
||||
}
|
||||
endpointDetailsActivityLogChangedMiddleware({ store, coreStart });
|
||||
}
|
||||
|
||||
// page activity log API
|
||||
|
@ -412,91 +128,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState
|
|||
action.type === 'endpointDetailsActivityLogUpdatePaging' &&
|
||||
hasSelectedEndpoint(getState())
|
||||
) {
|
||||
try {
|
||||
const { disabled, page, pageSize, startDate, endDate } = getActivityLogDataPaging(
|
||||
getState()
|
||||
);
|
||||
// don't page when paging is disabled or when date ranges are invalid
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
if (getIsInvalidDateRange({ startDate, endDate })) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange',
|
||||
payload: {
|
||||
isInvalidDateRange: true,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange',
|
||||
payload: {
|
||||
isInvalidDateRange: false,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
// ts error to be fixed when AsyncResourceState is refactored (#830)
|
||||
// @ts-expect-error
|
||||
payload: createLoadingResourceState<ActivityLog>(getActivityLogData(getState())),
|
||||
});
|
||||
const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, {
|
||||
agent_id: selectedAgent(getState()),
|
||||
});
|
||||
const activityLog = await coreStart.http.get<ActivityLog>(route, {
|
||||
query: {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
},
|
||||
});
|
||||
|
||||
const lastLoadedLogData = getLastLoadedActivityLogData(getState());
|
||||
if (lastLoadedLogData !== undefined) {
|
||||
const updatedLogDataItems = ([
|
||||
...new Set([...lastLoadedLogData.data, ...activityLog.data]),
|
||||
] as ActivityLog['data']).sort((a, b) =>
|
||||
new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1
|
||||
);
|
||||
|
||||
const updatedLogData = {
|
||||
page: activityLog.page,
|
||||
pageSize: activityLog.pageSize,
|
||||
startDate: activityLog.startDate,
|
||||
endDate: activityLog.endDate,
|
||||
data: activityLog.page === 1 ? activityLog.data : updatedLogDataItems,
|
||||
};
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(updatedLogData),
|
||||
});
|
||||
if (!activityLog.data.length) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdatePaging',
|
||||
payload: {
|
||||
disabled: true,
|
||||
page: activityLog.page > 1 ? activityLog.page - 1 : 1,
|
||||
pageSize: activityLog.pageSize,
|
||||
startDate: activityLog.startDate,
|
||||
endDate: activityLog.endDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(activityLog),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createFailedResourceState<ActivityLog>(error.body ?? error),
|
||||
});
|
||||
}
|
||||
endpointDetailsActivityLogPagingMiddleware({ store, coreStart });
|
||||
}
|
||||
|
||||
// Isolate Host
|
||||
|
@ -730,6 +362,416 @@ const loadEndpointsPendingActions = async ({
|
|||
}
|
||||
};
|
||||
|
||||
async function endpointDetailsListMiddleware({
|
||||
store,
|
||||
coreStart,
|
||||
fetchIndexPatterns,
|
||||
}: {
|
||||
store: ImmutableMiddlewareAPI<EndpointState, AppAction>;
|
||||
coreStart: CoreStart;
|
||||
fetchIndexPatterns: () => Promise<IIndexPattern[]>;
|
||||
}) {
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
let endpointResponse;
|
||||
|
||||
try {
|
||||
const decodedQuery: Query = searchBarQuery(getState());
|
||||
|
||||
endpointResponse = await coreStart.http.post<HostResultList>(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
filters: { kql: decodedQuery.query },
|
||||
}),
|
||||
});
|
||||
endpointResponse.request_page_index = Number(pageIndex);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: endpointResponse,
|
||||
});
|
||||
|
||||
loadEndpointsPendingActions(store);
|
||||
|
||||
try {
|
||||
const endpointsTotalCount = await endpointsTotal(coreStart.http);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointsTotal',
|
||||
payload: endpointsTotalCount,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointsTotal',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const agentsWithEndpoint = await sendGetFleetAgentsWithEndpoint(coreStart.http);
|
||||
dispatch({
|
||||
type: 'serverReturnedAgenstWithEndpointsTotal',
|
||||
payload: agentsWithEndpoint.total,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnAgenstWithEndpointsTotal',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
endpointResponse.hosts,
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies?.packagePolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
// 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// No endpoints, so we should check to see if there are policies for onboarding
|
||||
if (endpointResponse && endpointResponse.hosts.length === 0) {
|
||||
const http = coreStart.http;
|
||||
|
||||
// The original query to the list could have had an invalid param (ex. invalid page_size),
|
||||
// so we check first if endpoints actually do exist before pulling in data for the onboarding
|
||||
// messages.
|
||||
if (await doEndpointsExist(http)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointExistValue',
|
||||
payload: false,
|
||||
});
|
||||
|
||||
try {
|
||||
const policyDataResponse: GetPolicyListResponse = await sendGetEndpointSpecificPackagePolicies(
|
||||
http,
|
||||
{
|
||||
query: {
|
||||
perPage: 50, // Since this is an oboarding flow, we'll cap at 50 policies.
|
||||
page: 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedPoliciesForOnboarding',
|
||||
payload: {
|
||||
policyItems: policyDataResponse.items,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnPoliciesForOnboarding',
|
||||
payload: error.body ?? error,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'serverCancelledPolicyItemsLoading',
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointExistValue',
|
||||
payload: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function endpointDetailsActivityLogPagingMiddleware({
|
||||
store,
|
||||
coreStart,
|
||||
}: {
|
||||
store: ImmutableMiddlewareAPI<EndpointState, AppAction>;
|
||||
coreStart: CoreStart;
|
||||
}) {
|
||||
const { getState, dispatch } = store;
|
||||
try {
|
||||
const { disabled, page, pageSize, startDate, endDate } = getActivityLogDataPaging(getState());
|
||||
// don't page when paging is disabled or when date ranges are invalid
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
if (getIsInvalidDateRange({ startDate, endDate })) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange',
|
||||
payload: {
|
||||
isInvalidDateRange: true,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange',
|
||||
payload: {
|
||||
isInvalidDateRange: false,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
// ts error to be fixed when AsyncResourceState is refactored (#830)
|
||||
// @ts-expect-error
|
||||
payload: createLoadingResourceState<ActivityLog>(getActivityLogData(getState())),
|
||||
});
|
||||
const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, {
|
||||
agent_id: selectedAgent(getState()),
|
||||
});
|
||||
const activityLog = await coreStart.http.get<ActivityLog>(route, {
|
||||
query: {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
start_date: startDate,
|
||||
end_date: endDate,
|
||||
},
|
||||
});
|
||||
|
||||
const lastLoadedLogData = getLastLoadedActivityLogData(getState());
|
||||
if (lastLoadedLogData !== undefined) {
|
||||
const updatedLogDataItems = ([
|
||||
...new Set([...lastLoadedLogData.data, ...activityLog.data]),
|
||||
] as ActivityLog['data']).sort((a, b) =>
|
||||
new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1
|
||||
);
|
||||
|
||||
const updatedLogData = {
|
||||
page: activityLog.page,
|
||||
pageSize: activityLog.pageSize,
|
||||
startDate: activityLog.startDate,
|
||||
endDate: activityLog.endDate,
|
||||
data: activityLog.page === 1 ? activityLog.data : updatedLogDataItems,
|
||||
};
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(updatedLogData),
|
||||
});
|
||||
if (!activityLog.data.length) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogUpdatePaging',
|
||||
payload: {
|
||||
disabled: true,
|
||||
page: activityLog.page > 1 ? activityLog.page - 1 : 1,
|
||||
pageSize: activityLog.pageSize,
|
||||
startDate: activityLog.startDate,
|
||||
endDate: activityLog.endDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(activityLog),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createFailedResourceState<ActivityLog>(error.body ?? error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function endpointDetailsMiddleware({
|
||||
store,
|
||||
coreStart,
|
||||
}: {
|
||||
store: ImmutableMiddlewareAPI<EndpointState, AppAction>;
|
||||
coreStart: CoreStart;
|
||||
}) {
|
||||
const { getState, dispatch } = store;
|
||||
dispatch({
|
||||
type: 'serverCancelledPolicyItemsLoading',
|
||||
});
|
||||
|
||||
// If user navigated directly to a endpoint details page, load the endpoint list
|
||||
if (listData(getState()).length === 0) {
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
try {
|
||||
const response = await coreStart.http.post(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
}),
|
||||
});
|
||||
response.request_page_index = Number(pageIndex);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
response.hosts,
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies?.packagePolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'serverCancelledEndpointListLoading',
|
||||
});
|
||||
}
|
||||
|
||||
// call the endpoint details api
|
||||
const { selected_endpoint: selectedEndpoint } = uiQueryParams(getState());
|
||||
try {
|
||||
const response = await coreStart.http.get<HostInfo>(
|
||||
resolvePathVariables(HOST_METADATA_GET_ROUTE, { id: selectedEndpoint as string })
|
||||
);
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointDetails',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
try {
|
||||
const ingestPolicies = await getAgentAndPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
[response],
|
||||
nonExistingPolicies(getState())
|
||||
);
|
||||
if (ingestPolicies !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: ingestPolicies.packagePolicy,
|
||||
});
|
||||
}
|
||||
if (ingestPolicies?.agentPolicy !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointAgentPolicies',
|
||||
payload: ingestPolicies.agentPolicy,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO should handle the error instead of logging it to the browser
|
||||
// Also this is an anti-pattern we shouldn't use
|
||||
// Ignore Errors, since this should not hinder the user's ability to use the UI
|
||||
logError(error);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointDetails',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
loadEndpointsPendingActions(store);
|
||||
|
||||
// call the policy response api
|
||||
try {
|
||||
const policyResponse = await coreStart.http.get(BASE_POLICY_RESPONSE_ROUTE, {
|
||||
query: { agentId: selectedEndpoint },
|
||||
});
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointPolicyResponse',
|
||||
payload: policyResponse,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointPolicyResponse',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
}
|
||||
async function endpointDetailsActivityLogChangedMiddleware({
|
||||
store,
|
||||
coreStart,
|
||||
}: {
|
||||
store: ImmutableMiddlewareAPI<EndpointState, AppAction>;
|
||||
coreStart: CoreStart;
|
||||
}) {
|
||||
const { getState, dispatch } = store;
|
||||
// call the activity log api
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
// ts error to be fixed when AsyncResourceState is refactored (#830)
|
||||
// @ts-expect-error
|
||||
payload: createLoadingResourceState<ActivityLog>(getActivityLogData(getState())),
|
||||
});
|
||||
|
||||
try {
|
||||
const { page, pageSize } = getActivityLogDataPaging(getState());
|
||||
const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, {
|
||||
agent_id: selectedAgent(getState()),
|
||||
});
|
||||
const activityLog = await coreStart.http.get<ActivityLog>(route, {
|
||||
query: { page, page_size: pageSize },
|
||||
});
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createLoadedResourceState<ActivityLog>(activityLog),
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'endpointDetailsActivityLogChanged',
|
||||
payload: createFailedResourceState<ActivityLog>(error.body ?? error),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleLoadMetadataTransformStats(http: HttpStart, store: EndpointPageStore) {
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
|
|
Loading…
Reference in a new issue