mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution] migrate to new GET metadata list API (#119123)
This commit is contained in:
parent
079db9666e
commit
edf66a52d2
19 changed files with 273 additions and 180 deletions
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { HostStatus } from '../types';
|
||||
import { GetMetadataListRequestSchemaV2 } from './metadata';
|
||||
|
||||
describe('endpoint metadata schema', () => {
|
||||
describe('GetMetadataListRequestSchemaV2', () => {
|
||||
const query = GetMetadataListRequestSchemaV2.query;
|
||||
|
||||
it('should return correct query params when valid', () => {
|
||||
const queryParams = {
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
kuery: 'some kuery',
|
||||
hostStatuses: [HostStatus.HEALTHY.toString()],
|
||||
};
|
||||
expect(query.validate(queryParams)).toEqual(queryParams);
|
||||
});
|
||||
|
||||
it('should correctly use default values', () => {
|
||||
const expected = { page: 0, pageSize: 10 };
|
||||
expect(query.validate(undefined)).toEqual(expected);
|
||||
expect(query.validate({ page: undefined })).toEqual(expected);
|
||||
expect(query.validate({ pageSize: undefined })).toEqual(expected);
|
||||
expect(query.validate({ page: undefined, pageSize: undefined })).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should throw if page param is not a number', () => {
|
||||
expect(() => query.validate({ page: 'notanumber' })).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if page param is less than 0', () => {
|
||||
expect(() => query.validate({ page: -1 })).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if pageSize param is not a number', () => {
|
||||
expect(() => query.validate({ pageSize: 'notanumber' })).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if pageSize param is less than 1', () => {
|
||||
expect(() => query.validate({ pageSize: 0 })).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if pageSize param is greater than 10000', () => {
|
||||
expect(() => query.validate({ pageSize: 10001 })).toThrowError();
|
||||
});
|
||||
|
||||
it('should throw if kuery is not string', () => {
|
||||
expect(() => query.validate({ kuery: 123 })).toThrowError();
|
||||
});
|
||||
|
||||
it('should work with valid hostStatus', () => {
|
||||
const queryParams = { hostStatuses: [HostStatus.HEALTHY, HostStatus.UPDATING] };
|
||||
const expected = { page: 0, pageSize: 10, ...queryParams };
|
||||
expect(query.validate(queryParams)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should throw if invalid hostStatus', () => {
|
||||
expect(() =>
|
||||
query.validate({ hostStatuses: [HostStatus.UNHEALTHY, 'invalidstatus'] })
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { HostStatus } from '../types';
|
||||
|
||||
export const GetMetadataListRequestSchemaV2 = {
|
||||
query: schema.object(
|
||||
{
|
||||
page: schema.number({ defaultValue: 0, min: 0 }),
|
||||
pageSize: schema.number({ defaultValue: 10, min: 1, max: 10000 }),
|
||||
kuery: schema.maybe(schema.string()),
|
||||
hostStatuses: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.oneOf([
|
||||
schema.literal(HostStatus.HEALTHY.toString()),
|
||||
schema.literal(HostStatus.OFFLINE.toString()),
|
||||
schema.literal(HostStatus.UPDATING.toString()),
|
||||
schema.literal(HostStatus.UNHEALTHY.toString()),
|
||||
schema.literal(HostStatus.INACTIVE.toString()),
|
||||
])
|
||||
)
|
||||
),
|
||||
},
|
||||
{ defaultValue: { page: 0, pageSize: 10 } }
|
||||
),
|
||||
};
|
||||
|
||||
export type GetMetadataListRequestQuery = TypeOf<typeof GetMetadataListRequestSchemaV2.query>;
|
|
@ -1235,18 +1235,14 @@ export interface ListPageRouteState {
|
|||
/**
|
||||
* REST API standard base response for list types
|
||||
*/
|
||||
export interface BaseListResponse {
|
||||
data: unknown[];
|
||||
interface BaseListResponse<D = unknown> {
|
||||
data: D[];
|
||||
page: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
sort?: string;
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned by the server via GET /api/endpoint/metadata
|
||||
*/
|
||||
export interface MetadataListResponse extends BaseListResponse {
|
||||
data: HostInfo[];
|
||||
}
|
||||
export type MetadataListResponse = BaseListResponse<HostInfo>;
|
||||
|
|
|
@ -14,8 +14,8 @@ import {
|
|||
ActivityLog,
|
||||
HostInfo,
|
||||
HostPolicyResponse,
|
||||
HostResultList,
|
||||
HostStatus,
|
||||
MetadataListResponse,
|
||||
} from '../../../../common/endpoint/types';
|
||||
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';
|
||||
import { FleetActionGenerator } from '../../../../common/endpoint/data_generators/fleet_action_generator';
|
||||
|
@ -43,7 +43,7 @@ import {
|
|||
} from '../mocks';
|
||||
|
||||
type EndpointMetadataHttpMocksInterface = ResponseProvidersInterface<{
|
||||
metadataList: () => HostResultList;
|
||||
metadataList: () => MetadataListResponse;
|
||||
metadataDetails: () => HostInfo;
|
||||
}>;
|
||||
export const endpointMetadataHttpMocks = httpHandlerMockFactory<EndpointMetadataHttpMocksInterface>(
|
||||
|
@ -72,6 +72,30 @@ export const endpointMetadataHttpMocks = httpHandlerMockFactory<EndpointMetadata
|
|||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'metadataList',
|
||||
path: HOST_METADATA_LIST_ROUTE,
|
||||
method: 'get',
|
||||
handler: () => {
|
||||
const generator = new EndpointDocGenerator('seed');
|
||||
|
||||
return {
|
||||
data: Array.from({ length: 10 }, () => {
|
||||
const endpoint = {
|
||||
metadata: generator.generateHostMetadata(),
|
||||
host_status: HostStatus.UNHEALTHY,
|
||||
};
|
||||
|
||||
generator.updateCommonInfo();
|
||||
|
||||
return endpoint;
|
||||
}),
|
||||
total: 10,
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'metadataDetails',
|
||||
path: HOST_METADATA_GET_ROUTE,
|
||||
|
|
|
@ -9,11 +9,11 @@ import { Action } from 'redux';
|
|||
import { EuiSuperDatePickerRecentRange } from '@elastic/eui';
|
||||
import type { DataViewBase } from '@kbn/es-query';
|
||||
import {
|
||||
HostResultList,
|
||||
HostInfo,
|
||||
GetHostPolicyResponse,
|
||||
HostIsolationRequestBody,
|
||||
ISOLATION_ACTIONS,
|
||||
MetadataListResponse,
|
||||
} from '../../../../../common/endpoint/types';
|
||||
import { ServerApiError } from '../../../../common/types';
|
||||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
|
@ -21,7 +21,7 @@ import { EndpointState } from '../types';
|
|||
|
||||
export interface ServerReturnedEndpointList {
|
||||
type: 'serverReturnedEndpointList';
|
||||
payload: HostResultList;
|
||||
payload: MetadataListResponse;
|
||||
}
|
||||
|
||||
export interface ServerFailedToReturnEndpointList {
|
||||
|
|
|
@ -11,7 +11,7 @@ import { applyMiddleware, Store, createStore } from 'redux';
|
|||
|
||||
import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
||||
|
||||
import { HostResultList, AppLocation } from '../../../../../common/endpoint/types';
|
||||
import { AppLocation, MetadataListResponse } from '../../../../../common/endpoint/types';
|
||||
import { DepsStartMock, depsStartMock } from '../../../../common/mock/endpoint';
|
||||
|
||||
import { endpointMiddlewareFactory } from './middleware';
|
||||
|
@ -19,13 +19,17 @@ import { endpointMiddlewareFactory } from './middleware';
|
|||
import { endpointListReducer } from './reducer';
|
||||
|
||||
import { uiQueryParams } from './selectors';
|
||||
import { mockEndpointResultList } from './mock_endpoint_result_list';
|
||||
import {
|
||||
mockEndpointResultList,
|
||||
setEndpointListApiMockImplementation,
|
||||
} from './mock_endpoint_result_list';
|
||||
import { EndpointState, EndpointIndexUIQueryParams } from '../types';
|
||||
import {
|
||||
MiddlewareActionSpyHelper,
|
||||
createSpyMiddleware,
|
||||
} from '../../../../common/store/test_utils';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
import { HOST_METADATA_LIST_ROUTE } from '../../../../../common/endpoint/constants';
|
||||
|
||||
jest.mock('../../policy/store/services/ingest', () => ({
|
||||
sendGetAgentPolicyList: () => Promise.resolve({ items: [] }),
|
||||
|
@ -40,8 +44,8 @@ describe('endpoint list pagination: ', () => {
|
|||
let queryParams: () => EndpointIndexUIQueryParams;
|
||||
let waitForAction: MiddlewareActionSpyHelper['waitForAction'];
|
||||
let actionSpyMiddleware;
|
||||
const getEndpointListApiResponse = (): HostResultList => {
|
||||
return mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
const getEndpointListApiResponse = (): MetadataListResponse => {
|
||||
return mockEndpointResultList({ pageSize: 1, page: 0, total: 10 });
|
||||
};
|
||||
|
||||
let historyPush: (params: EndpointIndexUIQueryParams) => void;
|
||||
|
@ -63,13 +67,15 @@ describe('endpoint list pagination: ', () => {
|
|||
historyPush = (nextQueryParams: EndpointIndexUIQueryParams): void => {
|
||||
return history.push(getEndpointListPath({ name: 'endpointList', ...nextQueryParams }));
|
||||
};
|
||||
|
||||
setEndpointListApiMockImplementation(fakeHttpServices);
|
||||
});
|
||||
|
||||
describe('when the user enteres the endpoint list for the first time', () => {
|
||||
it('the api is called with page_index and page_size defaulting to 0 and 10 respectively', async () => {
|
||||
const apiResponse = getEndpointListApiResponse();
|
||||
fakeHttpServices.post.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.post).not.toHaveBeenCalled();
|
||||
fakeHttpServices.get.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.get).not.toHaveBeenCalled();
|
||||
|
||||
store.dispatch({
|
||||
type: 'userChangedUrl',
|
||||
|
@ -79,11 +85,12 @@ describe('endpoint list pagination: ', () => {
|
|||
},
|
||||
});
|
||||
await waitForAction('serverReturnedEndpointList');
|
||||
expect(fakeHttpServices.post).toHaveBeenCalledWith('/api/endpoint/metadata', {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: '0' }, { page_size: '10' }],
|
||||
filters: { kql: '' },
|
||||
}),
|
||||
expect(fakeHttpServices.get).toHaveBeenCalledWith(HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: '0',
|
||||
pageSize: '10',
|
||||
kuery: '',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ describe('EndpointList store concerns', () => {
|
|||
const loadDataToStore = () => {
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 }),
|
||||
payload: mockEndpointResultList({ pageSize: 1, page: 0, total: 10 }),
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -101,8 +101,8 @@ describe('EndpointList store concerns', () => {
|
|||
|
||||
test('it handles `serverReturnedEndpointList', () => {
|
||||
const payload = mockEndpointResultList({
|
||||
request_page_size: 1,
|
||||
request_page_index: 1,
|
||||
page: 0,
|
||||
pageSize: 1,
|
||||
total: 10,
|
||||
});
|
||||
dispatch({
|
||||
|
@ -111,9 +111,9 @@ describe('EndpointList store concerns', () => {
|
|||
});
|
||||
|
||||
const currentState = store.getState();
|
||||
expect(currentState.hosts).toEqual(payload.hosts);
|
||||
expect(currentState.pageSize).toEqual(payload.request_page_size);
|
||||
expect(currentState.pageIndex).toEqual(payload.request_page_index);
|
||||
expect(currentState.hosts).toEqual(payload.data);
|
||||
expect(currentState.pageSize).toEqual(payload.pageSize);
|
||||
expect(currentState.pageIndex).toEqual(payload.page);
|
||||
expect(currentState.total).toEqual(payload.total);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,10 +16,10 @@ import {
|
|||
} from '../../../../common/store/test_utils';
|
||||
import {
|
||||
Immutable,
|
||||
HostResultList,
|
||||
HostIsolationResponse,
|
||||
ISOLATION_ACTIONS,
|
||||
ActivityLog,
|
||||
MetadataListResponse,
|
||||
} from '../../../../../common/endpoint/types';
|
||||
import { AppAction } from '../../../../common/store/actions';
|
||||
import { mockEndpointResultList } from './mock_endpoint_result_list';
|
||||
|
@ -72,8 +72,8 @@ describe('endpoint list middleware', () => {
|
|||
let actionSpyMiddleware;
|
||||
let history: History<never>;
|
||||
|
||||
const getEndpointListApiResponse = (): HostResultList => {
|
||||
return mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
const getEndpointListApiResponse = (): MetadataListResponse => {
|
||||
return mockEndpointResultList({ pageSize: 1, page: 0, total: 10 });
|
||||
};
|
||||
|
||||
const dispatchUserChangedUrlToEndpointList = (locationOverrides: Partial<Location> = {}) => {
|
||||
|
@ -105,25 +105,26 @@ describe('endpoint list middleware', () => {
|
|||
it('handles `userChangedUrl`', async () => {
|
||||
endpointPageHttpMock(fakeHttpServices);
|
||||
const apiResponse = getEndpointListApiResponse();
|
||||
fakeHttpServices.post.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.post).not.toHaveBeenCalled();
|
||||
fakeHttpServices.get.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.get).not.toHaveBeenCalled();
|
||||
|
||||
dispatchUserChangedUrlToEndpointList();
|
||||
await waitForAction('serverReturnedEndpointList');
|
||||
expect(fakeHttpServices.post).toHaveBeenCalledWith('/api/endpoint/metadata', {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: '0' }, { page_size: '10' }],
|
||||
filters: { kql: '' },
|
||||
}),
|
||||
expect(fakeHttpServices.get).toHaveBeenNthCalledWith(1, HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: '0',
|
||||
pageSize: '10',
|
||||
kuery: '',
|
||||
},
|
||||
});
|
||||
expect(listData(getState())).toEqual(apiResponse.hosts);
|
||||
expect(listData(getState())).toEqual(apiResponse.data);
|
||||
});
|
||||
|
||||
it('handles `appRequestedEndpointList`', async () => {
|
||||
endpointPageHttpMock(fakeHttpServices);
|
||||
const apiResponse = getEndpointListApiResponse();
|
||||
fakeHttpServices.post.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.post).not.toHaveBeenCalled();
|
||||
fakeHttpServices.get.mockResolvedValue(apiResponse);
|
||||
expect(fakeHttpServices.get).not.toHaveBeenCalled();
|
||||
|
||||
// First change the URL
|
||||
dispatchUserChangedUrlToEndpointList();
|
||||
|
@ -144,13 +145,14 @@ describe('endpoint list middleware', () => {
|
|||
waitForAction('serverReturnedAgenstWithEndpointsTotal'),
|
||||
]);
|
||||
|
||||
expect(fakeHttpServices.post).toHaveBeenCalledWith(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: '0' }, { page_size: '10' }],
|
||||
filters: { kql: '' },
|
||||
}),
|
||||
expect(fakeHttpServices.get).toHaveBeenNthCalledWith(1, HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: '0',
|
||||
pageSize: '10',
|
||||
kuery: '',
|
||||
},
|
||||
});
|
||||
expect(listData(getState())).toEqual(apiResponse.hosts);
|
||||
expect(listData(getState())).toEqual(apiResponse.data);
|
||||
});
|
||||
|
||||
describe('handling of IsolateEndpointHost action', () => {
|
||||
|
@ -242,7 +244,7 @@ describe('endpoint list middleware', () => {
|
|||
});
|
||||
|
||||
const endpointList = getEndpointListApiResponse();
|
||||
const agentId = endpointList.hosts[0].metadata.agent.id;
|
||||
const agentId = endpointList.data[0].metadata.agent.id;
|
||||
const search = getEndpointDetailsPath({
|
||||
name: 'endpointActivityLog',
|
||||
selected_endpoint: agentId,
|
||||
|
@ -514,7 +516,7 @@ describe('endpoint list middleware', () => {
|
|||
});
|
||||
|
||||
const endpointList = getEndpointListApiResponse();
|
||||
const agentId = endpointList.hosts[0].metadata.agent.id;
|
||||
const agentId = endpointList.data[0].metadata.agent.id;
|
||||
const search = getEndpointDetailsPath({
|
||||
name: 'endpointDetails',
|
||||
selected_endpoint: agentId,
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
HostResultList,
|
||||
Immutable,
|
||||
ImmutableObject,
|
||||
MetadataListResponse,
|
||||
} from '../../../../../common/endpoint/types';
|
||||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
import { ImmutableMiddlewareAPI, ImmutableMiddlewareFactory } from '../../../../common/store';
|
||||
|
@ -246,10 +247,11 @@ const getAgentAndPoliciesForEndpointsList = async (
|
|||
const endpointsTotal = async (http: HttpStart): Promise<number> => {
|
||||
try {
|
||||
return (
|
||||
await http.post<HostResultList>(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: 0 }, { page_size: 1 }],
|
||||
}),
|
||||
await http.get<MetadataListResponse>(HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: 0,
|
||||
pageSize: 1,
|
||||
},
|
||||
})
|
||||
).total;
|
||||
} catch (error) {
|
||||
|
@ -401,18 +403,18 @@ async function endpointDetailsListMiddleware({
|
|||
const { getState, dispatch } = store;
|
||||
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
let endpointResponse;
|
||||
let endpointResponse: MetadataListResponse | undefined;
|
||||
|
||||
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 = await coreStart.http.get<MetadataListResponse>(HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: pageIndex,
|
||||
pageSize,
|
||||
kuery: decodedQuery.query as string,
|
||||
},
|
||||
});
|
||||
endpointResponse.request_page_index = Number(pageIndex);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
|
@ -447,7 +449,7 @@ async function endpointDetailsListMiddleware({
|
|||
});
|
||||
}
|
||||
|
||||
dispatchIngestPolicies({ http: coreStart.http, hosts: endpointResponse.hosts, store });
|
||||
dispatchIngestPolicies({ http: coreStart.http, hosts: endpointResponse.data, store });
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
|
@ -474,7 +476,7 @@ async function endpointDetailsListMiddleware({
|
|||
}
|
||||
|
||||
// No endpoints, so we should check to see if there are policies for onboarding
|
||||
if (endpointResponse && endpointResponse.hosts.length === 0) {
|
||||
if (endpointResponse && endpointResponse.data.length === 0) {
|
||||
const http = coreStart.http;
|
||||
|
||||
// The original query to the list could have had an invalid param (ex. invalid page_size),
|
||||
|
@ -611,18 +613,19 @@ async function endpointDetailsMiddleware({
|
|||
if (listData(getState()).length === 0) {
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState());
|
||||
try {
|
||||
const response = await coreStart.http.post<HostResultList>(HOST_METADATA_LIST_ROUTE, {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
}),
|
||||
const response = await coreStart.http.get<MetadataListResponse>(HOST_METADATA_LIST_ROUTE, {
|
||||
query: {
|
||||
page: pageIndex,
|
||||
pageSize,
|
||||
},
|
||||
});
|
||||
response.request_page_index = Number(pageIndex);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
dispatchIngestPolicies({ http: coreStart.http, hosts: response.hosts, store });
|
||||
dispatchIngestPolicies({ http: coreStart.http, hosts: response.data, store });
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
|
|
|
@ -10,8 +10,8 @@ import {
|
|||
GetHostPolicyResponse,
|
||||
HostInfo,
|
||||
HostPolicyResponse,
|
||||
HostResultList,
|
||||
HostStatus,
|
||||
MetadataListResponse,
|
||||
PendingActionsResponse,
|
||||
} from '../../../../../common/endpoint/types';
|
||||
import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data';
|
||||
|
@ -29,7 +29,10 @@ import {
|
|||
} from '../../../../../../fleet/common/types/rest_spec';
|
||||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
import { pendingActionsResponseMock } from '../../../../common/lib/endpoint_pending_actions/mocks';
|
||||
import { ACTION_STATUS_ROUTE } from '../../../../../common/endpoint/constants';
|
||||
import {
|
||||
ACTION_STATUS_ROUTE,
|
||||
HOST_METADATA_LIST_ROUTE,
|
||||
} from '../../../../../common/endpoint/constants';
|
||||
import { METADATA_TRANSFORM_STATS_URL } from '../../../../../common/constants';
|
||||
import { TransformStats, TransformStatsResponse } from '../types';
|
||||
|
||||
|
@ -37,20 +40,16 @@ const generator = new EndpointDocGenerator('seed');
|
|||
|
||||
export const mockEndpointResultList: (options?: {
|
||||
total?: number;
|
||||
request_page_size?: number;
|
||||
request_page_index?: number;
|
||||
}) => HostResultList = (options = {}) => {
|
||||
const {
|
||||
total = 1,
|
||||
request_page_size: requestPageSize = 10,
|
||||
request_page_index: requestPageIndex = 0,
|
||||
} = options;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}) => MetadataListResponse = (options = {}) => {
|
||||
const { total = 1, page = 0, pageSize = 10 } = options;
|
||||
|
||||
// Skip any that are before the page we're on
|
||||
const numberToSkip = requestPageSize * requestPageIndex;
|
||||
const numberToSkip = pageSize * page;
|
||||
|
||||
// total - numberToSkip is the count of non-skipped ones, but return no more than a pageSize, and no less than 0
|
||||
const actualCountToReturn = Math.max(Math.min(total - numberToSkip, requestPageSize), 0);
|
||||
const actualCountToReturn = Math.max(Math.min(total - numberToSkip, pageSize), 0);
|
||||
|
||||
const hosts: HostInfo[] = [];
|
||||
for (let index = 0; index < actualCountToReturn; index++) {
|
||||
|
@ -59,11 +58,11 @@ export const mockEndpointResultList: (options?: {
|
|||
host_status: HostStatus.UNHEALTHY,
|
||||
});
|
||||
}
|
||||
const mock: HostResultList = {
|
||||
hosts,
|
||||
const mock: MetadataListResponse = {
|
||||
data: hosts,
|
||||
total,
|
||||
request_page_size: requestPageSize,
|
||||
request_page_index: requestPageIndex,
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
return mock;
|
||||
};
|
||||
|
@ -83,7 +82,7 @@ export const mockEndpointDetailsApiResult = (): HostInfo => {
|
|||
* API handlers for Host details based on a list of Host results.
|
||||
*/
|
||||
const endpointListApiPathHandlerMocks = ({
|
||||
endpointsResults = mockEndpointResultList({ total: 3 }).hosts,
|
||||
endpointsResults = mockEndpointResultList({ total: 3 }).data,
|
||||
epmPackages = [generator.generateEpmPackage()],
|
||||
endpointPackagePolicies = [],
|
||||
policyResponse = generator.generatePolicyResponse(),
|
||||
|
@ -92,7 +91,7 @@ const endpointListApiPathHandlerMocks = ({
|
|||
transforms = [],
|
||||
}: {
|
||||
/** route handlers will be setup for each individual host in this array */
|
||||
endpointsResults?: HostResultList['hosts'];
|
||||
endpointsResults?: MetadataListResponse['data'];
|
||||
epmPackages?: GetPackagesResponse['response'];
|
||||
endpointPackagePolicies?: GetPolicyListResponse['items'];
|
||||
policyResponse?: HostPolicyResponse;
|
||||
|
@ -109,12 +108,12 @@ const endpointListApiPathHandlerMocks = ({
|
|||
},
|
||||
|
||||
// endpoint list
|
||||
'/api/endpoint/metadata': (): HostResultList => {
|
||||
[HOST_METADATA_LIST_ROUTE]: (): MetadataListResponse => {
|
||||
return {
|
||||
hosts: endpointsResults,
|
||||
request_page_size: 10,
|
||||
request_page_index: 0,
|
||||
data: endpointsResults,
|
||||
total: endpointsResults?.length || 0,
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -173,7 +172,7 @@ const endpointListApiPathHandlerMocks = ({
|
|||
if (endpointsResults) {
|
||||
endpointsResults.forEach((host) => {
|
||||
// @ts-expect-error
|
||||
apiHandlers[`/api/endpoint/metadata/${host.metadata.agent.id}`] = () => host;
|
||||
apiHandlers[`${HOST_METADATA_LIST_ROUTE}/${host.metadata.agent.id}`] = () => host;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -192,34 +191,13 @@ export const setEndpointListApiMockImplementation: (
|
|||
apiResponses?: Parameters<typeof endpointListApiPathHandlerMocks>[0]
|
||||
) => void = (
|
||||
mockedHttpService,
|
||||
{ endpointsResults = mockEndpointResultList({ total: 3 }).hosts, ...pathHandlersOptions } = {}
|
||||
{ endpointsResults = mockEndpointResultList({ total: 3 }).data, ...pathHandlersOptions } = {}
|
||||
) => {
|
||||
const apiHandlers = endpointListApiPathHandlerMocks({
|
||||
...pathHandlersOptions,
|
||||
endpointsResults,
|
||||
});
|
||||
|
||||
mockedHttpService.post
|
||||
.mockImplementation(async (...args) => {
|
||||
throw new Error(`un-expected call to http.post: ${args}`);
|
||||
})
|
||||
// First time called, return list of endpoints
|
||||
.mockImplementationOnce(async () => {
|
||||
return apiHandlers['/api/endpoint/metadata']();
|
||||
})
|
||||
// Metadata is called a second time to get the full total of Endpoints regardless of filters.
|
||||
.mockImplementationOnce(async () => {
|
||||
return apiHandlers['/api/endpoint/metadata']();
|
||||
});
|
||||
|
||||
// If the endpoints list results is zero, then mock the third call to `/metadata` to return
|
||||
// empty list - indicating there are no endpoints currently present on the system
|
||||
if (!endpointsResults.length) {
|
||||
mockedHttpService.post.mockImplementationOnce(async () => {
|
||||
return apiHandlers['/api/endpoint/metadata']();
|
||||
});
|
||||
}
|
||||
|
||||
// Setup handling of GET requests
|
||||
mockedHttpService.get.mockImplementation(async (...args) => {
|
||||
const [path] = args;
|
||||
|
|
|
@ -95,20 +95,13 @@ const handleMetadataTransformStatsChanged: CaseReducer<MetadataTransformStatsCha
|
|||
/* eslint-disable-next-line complexity */
|
||||
export const endpointListReducer: StateReducer = (state = initialEndpointPageState(), action) => {
|
||||
if (action.type === 'serverReturnedEndpointList') {
|
||||
const {
|
||||
hosts,
|
||||
total,
|
||||
request_page_size: pageSize,
|
||||
request_page_index: pageIndex,
|
||||
policy_info: policyVersionInfo,
|
||||
} = action.payload;
|
||||
const { data, total, page, pageSize } = action.payload;
|
||||
return {
|
||||
...state,
|
||||
hosts,
|
||||
hosts: data,
|
||||
total,
|
||||
pageIndex: page,
|
||||
pageSize,
|
||||
pageIndex,
|
||||
policyVersionInfo,
|
||||
loading: false,
|
||||
error: undefined,
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('When using the EndpointAgentStatus component', () => {
|
|||
(KibanaServices.get as jest.Mock).mockReturnValue(mockedContext.startServices);
|
||||
httpMocks = endpointPageHttpMock(mockedContext.coreStart.http);
|
||||
waitForAction = mockedContext.middlewareSpy.waitForAction;
|
||||
endpointMeta = httpMocks.responseProvider.metadataList().hosts[0].metadata;
|
||||
endpointMeta = httpMocks.responseProvider.metadataList().data[0].metadata;
|
||||
render = async (props: EndpointAgentStatusProps) => {
|
||||
renderResult = mockedContext.render(<EndpointAgentStatus {...props} />);
|
||||
return renderResult;
|
||||
|
|
|
@ -52,6 +52,7 @@ import {
|
|||
} from '../../../../../common/constants';
|
||||
import { TransformStats } from '../types';
|
||||
import {
|
||||
HOST_METADATA_LIST_ROUTE,
|
||||
metadataTransformPrefix,
|
||||
METADATA_UNITED_TRANSFORM,
|
||||
} from '../../../../../common/endpoint/constants';
|
||||
|
@ -170,6 +171,10 @@ describe('when on the endpoint list page', () => {
|
|||
});
|
||||
|
||||
it('should NOT display timeline', async () => {
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: [],
|
||||
});
|
||||
|
||||
const renderResult = render();
|
||||
const timelineFlyout = renderResult.queryByTestId('flyoutOverlay');
|
||||
expect(timelineFlyout).toBeNull();
|
||||
|
@ -243,7 +248,7 @@ describe('when on the endpoint list page', () => {
|
|||
total: 4,
|
||||
});
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: mockedEndpointListData.hosts,
|
||||
endpointsResults: mockedEndpointListData.data,
|
||||
totalAgentsUsingEndpoint: 5,
|
||||
});
|
||||
});
|
||||
|
@ -260,7 +265,7 @@ describe('when on the endpoint list page', () => {
|
|||
total: 5,
|
||||
});
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: mockedEndpointListData.hosts,
|
||||
endpointsResults: mockedEndpointListData.data,
|
||||
totalAgentsUsingEndpoint: 5,
|
||||
});
|
||||
});
|
||||
|
@ -277,7 +282,7 @@ describe('when on the endpoint list page', () => {
|
|||
total: 6,
|
||||
});
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: mockedEndpointListData.hosts,
|
||||
endpointsResults: mockedEndpointListData.data,
|
||||
totalAgentsUsingEndpoint: 5,
|
||||
});
|
||||
});
|
||||
|
@ -291,6 +296,10 @@ describe('when on the endpoint list page', () => {
|
|||
|
||||
describe('when there is no selected host in the url', () => {
|
||||
it('should not show the flyout', () => {
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: [],
|
||||
});
|
||||
|
||||
const renderResult = render();
|
||||
expect.assertions(1);
|
||||
return renderResult.findByTestId('endpointDetailsFlyout').catch((e) => {
|
||||
|
@ -307,7 +316,7 @@ describe('when on the endpoint list page', () => {
|
|||
beforeEach(() => {
|
||||
reactTestingLibrary.act(() => {
|
||||
const mockedEndpointData = mockEndpointResultList({ total: 5 });
|
||||
const hostListData = mockedEndpointData.hosts;
|
||||
const hostListData = mockedEndpointData.data;
|
||||
|
||||
firstPolicyID = hostListData[0].metadata.Endpoint.policy.applied.id;
|
||||
firstPolicyRev = hostListData[0].metadata.Endpoint.policy.applied.endpoint_policy_version;
|
||||
|
@ -518,7 +527,7 @@ describe('when on the endpoint list page', () => {
|
|||
describe.skip('when polling on Endpoint List', () => {
|
||||
beforeEach(() => {
|
||||
reactTestingLibrary.act(() => {
|
||||
const hostListData = mockEndpointResultList({ total: 4 }).hosts;
|
||||
const hostListData = mockEndpointResultList({ total: 4 }).data;
|
||||
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: hostListData,
|
||||
|
@ -546,7 +555,7 @@ describe('when on the endpoint list page', () => {
|
|||
expect(total[0].textContent).toEqual('4 Hosts');
|
||||
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: mockEndpointResultList({ total: 1 }).hosts,
|
||||
endpointsResults: mockEndpointResultList({ total: 1 }).data,
|
||||
});
|
||||
|
||||
await reactTestingLibrary.act(async () => {
|
||||
|
@ -1090,7 +1099,7 @@ describe('when on the endpoint list page', () => {
|
|||
let renderResult: ReturnType<typeof render>;
|
||||
beforeEach(async () => {
|
||||
coreStart.http.post.mockImplementation(async (requestOptions) => {
|
||||
if (requestOptions.path === '/api/endpoint/metadata') {
|
||||
if (requestOptions.path === HOST_METADATA_LIST_ROUTE) {
|
||||
return mockEndpointResultList({ total: 0 });
|
||||
}
|
||||
throw new Error(`POST to '${requestOptions.path}' does not have a mock response!`);
|
||||
|
@ -1377,7 +1386,7 @@ describe('when on the endpoint list page', () => {
|
|||
let renderResult: ReturnType<AppContextTestRender['render']>;
|
||||
|
||||
const mockEndpointListApi = () => {
|
||||
const { hosts } = mockEndpointResultList();
|
||||
const { data: hosts } = mockEndpointResultList();
|
||||
hostInfo = {
|
||||
host_status: hosts[0].host_status,
|
||||
metadata: {
|
||||
|
|
|
@ -11,6 +11,7 @@ import { ManagementContainer } from './index';
|
|||
import '../../common/mock/match_media.ts';
|
||||
import { AppContextTestRender, createAppRootMockRenderer } from '../../common/mock/endpoint';
|
||||
import { useUserPrivileges } from '../../common/components/user_privileges';
|
||||
import { endpointPageHttpMock } from './endpoint_hosts/mocks';
|
||||
|
||||
jest.mock('../../common/components/user_privileges');
|
||||
|
||||
|
@ -19,6 +20,7 @@ describe('when in the Administration tab', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
const mockedContext = createAppRootMockRenderer();
|
||||
endpointPageHttpMock(mockedContext.coreStart.http);
|
||||
render = () => mockedContext.render(<ManagementContainer />);
|
||||
mockedContext.history.push('/administration/endpoints');
|
||||
});
|
||||
|
|
|
@ -27,11 +27,7 @@ import { getPagingProperties, kibanaRequestToMetadataListESQuery } from './query
|
|||
import { PackagePolicy } from '../../../../../fleet/common/types/models';
|
||||
import { AgentNotFoundError } from '../../../../../fleet/server';
|
||||
import { EndpointAppContext, HostListQueryResult } from '../../types';
|
||||
import {
|
||||
GetMetadataListRequestSchema,
|
||||
GetMetadataListRequestSchemaV2,
|
||||
GetMetadataRequestSchema,
|
||||
} from './index';
|
||||
import { GetMetadataListRequestSchema, GetMetadataRequestSchema } from './index';
|
||||
import { findAllUnenrolledAgentIds } from './support/unenroll';
|
||||
import { getAllEndpointPackagePolicies } from './support/endpoint_package_policies';
|
||||
import { findAgentIdsByStatus } from './support/agent_status';
|
||||
|
@ -41,6 +37,7 @@ import { queryResponseToHostListResult } from './support/query_strategies';
|
|||
import { EndpointError, NotFoundError } from '../../errors';
|
||||
import { EndpointHostUnEnrolledError } from '../../services/metadata';
|
||||
import { CustomHttpRequestError } from '../../../utils/custom_http_request_error';
|
||||
import { GetMetadataListRequestQuery } from '../../../../common/endpoint/schema/metadata';
|
||||
|
||||
export interface MetadataRequestContext {
|
||||
esClient?: IScopedClusterClient;
|
||||
|
@ -163,15 +160,12 @@ export function getMetadataListRequestHandlerV2(
|
|||
logger: Logger
|
||||
): RequestHandler<
|
||||
unknown,
|
||||
TypeOf<typeof GetMetadataListRequestSchemaV2.query>,
|
||||
GetMetadataListRequestQuery,
|
||||
unknown,
|
||||
SecuritySolutionRequestHandlerContext
|
||||
> {
|
||||
return async (context, request, response) => {
|
||||
const endpointMetadataService = endpointAppContext.service.getEndpointMetadataService();
|
||||
if (!endpointMetadataService) {
|
||||
throw new EndpointError('endpoint metadata service not available');
|
||||
}
|
||||
|
||||
let doesUnitedIndexExist = false;
|
||||
let didUnitedIndexError = false;
|
||||
|
@ -191,6 +185,9 @@ export function getMetadataListRequestHandlerV2(
|
|||
didUnitedIndexError = true;
|
||||
}
|
||||
|
||||
const { endpointResultListDefaultPageSize, endpointResultListDefaultFirstPageIndex } =
|
||||
await endpointAppContext.config();
|
||||
|
||||
// If no unified Index present, then perform a search using the legacy approach
|
||||
if (!doesUnitedIndexExist || didUnitedIndexError) {
|
||||
const endpointPolicies = await getAllEndpointPackagePolicies(
|
||||
|
@ -208,8 +205,8 @@ export function getMetadataListRequestHandlerV2(
|
|||
body = {
|
||||
data: legacyResponse.hosts,
|
||||
total: legacyResponse.total,
|
||||
page: request.query.page,
|
||||
pageSize: request.query.pageSize,
|
||||
page: request.query.page || endpointResultListDefaultFirstPageIndex,
|
||||
pageSize: request.query.pageSize || endpointResultListDefaultPageSize,
|
||||
};
|
||||
return response.ok({ body });
|
||||
}
|
||||
|
@ -224,8 +221,8 @@ export function getMetadataListRequestHandlerV2(
|
|||
body = {
|
||||
data,
|
||||
total,
|
||||
page: request.query.page,
|
||||
pageSize: request.query.pageSize,
|
||||
page: request.query.page || endpointResultListDefaultFirstPageIndex,
|
||||
pageSize: request.query.pageSize || endpointResultListDefaultPageSize,
|
||||
};
|
||||
} catch (error) {
|
||||
return errorHandler(logger, response, error);
|
||||
|
@ -396,7 +393,7 @@ async function legacyListMetadataQuery(
|
|||
endpointAppContext: EndpointAppContext,
|
||||
logger: Logger,
|
||||
endpointPolicies: PackagePolicy[],
|
||||
queryOptions: TypeOf<typeof GetMetadataListRequestSchemaV2.query>
|
||||
queryOptions: GetMetadataListRequestQuery
|
||||
): Promise<HostResultList> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const agentService = endpointAppContext.service.getAgentService()!;
|
||||
|
@ -422,13 +419,15 @@ async function legacyListMetadataQuery(
|
|||
const statusAgentIds = await findAgentIdsByStatus(
|
||||
agentService,
|
||||
context.core.elasticsearch.client.asCurrentUser,
|
||||
queryOptions.hostStatuses
|
||||
queryOptions?.hostStatuses || []
|
||||
);
|
||||
|
||||
const { endpointResultListDefaultPageSize, endpointResultListDefaultFirstPageIndex } =
|
||||
await endpointAppContext.config();
|
||||
const queryParams = await kibanaRequestToMetadataListESQuery({
|
||||
page: queryOptions.page,
|
||||
pageSize: queryOptions.pageSize,
|
||||
kuery: queryOptions.kuery,
|
||||
page: queryOptions?.page || endpointResultListDefaultFirstPageIndex,
|
||||
pageSize: queryOptions?.pageSize || endpointResultListDefaultPageSize,
|
||||
kuery: queryOptions?.kuery || '',
|
||||
unenrolledAgentIds,
|
||||
statusAgentIds,
|
||||
});
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
HOST_METADATA_GET_ROUTE,
|
||||
HOST_METADATA_LIST_ROUTE,
|
||||
} from '../../../../common/endpoint/constants';
|
||||
import { GetMetadataListRequestSchemaV2 } from '../../../../common/endpoint/schema/metadata';
|
||||
|
||||
/* Filters that can be applied to the endpoint fetch route */
|
||||
export const endpointFilters = schema.object({
|
||||
|
@ -65,24 +66,6 @@ export const GetMetadataListRequestSchema = {
|
|||
),
|
||||
};
|
||||
|
||||
export const GetMetadataListRequestSchemaV2 = {
|
||||
query: schema.object({
|
||||
page: schema.number({ defaultValue: 0 }),
|
||||
pageSize: schema.number({ defaultValue: 10, min: 1, max: 10000 }),
|
||||
kuery: schema.maybe(schema.string()),
|
||||
hostStatuses: schema.arrayOf(
|
||||
schema.oneOf([
|
||||
schema.literal(HostStatus.HEALTHY.toString()),
|
||||
schema.literal(HostStatus.OFFLINE.toString()),
|
||||
schema.literal(HostStatus.UPDATING.toString()),
|
||||
schema.literal(HostStatus.UNHEALTHY.toString()),
|
||||
schema.literal(HostStatus.INACTIVE.toString()),
|
||||
]),
|
||||
{ defaultValue: [] }
|
||||
),
|
||||
}),
|
||||
};
|
||||
|
||||
export function registerEndpointRoutes(
|
||||
router: SecuritySolutionPluginRouter,
|
||||
endpointAppContext: EndpointAppContext
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query';
|
||||
import {
|
||||
metadataCurrentIndexPattern,
|
||||
|
@ -15,7 +14,7 @@ import {
|
|||
import { KibanaRequest } from '../../../../../../../src/core/server';
|
||||
import { EndpointAppContext } from '../../types';
|
||||
import { buildStatusesKuery } from './support/agent_status';
|
||||
import { GetMetadataListRequestSchemaV2 } from '.';
|
||||
import { GetMetadataListRequestQuery } from '../../../../common/endpoint/schema/metadata';
|
||||
|
||||
/**
|
||||
* 00000000-0000-0000-0000-000000000000 is initial Elastic Agent id sent by Endpoint before policy is configured
|
||||
|
@ -234,14 +233,11 @@ interface BuildUnitedIndexQueryResponse {
|
|||
}
|
||||
|
||||
export async function buildUnitedIndexQuery(
|
||||
{
|
||||
page = 0,
|
||||
pageSize = 10,
|
||||
hostStatuses = [],
|
||||
kuery = '',
|
||||
}: TypeOf<typeof GetMetadataListRequestSchemaV2.query>,
|
||||
queryOptions: GetMetadataListRequestQuery,
|
||||
endpointPolicyIds: string[] = []
|
||||
): Promise<BuildUnitedIndexQueryResponse> {
|
||||
const { page = 0, pageSize = 10, hostStatuses = [], kuery = '' } = queryOptions || {};
|
||||
|
||||
const statusesKuery = buildStatusesKuery(hostStatuses);
|
||||
|
||||
const filterIgnoredAgents = {
|
||||
|
|
|
@ -36,7 +36,7 @@ export function buildStatusesKuery(statusesToFilter: string[]): string | undefin
|
|||
export async function findAgentIdsByStatus(
|
||||
agentService: AgentService,
|
||||
esClient: ElasticsearchClient,
|
||||
statuses: string[] = [],
|
||||
statuses: string[],
|
||||
pageSize: number = 1000
|
||||
): Promise<string[]> {
|
||||
if (!statuses.length) {
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
SavedObjectsServiceStart,
|
||||
} from 'kibana/server';
|
||||
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { TransportResult } from '@elastic/elasticsearch';
|
||||
import { SearchTotalHits, SearchResponse } from '@elastic/elasticsearch/lib/api/types';
|
||||
import {
|
||||
|
@ -57,7 +56,7 @@ import { createInternalReadonlySoClient } from '../../utils/create_internal_read
|
|||
import { METADATA_UNITED_INDEX } from '../../../../common/endpoint/constants';
|
||||
import { getAllEndpointPackagePolicies } from '../../routes/metadata/support/endpoint_package_policies';
|
||||
import { getAgentStatus } from '../../../../../fleet/common/services/agent_status';
|
||||
import { GetMetadataListRequestSchemaV2 } from '../../routes/metadata';
|
||||
import { GetMetadataListRequestQuery } from '../../../../common/endpoint/schema/metadata';
|
||||
|
||||
type AgentPolicyWithPackagePolicies = Omit<AgentPolicy, 'package_policies'> & {
|
||||
package_policies: PackagePolicy[];
|
||||
|
@ -403,7 +402,7 @@ export class EndpointMetadataService {
|
|||
*/
|
||||
async getHostMetadataList(
|
||||
esClient: ElasticsearchClient,
|
||||
queryOptions: TypeOf<typeof GetMetadataListRequestSchemaV2.query>
|
||||
queryOptions: GetMetadataListRequestQuery
|
||||
): Promise<Pick<MetadataListResponse, 'data' | 'total'>> {
|
||||
const endpointPolicies = await getAllEndpointPackagePolicies(
|
||||
this.packagePolicyService,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue