[Security Solution] Rename Administration > Hosts subtab to Endpoints (#74287)
This commit is contained in:
parent
7b5df7ce3b
commit
80a5c4bef7
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { HostAction } from '../../management/pages/endpoint_hosts/store/action';
|
||||
import { EndpointAction } from '../../management/pages/endpoint_hosts/store/action';
|
||||
import { PolicyListAction } from '../../management/pages/policy/store/policy_list';
|
||||
import { PolicyDetailsAction } from '../../management/pages/policy/store/policy_details';
|
||||
|
||||
|
@ -13,4 +13,4 @@ export { dragAndDropActions } from './drag_and_drop';
|
|||
export { inputsActions } from './inputs';
|
||||
import { RoutingAction } from './routing';
|
||||
|
||||
export type AppAction = HostAction | RoutingAction | PolicyListAction | PolicyDetailsAction;
|
||||
export type AppAction = EndpointAction | RoutingAction | PolicyListAction | PolicyDetailsAction;
|
||||
|
|
|
@ -10,7 +10,7 @@ import { SecurityPageName } from '../../app/types';
|
|||
// --[ ROUTING ]---------------------------------------------------------------------------
|
||||
export const MANAGEMENT_APP_ID = `${APP_ID}:${SecurityPageName.administration}`;
|
||||
export const MANAGEMENT_ROUTING_ROOT_PATH = '';
|
||||
export const MANAGEMENT_ROUTING_HOSTS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.hosts})`;
|
||||
export const MANAGEMENT_ROUTING_ENDPOINTS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.endpoints})`;
|
||||
export const MANAGEMENT_ROUTING_POLICIES_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.policies})`;
|
||||
export const MANAGEMENT_ROUTING_POLICY_DETAILS_PATH = `${MANAGEMENT_ROUTING_ROOT_PATH}/:tabName(${AdministrationSubTab.policies})/:policyId`;
|
||||
|
||||
|
@ -21,5 +21,5 @@ export const MANAGEMENT_STORE_GLOBAL_NAMESPACE: ManagementStoreGlobalNamespace =
|
|||
export const MANAGEMENT_STORE_POLICY_LIST_NAMESPACE = 'policyList';
|
||||
/** Namespace within the Management state where policy details state is maintained */
|
||||
export const MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE = 'policyDetails';
|
||||
/** Namespace within the Management state where hosts state is maintained */
|
||||
export const MANAGEMENT_STORE_HOSTS_NAMESPACE = 'hosts';
|
||||
/** Namespace within the Management state where endpoint-host state is maintained */
|
||||
export const MANAGEMENT_STORE_ENDPOINTS_NAMESPACE = 'endpoints';
|
||||
|
|
|
@ -10,13 +10,13 @@ import { generatePath } from 'react-router-dom';
|
|||
import querystring from 'querystring';
|
||||
|
||||
import {
|
||||
MANAGEMENT_ROUTING_HOSTS_PATH,
|
||||
MANAGEMENT_ROUTING_ENDPOINTS_PATH,
|
||||
MANAGEMENT_ROUTING_POLICIES_PATH,
|
||||
MANAGEMENT_ROUTING_POLICY_DETAILS_PATH,
|
||||
} from './constants';
|
||||
import { AdministrationSubTab } from '../types';
|
||||
import { appendSearch } from '../../common/components/link_to/helpers';
|
||||
import { HostIndexUIQueryParams } from '../pages/endpoint_hosts/types';
|
||||
import { EndpointIndexUIQueryParams } from '../pages/endpoint_hosts/types';
|
||||
|
||||
// Taken from: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-559034150
|
||||
type ExactKeys<T1, T2> = Exclude<keyof T1, keyof T2> extends never ? T1 : never;
|
||||
|
@ -31,42 +31,44 @@ const querystringStringify: <ExpectedType extends object, ArgType>(
|
|||
params: Exact<ExpectedType, ArgType>
|
||||
) => string = querystring.stringify;
|
||||
|
||||
/** Make `selected_host` required */
|
||||
type HostDetailsUrlProps = Omit<HostIndexUIQueryParams, 'selected_host'> &
|
||||
Required<Pick<HostIndexUIQueryParams, 'selected_host'>>;
|
||||
/** Make `selected_endpoint` required */
|
||||
type EndpointDetailsUrlProps = Omit<EndpointIndexUIQueryParams, 'selected_endpoint'> &
|
||||
Required<Pick<EndpointIndexUIQueryParams, 'selected_endpoint'>>;
|
||||
|
||||
export const getHostListPath = (
|
||||
props: { name: 'default' | 'hostList' } & HostIndexUIQueryParams,
|
||||
export const getEndpointListPath = (
|
||||
props: { name: 'default' | 'endpointList' } & EndpointIndexUIQueryParams,
|
||||
search?: string
|
||||
) => {
|
||||
const { name, ...queryParams } = props;
|
||||
const urlQueryParams = querystringStringify<HostIndexUIQueryParams, typeof queryParams>(
|
||||
const urlQueryParams = querystringStringify<EndpointIndexUIQueryParams, typeof queryParams>(
|
||||
queryParams
|
||||
);
|
||||
const urlSearch = `${urlQueryParams && !isEmpty(search) ? '&' : ''}${search ?? ''}`;
|
||||
|
||||
if (name === 'hostList') {
|
||||
return `${generatePath(MANAGEMENT_ROUTING_HOSTS_PATH, {
|
||||
tabName: AdministrationSubTab.hosts,
|
||||
if (name === 'endpointList') {
|
||||
return `${generatePath(MANAGEMENT_ROUTING_ENDPOINTS_PATH, {
|
||||
tabName: AdministrationSubTab.endpoints,
|
||||
})}${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
|
||||
}
|
||||
return `${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
|
||||
};
|
||||
|
||||
export const getHostDetailsPath = (
|
||||
props: { name: 'hostDetails' | 'hostPolicyResponse' } & HostIndexUIQueryParams &
|
||||
HostDetailsUrlProps,
|
||||
export const getEndpointDetailsPath = (
|
||||
props: { name: 'endpointDetails' | 'endpointPolicyResponse' } & EndpointIndexUIQueryParams &
|
||||
EndpointDetailsUrlProps,
|
||||
search?: string
|
||||
) => {
|
||||
const { name, ...queryParams } = props;
|
||||
queryParams.show = (props.name === 'hostPolicyResponse'
|
||||
queryParams.show = (props.name === 'endpointPolicyResponse'
|
||||
? 'policy_response'
|
||||
: '') as HostIndexUIQueryParams['show'];
|
||||
const urlQueryParams = querystringStringify<HostDetailsUrlProps, typeof queryParams>(queryParams);
|
||||
: '') as EndpointIndexUIQueryParams['show'];
|
||||
const urlQueryParams = querystringStringify<EndpointDetailsUrlProps, typeof queryParams>(
|
||||
queryParams
|
||||
);
|
||||
const urlSearch = `${urlQueryParams && !isEmpty(search) ? '&' : ''}${search ?? ''}`;
|
||||
|
||||
return `${generatePath(MANAGEMENT_ROUTING_HOSTS_PATH, {
|
||||
tabName: AdministrationSubTab.hosts,
|
||||
return `${generatePath(MANAGEMENT_ROUTING_ENDPOINTS_PATH, {
|
||||
tabName: AdministrationSubTab.endpoints,
|
||||
})}${appendSearch(`${urlQueryParams ? `${urlQueryParams}${urlSearch}` : urlSearch}`)}`;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const HOSTS_TAB = i18n.translate('xpack.securitySolution.hostsTab', {
|
||||
defaultMessage: 'Hosts',
|
||||
export const ENDPOINTS_TAB = i18n.translate('xpack.securitySolution.endpointsTab', {
|
||||
defaultMessage: 'Endpoints',
|
||||
});
|
||||
|
||||
export const POLICIES_TAB = i18n.translate('xpack.securitySolution.policiesTab', {
|
||||
|
|
|
@ -116,7 +116,7 @@ const PolicyEmptyState = React.memo<{
|
|||
);
|
||||
});
|
||||
|
||||
const HostsEmptyState = React.memo<{
|
||||
const EndpointsEmptyState = React.memo<{
|
||||
loading: boolean;
|
||||
onActionClick: (event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;
|
||||
actionDisabled: boolean;
|
||||
|
@ -126,14 +126,14 @@ const HostsEmptyState = React.memo<{
|
|||
const policySteps = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.hostList.stepOneTitle', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.list.stepOneTitle', {
|
||||
defaultMessage: 'Select the integration you want to use',
|
||||
}),
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued" size="m" grow={false}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.stepOne"
|
||||
id="xpack.securitySolution.endpoint.list.stepOne"
|
||||
defaultMessage="Select from existing integrations. This can be changed later."
|
||||
/>
|
||||
</EuiText>
|
||||
|
@ -151,7 +151,7 @@ const HostsEmptyState = React.memo<{
|
|||
return loading ? (
|
||||
<EuiSelectableMessage>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.loadingPolicies"
|
||||
id="xpack.securitySolution.endpoint.list.loadingPolicies"
|
||||
defaultMessage="Loading integrations"
|
||||
/>
|
||||
</EuiSelectableMessage>
|
||||
|
@ -159,7 +159,7 @@ const HostsEmptyState = React.memo<{
|
|||
list
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.noPolicies"
|
||||
id="xpack.securitySolution.endpoint.list.noPolicies"
|
||||
defaultMessage="There are no integrations."
|
||||
/>
|
||||
);
|
||||
|
@ -169,7 +169,7 @@ const HostsEmptyState = React.memo<{
|
|||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.hostList.stepTwoTitle', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.list.stepTwoTitle', {
|
||||
defaultMessage:
|
||||
'Enroll your agents enabled with Endpoint Security through Ingest Manager',
|
||||
}),
|
||||
|
@ -179,7 +179,7 @@ const HostsEmptyState = React.memo<{
|
|||
<EuiFlexItem>
|
||||
<EuiText color="subdued" size="m" grow={false}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.stepTwo"
|
||||
id="xpack.securitySolution.endpoint.list.stepTwo"
|
||||
defaultMessage="You’ll be provided with the necessary commands to get started."
|
||||
/>
|
||||
</EuiText>
|
||||
|
@ -211,13 +211,13 @@ const HostsEmptyState = React.memo<{
|
|||
steps={policySteps}
|
||||
headerComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.noEndpointsPrompt"
|
||||
id="xpack.securitySolution.endpoint.list.noEndpointsPrompt"
|
||||
defaultMessage="Next step: Enroll an Agent with Elastic Endpoint Security"
|
||||
/>
|
||||
}
|
||||
bodyComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.noEndpointsInstructions"
|
||||
id="xpack.securitySolution.endpoint.list.noEndpointsInstructions"
|
||||
defaultMessage="You’ve added the Endpoint Security integration. Now enroll your agents using the steps below."
|
||||
/>
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ const ManagementEmptyState = React.memo<{
|
|||
});
|
||||
|
||||
PolicyEmptyState.displayName = 'PolicyEmptyState';
|
||||
HostsEmptyState.displayName = 'HostsEmptyState';
|
||||
EndpointsEmptyState.displayName = 'HostsEmptyState';
|
||||
ManagementEmptyState.displayName = 'ManagementEmptyState';
|
||||
|
||||
export { PolicyEmptyState, HostsEmptyState };
|
||||
export { PolicyEmptyState, EndpointsEmptyState as HostsEmptyState };
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import React, { memo } from 'react';
|
||||
import { HostList } from './view';
|
||||
import { MANAGEMENT_ROUTING_HOSTS_PATH } from '../../common/constants';
|
||||
import { EndpointList } from './view';
|
||||
import { MANAGEMENT_ROUTING_ENDPOINTS_PATH } from '../../common/constants';
|
||||
import { NotFoundPage } from '../../../app/404';
|
||||
|
||||
/**
|
||||
* Provides the routing container for the hosts related views
|
||||
*/
|
||||
export const HostsContainer = memo(() => {
|
||||
export const EndpointsContainer = memo(() => {
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={MANAGEMENT_ROUTING_HOSTS_PATH} exact component={HostList} />
|
||||
<Route path={MANAGEMENT_ROUTING_ENDPOINTS_PATH} exact component={EndpointList} />
|
||||
<Route path="*" component={NotFoundPage} />
|
||||
</Switch>
|
||||
);
|
||||
});
|
||||
|
||||
HostsContainer.displayName = 'HostsContainer';
|
||||
EndpointsContainer.displayName = 'EndpointsContainer';
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
import React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { HostList } from './view';
|
||||
import { EndpointList } from './view';
|
||||
|
||||
export const EndpointHostsRoutes: React.FC = () => (
|
||||
<Switch>
|
||||
<Route path="/:pageName(endpoint-hosts)">
|
||||
<HostList />
|
||||
<Route path="/:pageName(endpoint-endpoints)">
|
||||
<EndpointList />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
|
|
|
@ -12,35 +12,35 @@ import {
|
|||
import { ServerApiError } from '../../../../common/types';
|
||||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
import { GetPackagesResponse } from '../../../../../../ingest_manager/common';
|
||||
import { HostState } from '../types';
|
||||
import { EndpointState } from '../types';
|
||||
|
||||
interface ServerReturnedHostList {
|
||||
type: 'serverReturnedHostList';
|
||||
interface ServerReturnedEndpointList {
|
||||
type: 'serverReturnedEndpointList';
|
||||
payload: HostResultList;
|
||||
}
|
||||
|
||||
interface ServerFailedToReturnHostList {
|
||||
type: 'serverFailedToReturnHostList';
|
||||
interface ServerFailedToReturnEndpointList {
|
||||
type: 'serverFailedToReturnEndpointList';
|
||||
payload: ServerApiError;
|
||||
}
|
||||
|
||||
interface ServerReturnedHostDetails {
|
||||
type: 'serverReturnedHostDetails';
|
||||
interface ServerReturnedEndpointDetails {
|
||||
type: 'serverReturnedEndpointDetails';
|
||||
payload: HostInfo;
|
||||
}
|
||||
|
||||
interface ServerFailedToReturnHostDetails {
|
||||
type: 'serverFailedToReturnHostDetails';
|
||||
interface ServerFailedToReturnEndpointDetails {
|
||||
type: 'serverFailedToReturnEndpointDetails';
|
||||
payload: ServerApiError;
|
||||
}
|
||||
|
||||
interface ServerReturnedHostPolicyResponse {
|
||||
type: 'serverReturnedHostPolicyResponse';
|
||||
interface ServerReturnedEndpointPolicyResponse {
|
||||
type: 'serverReturnedEndpointPolicyResponse';
|
||||
payload: GetHostPolicyResponse;
|
||||
}
|
||||
|
||||
interface ServerFailedToReturnHostPolicyResponse {
|
||||
type: 'serverFailedToReturnHostPolicyResponse';
|
||||
interface ServerFailedToReturnEndpointPolicyResponse {
|
||||
type: 'serverFailedToReturnEndpointPolicyResponse';
|
||||
payload: ServerApiError;
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,8 @@ interface UserSelectedEndpointPolicy {
|
|||
};
|
||||
}
|
||||
|
||||
interface ServerCancelledHostListLoading {
|
||||
type: 'serverCancelledHostListLoading';
|
||||
interface ServerCancelledEndpointListLoading {
|
||||
type: 'serverCancelledEndpointListLoading';
|
||||
}
|
||||
|
||||
interface ServerCancelledPolicyItemsLoading {
|
||||
|
@ -76,28 +76,28 @@ interface ServerReturnedEndpointPackageInfo {
|
|||
payload: GetPackagesResponse['response'][0];
|
||||
}
|
||||
|
||||
interface ServerReturnedHostNonExistingPolicies {
|
||||
type: 'serverReturnedHostNonExistingPolicies';
|
||||
payload: HostState['nonExistingPolicies'];
|
||||
interface ServerReturnedEndpointNonExistingPolicies {
|
||||
type: 'serverReturnedEndpointNonExistingPolicies';
|
||||
payload: EndpointState['nonExistingPolicies'];
|
||||
}
|
||||
|
||||
interface ServerReturnedHostExistValue {
|
||||
type: 'serverReturnedHostExistValue';
|
||||
interface ServerReturnedEndpointExistValue {
|
||||
type: 'serverReturnedEndpointExistValue';
|
||||
payload: boolean;
|
||||
}
|
||||
|
||||
export type HostAction =
|
||||
| ServerReturnedHostList
|
||||
| ServerFailedToReturnHostList
|
||||
| ServerReturnedHostDetails
|
||||
| ServerFailedToReturnHostDetails
|
||||
| ServerReturnedHostPolicyResponse
|
||||
| ServerFailedToReturnHostPolicyResponse
|
||||
export type EndpointAction =
|
||||
| ServerReturnedEndpointList
|
||||
| ServerFailedToReturnEndpointList
|
||||
| ServerReturnedEndpointDetails
|
||||
| ServerFailedToReturnEndpointDetails
|
||||
| ServerReturnedEndpointPolicyResponse
|
||||
| ServerFailedToReturnEndpointPolicyResponse
|
||||
| ServerReturnedPoliciesForOnboarding
|
||||
| ServerFailedToReturnPoliciesForOnboarding
|
||||
| UserSelectedEndpointPolicy
|
||||
| ServerCancelledHostListLoading
|
||||
| ServerReturnedHostExistValue
|
||||
| ServerCancelledEndpointListLoading
|
||||
| ServerReturnedEndpointExistValue
|
||||
| ServerCancelledPolicyItemsLoading
|
||||
| ServerReturnedEndpointPackageInfo
|
||||
| ServerReturnedHostNonExistingPolicies;
|
||||
| ServerReturnedEndpointNonExistingPolicies;
|
||||
|
|
|
@ -13,41 +13,41 @@ import { coreMock } from '../../../../../../../../src/core/public/mocks';
|
|||
import { HostResultList, AppLocation } from '../../../../../common/endpoint/types';
|
||||
import { DepsStartMock, depsStartMock } from '../../../../common/mock/endpoint';
|
||||
|
||||
import { hostMiddlewareFactory } from './middleware';
|
||||
import { endpointMiddlewareFactory } from './middleware';
|
||||
|
||||
import { hostListReducer } from './reducer';
|
||||
import { endpointListReducer } from './reducer';
|
||||
|
||||
import { uiQueryParams } from './selectors';
|
||||
import { mockHostResultList } from './mock_host_result_list';
|
||||
import { HostState, HostIndexUIQueryParams } from '../types';
|
||||
import { mockEndpointResultList } from './mock_endpoint_result_list';
|
||||
import { EndpointState, EndpointIndexUIQueryParams } from '../types';
|
||||
import {
|
||||
MiddlewareActionSpyHelper,
|
||||
createSpyMiddleware,
|
||||
} from '../../../../common/store/test_utils';
|
||||
import { getHostListPath } from '../../../common/routing';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
|
||||
describe('host list pagination: ', () => {
|
||||
describe('endpoint list pagination: ', () => {
|
||||
let fakeCoreStart: jest.Mocked<CoreStart>;
|
||||
let depsStart: DepsStartMock;
|
||||
let fakeHttpServices: jest.Mocked<HttpSetup>;
|
||||
let history: History<AppLocation['state']>;
|
||||
let store: Store;
|
||||
let queryParams: () => HostIndexUIQueryParams;
|
||||
let queryParams: () => EndpointIndexUIQueryParams;
|
||||
let waitForAction: MiddlewareActionSpyHelper['waitForAction'];
|
||||
let actionSpyMiddleware;
|
||||
const getEndpointListApiResponse = (): HostResultList => {
|
||||
return mockHostResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
return mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
};
|
||||
|
||||
let historyPush: (params: HostIndexUIQueryParams) => void;
|
||||
let historyPush: (params: EndpointIndexUIQueryParams) => void;
|
||||
beforeEach(() => {
|
||||
fakeCoreStart = coreMock.createStart();
|
||||
depsStart = depsStartMock();
|
||||
fakeHttpServices = fakeCoreStart.http as jest.Mocked<HttpSetup>;
|
||||
history = createBrowserHistory();
|
||||
const middleware = hostMiddlewareFactory(fakeCoreStart, depsStart);
|
||||
({ actionSpyMiddleware, waitForAction } = createSpyMiddleware<HostState>());
|
||||
store = createStore(hostListReducer, applyMiddleware(middleware, actionSpyMiddleware));
|
||||
const middleware = endpointMiddlewareFactory(fakeCoreStart, depsStart);
|
||||
({ actionSpyMiddleware, waitForAction } = createSpyMiddleware<EndpointState>());
|
||||
store = createStore(endpointListReducer, applyMiddleware(middleware, actionSpyMiddleware));
|
||||
|
||||
history.listen((location) => {
|
||||
store.dispatch({ type: 'userChangedUrl', payload: location });
|
||||
|
@ -55,12 +55,12 @@ describe('host list pagination: ', () => {
|
|||
|
||||
queryParams = () => uiQueryParams(store.getState());
|
||||
|
||||
historyPush = (nextQueryParams: HostIndexUIQueryParams): void => {
|
||||
return history.push(getHostListPath({ name: 'hostList', ...nextQueryParams }));
|
||||
historyPush = (nextQueryParams: EndpointIndexUIQueryParams): void => {
|
||||
return history.push(getEndpointListPath({ name: 'endpointList', ...nextQueryParams }));
|
||||
};
|
||||
});
|
||||
|
||||
describe('when the user enteres the host list for the first time', () => {
|
||||
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);
|
||||
|
@ -70,10 +70,10 @@ describe('host list pagination: ', () => {
|
|||
type: 'userChangedUrl',
|
||||
payload: {
|
||||
...history.location,
|
||||
pathname: getHostListPath({ name: 'hostList' }),
|
||||
pathname: getEndpointListPath({ name: 'endpointList' }),
|
||||
},
|
||||
});
|
||||
await waitForAction('serverReturnedHostList');
|
||||
await waitForAction('serverReturnedEndpointList');
|
||||
expect(fakeHttpServices.post).toHaveBeenCalledWith('/api/endpoint/metadata', {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: '0' }, { page_size: '10' }],
|
|
@ -5,24 +5,24 @@
|
|||
*/
|
||||
|
||||
import { createStore, Dispatch, Store } from 'redux';
|
||||
import { HostState } from '../types';
|
||||
import { EndpointState } from '../types';
|
||||
import { listData } from './selectors';
|
||||
import { mockHostResultList } from './mock_host_result_list';
|
||||
import { HostAction } from './action';
|
||||
import { hostListReducer } from './reducer';
|
||||
import { mockEndpointResultList } from './mock_endpoint_result_list';
|
||||
import { EndpointAction } from './action';
|
||||
import { endpointListReducer } from './reducer';
|
||||
|
||||
describe('HostList store concerns', () => {
|
||||
let store: Store<HostState>;
|
||||
let dispatch: Dispatch<HostAction>;
|
||||
describe('EndpointList store concerns', () => {
|
||||
let store: Store<EndpointState>;
|
||||
let dispatch: Dispatch<EndpointAction>;
|
||||
const createTestStore = () => {
|
||||
store = createStore(hostListReducer);
|
||||
store = createStore(endpointListReducer);
|
||||
dispatch = store.dispatch;
|
||||
};
|
||||
|
||||
const loadDataToStore = () => {
|
||||
dispatch({
|
||||
type: 'serverReturnedHostList',
|
||||
payload: mockHostResultList({ request_page_size: 1, request_page_index: 1, total: 10 }),
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 }),
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -51,18 +51,18 @@ describe('HostList store concerns', () => {
|
|||
policyItemsLoading: false,
|
||||
endpointPackageInfo: undefined,
|
||||
nonExistingPolicies: {},
|
||||
hostsExist: true,
|
||||
endpointsExist: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('it handles `serverReturnedHostList', () => {
|
||||
const payload = mockHostResultList({
|
||||
test('it handles `serverReturnedEndpointList', () => {
|
||||
const payload = mockEndpointResultList({
|
||||
request_page_size: 1,
|
||||
request_page_index: 1,
|
||||
total: 10,
|
||||
});
|
||||
dispatch({
|
||||
type: 'serverReturnedHostList',
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload,
|
||||
});
|
||||
|
||||
|
@ -80,7 +80,7 @@ describe('HostList store concerns', () => {
|
|||
loadDataToStore();
|
||||
});
|
||||
|
||||
test('it selects `hostListData`', () => {
|
||||
test('it selects `endpointListData`', () => {
|
||||
const currentState = store.getState();
|
||||
expect(listData(currentState)).toEqual(currentState.hosts);
|
||||
});
|
||||
|
|
|
@ -16,36 +16,36 @@ import {
|
|||
} from '../../../../common/store/test_utils';
|
||||
import { Immutable, HostResultList } from '../../../../../common/endpoint/types';
|
||||
import { AppAction } from '../../../../common/store/actions';
|
||||
import { mockHostResultList } from './mock_host_result_list';
|
||||
import { mockEndpointResultList } from './mock_endpoint_result_list';
|
||||
import { listData } from './selectors';
|
||||
import { HostState } from '../types';
|
||||
import { hostListReducer } from './reducer';
|
||||
import { hostMiddlewareFactory } from './middleware';
|
||||
import { getHostListPath } from '../../../common/routing';
|
||||
import { EndpointState } from '../types';
|
||||
import { endpointListReducer } from './reducer';
|
||||
import { endpointMiddlewareFactory } from './middleware';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
|
||||
describe('host list middleware', () => {
|
||||
describe('endpoint list middleware', () => {
|
||||
let fakeCoreStart: jest.Mocked<CoreStart>;
|
||||
let depsStart: DepsStartMock;
|
||||
let fakeHttpServices: jest.Mocked<HttpSetup>;
|
||||
type HostListStore = Store<Immutable<HostState>, Immutable<AppAction>>;
|
||||
let store: HostListStore;
|
||||
let getState: HostListStore['getState'];
|
||||
let dispatch: HostListStore['dispatch'];
|
||||
type EndpointListStore = Store<Immutable<EndpointState>, Immutable<AppAction>>;
|
||||
let store: EndpointListStore;
|
||||
let getState: EndpointListStore['getState'];
|
||||
let dispatch: EndpointListStore['dispatch'];
|
||||
let waitForAction: MiddlewareActionSpyHelper['waitForAction'];
|
||||
let actionSpyMiddleware;
|
||||
|
||||
let history: History<never>;
|
||||
const getEndpointListApiResponse = (): HostResultList => {
|
||||
return mockHostResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
return mockEndpointResultList({ request_page_size: 1, request_page_index: 1, total: 10 });
|
||||
};
|
||||
beforeEach(() => {
|
||||
fakeCoreStart = coreMock.createStart({ basePath: '/mock' });
|
||||
depsStart = depsStartMock();
|
||||
fakeHttpServices = fakeCoreStart.http as jest.Mocked<HttpSetup>;
|
||||
({ actionSpyMiddleware, waitForAction } = createSpyMiddleware<HostState>());
|
||||
({ actionSpyMiddleware, waitForAction } = createSpyMiddleware<EndpointState>());
|
||||
store = createStore(
|
||||
hostListReducer,
|
||||
applyMiddleware(hostMiddlewareFactory(fakeCoreStart, depsStart), actionSpyMiddleware)
|
||||
endpointListReducer,
|
||||
applyMiddleware(endpointMiddlewareFactory(fakeCoreStart, depsStart), actionSpyMiddleware)
|
||||
);
|
||||
getState = store.getState;
|
||||
dispatch = store.dispatch;
|
||||
|
@ -60,10 +60,10 @@ describe('host list middleware', () => {
|
|||
type: 'userChangedUrl',
|
||||
payload: {
|
||||
...history.location,
|
||||
pathname: getHostListPath({ name: 'hostList' }),
|
||||
pathname: getEndpointListPath({ name: 'endpointList' }),
|
||||
},
|
||||
});
|
||||
await waitForAction('serverReturnedHostList');
|
||||
await waitForAction('serverReturnedEndpointList');
|
||||
expect(fakeHttpServices.post).toHaveBeenCalledWith('/api/endpoint/metadata', {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: '0' }, { page_size: '10' }],
|
||||
|
|
|
@ -9,14 +9,14 @@ import { HostInfo, HostResultList } from '../../../../../common/endpoint/types';
|
|||
import { GetPolicyListResponse } from '../../policy/types';
|
||||
import { ImmutableMiddlewareFactory } from '../../../../common/store';
|
||||
import {
|
||||
isOnHostPage,
|
||||
hasSelectedHost,
|
||||
isOnEndpointPage,
|
||||
hasSelectedEndpoint,
|
||||
uiQueryParams,
|
||||
listData,
|
||||
endpointPackageInfo,
|
||||
nonExistingPolicies,
|
||||
} from './selectors';
|
||||
import { HostState } from '../types';
|
||||
import { EndpointState } from '../types';
|
||||
import {
|
||||
sendGetEndpointSpecificPackageConfigs,
|
||||
sendGetEndpointSecurityPackage,
|
||||
|
@ -24,16 +24,16 @@ import {
|
|||
} from '../../policy/store/policy_list/services/ingest';
|
||||
import { AGENT_CONFIG_SAVED_OBJECT_TYPE } from '../../../../../../ingest_manager/common';
|
||||
|
||||
export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (coreStart) => {
|
||||
export const endpointMiddlewareFactory: ImmutableMiddlewareFactory<EndpointState> = (coreStart) => {
|
||||
return ({ getState, dispatch }) => (next) => async (action) => {
|
||||
next(action);
|
||||
const state = getState();
|
||||
|
||||
// Host list
|
||||
// Endpoint list
|
||||
if (
|
||||
action.type === 'userChangedUrl' &&
|
||||
isOnHostPage(state) &&
|
||||
hasSelectedHost(state) !== true
|
||||
isOnEndpointPage(state) &&
|
||||
hasSelectedEndpoint(state) !== true
|
||||
) {
|
||||
if (!endpointPackageInfo(state)) {
|
||||
sendGetEndpointSecurityPackage(coreStart.http)
|
||||
|
@ -50,30 +50,30 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
}
|
||||
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(state);
|
||||
let hostResponse;
|
||||
let endpointResponse;
|
||||
|
||||
try {
|
||||
hostResponse = await coreStart.http.post<HostResultList>('/api/endpoint/metadata', {
|
||||
endpointResponse = await coreStart.http.post<HostResultList>('/api/endpoint/metadata', {
|
||||
body: JSON.stringify({
|
||||
paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }],
|
||||
}),
|
||||
});
|
||||
hostResponse.request_page_index = Number(pageIndex);
|
||||
endpointResponse.request_page_index = Number(pageIndex);
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedHostList',
|
||||
payload: hostResponse,
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: endpointResponse,
|
||||
});
|
||||
|
||||
getNonExistingPoliciesForHostsList(
|
||||
getNonExistingPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
hostResponse.hosts,
|
||||
endpointResponse.hosts,
|
||||
nonExistingPolicies(state)
|
||||
)
|
||||
.then((missingPolicies) => {
|
||||
if (missingPolicies !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedHostNonExistingPolicies',
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: missingPolicies,
|
||||
});
|
||||
}
|
||||
|
@ -83,24 +83,24 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
.catch((error) => console.error(error));
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnHostList',
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
||||
// No hosts, so we should check to see if there are policies for onboarding
|
||||
if (hostResponse && hostResponse.hosts.length === 0) {
|
||||
// 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 hosts actually do exist before pulling in data for the onboarding
|
||||
// so we check first if endpoints actually do exist before pulling in data for the onboarding
|
||||
// messages.
|
||||
if (await doHostsExist(http)) {
|
||||
if (await doEndpointsExist(http)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedHostExistValue',
|
||||
type: 'serverReturnedEndpointExistValue',
|
||||
payload: false,
|
||||
});
|
||||
|
||||
|
@ -135,13 +135,13 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
}
|
||||
}
|
||||
|
||||
// Host Details
|
||||
if (action.type === 'userChangedUrl' && hasSelectedHost(state) === true) {
|
||||
// Endpoint Details
|
||||
if (action.type === 'userChangedUrl' && hasSelectedEndpoint(state) === true) {
|
||||
dispatch({
|
||||
type: 'serverCancelledPolicyItemsLoading',
|
||||
});
|
||||
|
||||
// If user navigated directly to a host details page, load the host list
|
||||
// If user navigated directly to a endpoint details page, load the endpoint list
|
||||
if (listData(state).length === 0) {
|
||||
const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(state);
|
||||
try {
|
||||
|
@ -152,11 +152,11 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
});
|
||||
response.request_page_index = Number(pageIndex);
|
||||
dispatch({
|
||||
type: 'serverReturnedHostList',
|
||||
type: 'serverReturnedEndpointList',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
getNonExistingPoliciesForHostsList(
|
||||
getNonExistingPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
response.hosts,
|
||||
nonExistingPolicies(state)
|
||||
|
@ -164,7 +164,7 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
.then((missingPolicies) => {
|
||||
if (missingPolicies !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedHostNonExistingPolicies',
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: missingPolicies,
|
||||
});
|
||||
}
|
||||
|
@ -174,31 +174,35 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
.catch((error) => console.error(error));
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnHostList',
|
||||
type: 'serverFailedToReturnEndpointList',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'serverCancelledHostListLoading',
|
||||
type: 'serverCancelledEndpointListLoading',
|
||||
});
|
||||
}
|
||||
|
||||
// call the host details api
|
||||
const { selected_host: selectedHost } = uiQueryParams(state);
|
||||
// call the endpoint details api
|
||||
const { selected_endpoint: selectedEndpoint } = uiQueryParams(state);
|
||||
try {
|
||||
const response = await coreStart.http.get<HostInfo>(
|
||||
`/api/endpoint/metadata/${selectedHost}`
|
||||
`/api/endpoint/metadata/${selectedEndpoint}`
|
||||
);
|
||||
dispatch({
|
||||
type: 'serverReturnedHostDetails',
|
||||
type: 'serverReturnedEndpointDetails',
|
||||
payload: response,
|
||||
});
|
||||
getNonExistingPoliciesForHostsList(coreStart.http, [response], nonExistingPolicies(state))
|
||||
getNonExistingPoliciesForEndpointsList(
|
||||
coreStart.http,
|
||||
[response],
|
||||
nonExistingPolicies(state)
|
||||
)
|
||||
.then((missingPolicies) => {
|
||||
if (missingPolicies !== undefined) {
|
||||
dispatch({
|
||||
type: 'serverReturnedHostNonExistingPolicies',
|
||||
type: 'serverReturnedEndpointNonExistingPolicies',
|
||||
payload: missingPolicies,
|
||||
});
|
||||
}
|
||||
|
@ -208,7 +212,7 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
.catch((error) => console.error(error));
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnHostDetails',
|
||||
type: 'serverFailedToReturnEndpointDetails',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
@ -216,15 +220,15 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
// call the policy response api
|
||||
try {
|
||||
const policyResponse = await coreStart.http.get(`/api/endpoint/policy_response`, {
|
||||
query: { hostId: selectedHost },
|
||||
query: { hostId: selectedEndpoint },
|
||||
});
|
||||
dispatch({
|
||||
type: 'serverReturnedHostPolicyResponse',
|
||||
type: 'serverReturnedEndpointPolicyResponse',
|
||||
payload: policyResponse,
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch({
|
||||
type: 'serverFailedToReturnHostPolicyResponse',
|
||||
type: 'serverFailedToReturnEndpointPolicyResponse',
|
||||
payload: error,
|
||||
});
|
||||
}
|
||||
|
@ -232,11 +236,11 @@ export const hostMiddlewareFactory: ImmutableMiddlewareFactory<HostState> = (cor
|
|||
};
|
||||
};
|
||||
|
||||
const getNonExistingPoliciesForHostsList = async (
|
||||
const getNonExistingPoliciesForEndpointsList = async (
|
||||
http: HttpStart,
|
||||
hosts: HostResultList['hosts'],
|
||||
currentNonExistingPolicies: HostState['nonExistingPolicies']
|
||||
): Promise<HostState['nonExistingPolicies'] | undefined> => {
|
||||
currentNonExistingPolicies: EndpointState['nonExistingPolicies']
|
||||
): Promise<EndpointState['nonExistingPolicies'] | undefined> => {
|
||||
if (hosts.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -266,14 +270,14 @@ const getNonExistingPoliciesForHostsList = async (
|
|||
)})`,
|
||||
},
|
||||
})
|
||||
).items.reduce<HostState['nonExistingPolicies']>((list, agentConfig) => {
|
||||
).items.reduce<EndpointState['nonExistingPolicies']>((list, agentConfig) => {
|
||||
(agentConfig.package_configs as string[]).forEach((packageConfig) => {
|
||||
list[packageConfig as string] = true;
|
||||
});
|
||||
return list;
|
||||
}, {});
|
||||
|
||||
const nonExisting = policyIdsToCheck.reduce<HostState['nonExistingPolicies']>(
|
||||
const nonExisting = policyIdsToCheck.reduce<EndpointState['nonExistingPolicies']>(
|
||||
(list, policyId) => {
|
||||
if (policiesFound[policyId]) {
|
||||
return list;
|
||||
|
@ -291,7 +295,7 @@ const getNonExistingPoliciesForHostsList = async (
|
|||
return nonExisting;
|
||||
};
|
||||
|
||||
const doHostsExist = async (http: HttpStart): Promise<boolean> => {
|
||||
const doEndpointsExist = async (http: HttpStart): Promise<boolean> => {
|
||||
try {
|
||||
return (
|
||||
(
|
||||
|
@ -304,7 +308,7 @@ const doHostsExist = async (http: HttpStart): Promise<boolean> => {
|
|||
);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`error while trying to check if hosts exist`);
|
||||
console.error(`error while trying to check if endpoints exist`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import { GetPolicyListResponse } from '../../policy/types';
|
|||
|
||||
const generator = new EndpointDocGenerator('seed');
|
||||
|
||||
export const mockHostResultList: (options?: {
|
||||
export const mockEndpointResultList: (options?: {
|
||||
total?: number;
|
||||
request_page_size?: number;
|
||||
request_page_index?: number;
|
||||
|
@ -62,7 +62,7 @@ export const mockHostResultList: (options?: {
|
|||
/**
|
||||
* returns a mocked API response for retrieving a single host metadata
|
||||
*/
|
||||
export const mockHostDetailsApiResult = (): HostInfo => {
|
||||
export const mockEndpointDetailsApiResult = (): HostInfo => {
|
||||
return {
|
||||
metadata: generator.generateHostMetadata(),
|
||||
host_status: HostStatus.ERROR,
|
||||
|
@ -73,14 +73,14 @@ export const mockHostDetailsApiResult = (): HostInfo => {
|
|||
* Mock API handlers used by the Endpoint Host list. It also sets up a list of
|
||||
* API handlers for Host details based on a list of Host results.
|
||||
*/
|
||||
const hostListApiPathHandlerMocks = ({
|
||||
hostsResults = mockHostResultList({ total: 3 }).hosts,
|
||||
const endpointListApiPathHandlerMocks = ({
|
||||
endpointsResults = mockEndpointResultList({ total: 3 }).hosts,
|
||||
epmPackages = [generator.generateEpmPackage()],
|
||||
endpointPackageConfigs = [],
|
||||
policyResponse = generator.generatePolicyResponse(),
|
||||
}: {
|
||||
/** route handlers will be setup for each individual host in this array */
|
||||
hostsResults?: HostResultList['hosts'];
|
||||
endpointsResults?: HostResultList['hosts'];
|
||||
epmPackages?: GetPackagesResponse['response'];
|
||||
endpointPackageConfigs?: GetPolicyListResponse['items'];
|
||||
policyResponse?: HostPolicyResponse;
|
||||
|
@ -94,17 +94,17 @@ const hostListApiPathHandlerMocks = ({
|
|||
};
|
||||
},
|
||||
|
||||
// host list
|
||||
// endpoint list
|
||||
'/api/endpoint/metadata': (): HostResultList => {
|
||||
return {
|
||||
hosts: hostsResults,
|
||||
hosts: endpointsResults,
|
||||
request_page_size: 10,
|
||||
request_page_index: 0,
|
||||
total: hostsResults?.length || 0,
|
||||
total: endpointsResults?.length || 0,
|
||||
};
|
||||
},
|
||||
|
||||
// Do policies referenced in host list exist
|
||||
// Do policies referenced in endpoint list exist
|
||||
// just returns 1 single agent config that includes all of the packageConfig IDs provided
|
||||
[INGEST_API_AGENT_CONFIGS]: (): GetAgentConfigsResponse => {
|
||||
const agentConfig = generator.generateAgentConfig();
|
||||
|
@ -137,9 +137,9 @@ const hostListApiPathHandlerMocks = ({
|
|||
},
|
||||
};
|
||||
|
||||
// Build a GET route handler for each host details based on the list of Hosts passed on input
|
||||
if (hostsResults) {
|
||||
hostsResults.forEach((host) => {
|
||||
// Build a GET route handler for each endpoint details based on the list of Endpoints passed on input
|
||||
if (endpointsResults) {
|
||||
endpointsResults.forEach((host) => {
|
||||
// @ts-expect-error
|
||||
apiHandlers[`/api/endpoint/metadata/${host.metadata.host.id}`] = () => host;
|
||||
});
|
||||
|
@ -149,33 +149,36 @@ const hostListApiPathHandlerMocks = ({
|
|||
};
|
||||
|
||||
/**
|
||||
* Sets up mock impelementations in support of the Hosts list view
|
||||
* Sets up mock impelementations in support of the Endpoints list view
|
||||
*
|
||||
* @param mockedHttpService
|
||||
* @param hostsResults
|
||||
* @param endpointsResults
|
||||
* @param pathHandlersOptions
|
||||
*/
|
||||
export const setHostListApiMockImplementation: (
|
||||
export const setEndpointListApiMockImplementation: (
|
||||
mockedHttpService: jest.Mocked<HttpStart>,
|
||||
apiResponses?: Parameters<typeof hostListApiPathHandlerMocks>[0]
|
||||
apiResponses?: Parameters<typeof endpointListApiPathHandlerMocks>[0]
|
||||
) => void = (
|
||||
mockedHttpService,
|
||||
{ hostsResults = mockHostResultList({ total: 3 }).hosts, ...pathHandlersOptions } = {}
|
||||
{ endpointsResults = mockEndpointResultList({ total: 3 }).hosts, ...pathHandlersOptions } = {}
|
||||
) => {
|
||||
const apiHandlers = hostListApiPathHandlerMocks({ ...pathHandlersOptions, hostsResults });
|
||||
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 hosts
|
||||
// First time called, return list of endpoints
|
||||
.mockImplementationOnce(async () => {
|
||||
return apiHandlers['/api/endpoint/metadata']();
|
||||
});
|
||||
|
||||
// If the hosts list results is zero, then mock the second call to `/metadata` to return
|
||||
// empty list - indicating there are no hosts currently present on the system
|
||||
if (!hostsResults.length) {
|
||||
// If the endpoints list results is zero, then mock the second 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']();
|
||||
});
|
|
@ -4,13 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isOnHostPage, hasSelectedHost } from './selectors';
|
||||
import { HostState } from '../types';
|
||||
import { isOnEndpointPage, hasSelectedEndpoint } from './selectors';
|
||||
import { EndpointState } from '../types';
|
||||
import { AppAction } from '../../../../common/store/actions';
|
||||
import { ImmutableReducer } from '../../../../common/store';
|
||||
import { Immutable } from '../../../../../common/endpoint/types';
|
||||
|
||||
export const initialHostListState: Immutable<HostState> = {
|
||||
export const initialEndpointListState: Immutable<EndpointState> = {
|
||||
hosts: [],
|
||||
pageSize: 10,
|
||||
pageIndex: 0,
|
||||
|
@ -29,15 +29,15 @@ export const initialHostListState: Immutable<HostState> = {
|
|||
policyItemsLoading: false,
|
||||
endpointPackageInfo: undefined,
|
||||
nonExistingPolicies: {},
|
||||
hostsExist: true,
|
||||
endpointsExist: true,
|
||||
};
|
||||
|
||||
/* eslint-disable-next-line complexity */
|
||||
export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
||||
state = initialHostListState,
|
||||
export const endpointListReducer: ImmutableReducer<EndpointState, AppAction> = (
|
||||
state = initialEndpointListState,
|
||||
action
|
||||
) => {
|
||||
if (action.type === 'serverReturnedHostList') {
|
||||
if (action.type === 'serverReturnedEndpointList') {
|
||||
const {
|
||||
hosts,
|
||||
total,
|
||||
|
@ -53,13 +53,13 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
loading: false,
|
||||
error: undefined,
|
||||
};
|
||||
} else if (action.type === 'serverFailedToReturnHostList') {
|
||||
} else if (action.type === 'serverFailedToReturnEndpointList') {
|
||||
return {
|
||||
...state,
|
||||
error: action.payload,
|
||||
loading: false,
|
||||
};
|
||||
} else if (action.type === 'serverReturnedHostNonExistingPolicies') {
|
||||
} else if (action.type === 'serverReturnedEndpointNonExistingPolicies') {
|
||||
return {
|
||||
...state,
|
||||
nonExistingPolicies: {
|
||||
|
@ -67,14 +67,14 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
...action.payload,
|
||||
},
|
||||
};
|
||||
} else if (action.type === 'serverReturnedHostDetails') {
|
||||
} else if (action.type === 'serverReturnedEndpointDetails') {
|
||||
return {
|
||||
...state,
|
||||
details: action.payload.metadata,
|
||||
detailsLoading: false,
|
||||
detailsError: undefined,
|
||||
};
|
||||
} else if (action.type === 'serverFailedToReturnHostDetails') {
|
||||
} else if (action.type === 'serverFailedToReturnEndpointDetails') {
|
||||
return {
|
||||
...state,
|
||||
detailsError: action.payload,
|
||||
|
@ -92,14 +92,14 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
error: action.payload,
|
||||
policyItemsLoading: false,
|
||||
};
|
||||
} else if (action.type === 'serverReturnedHostPolicyResponse') {
|
||||
} else if (action.type === 'serverReturnedEndpointPolicyResponse') {
|
||||
return {
|
||||
...state,
|
||||
policyResponse: action.payload.policy_response,
|
||||
policyResponseLoading: false,
|
||||
policyResponseError: undefined,
|
||||
};
|
||||
} else if (action.type === 'serverFailedToReturnHostPolicyResponse') {
|
||||
} else if (action.type === 'serverFailedToReturnEndpointPolicyResponse') {
|
||||
return {
|
||||
...state,
|
||||
policyResponseError: action.payload,
|
||||
|
@ -111,7 +111,7 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
selectedPolicyId: action.payload.selectedPolicyId,
|
||||
policyResponseLoading: false,
|
||||
};
|
||||
} else if (action.type === 'serverCancelledHostListLoading') {
|
||||
} else if (action.type === 'serverCancelledEndpointListLoading') {
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
|
@ -126,22 +126,22 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
...state,
|
||||
endpointPackageInfo: action.payload,
|
||||
};
|
||||
} else if (action.type === 'serverReturnedHostExistValue') {
|
||||
} else if (action.type === 'serverReturnedEndpointExistValue') {
|
||||
return {
|
||||
...state,
|
||||
hostsExist: action.payload,
|
||||
endpointsExist: action.payload,
|
||||
};
|
||||
} else if (action.type === 'userChangedUrl') {
|
||||
const newState: Immutable<HostState> = {
|
||||
const newState: Immutable<EndpointState> = {
|
||||
...state,
|
||||
location: action.payload,
|
||||
};
|
||||
const isCurrentlyOnListPage = isOnHostPage(newState) && !hasSelectedHost(newState);
|
||||
const wasPreviouslyOnListPage = isOnHostPage(state) && !hasSelectedHost(state);
|
||||
const isCurrentlyOnDetailsPage = isOnHostPage(newState) && hasSelectedHost(newState);
|
||||
const wasPreviouslyOnDetailsPage = isOnHostPage(state) && hasSelectedHost(state);
|
||||
const isCurrentlyOnListPage = isOnEndpointPage(newState) && !hasSelectedEndpoint(newState);
|
||||
const wasPreviouslyOnListPage = isOnEndpointPage(state) && !hasSelectedEndpoint(state);
|
||||
const isCurrentlyOnDetailsPage = isOnEndpointPage(newState) && hasSelectedEndpoint(newState);
|
||||
const wasPreviouslyOnDetailsPage = isOnEndpointPage(state) && hasSelectedEndpoint(state);
|
||||
|
||||
// if on the host list page for the first time, return new location and load list
|
||||
// if on the endpoint list page for the first time, return new location and load list
|
||||
if (isCurrentlyOnListPage) {
|
||||
if (!wasPreviouslyOnListPage) {
|
||||
return {
|
||||
|
@ -154,7 +154,7 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
};
|
||||
}
|
||||
} else if (isCurrentlyOnDetailsPage) {
|
||||
// if previous page was the list or another host details page, load host details only
|
||||
// if previous page was the list or another endpoint details page, load endpoint details only
|
||||
if (wasPreviouslyOnDetailsPage || wasPreviouslyOnListPage) {
|
||||
return {
|
||||
...state,
|
||||
|
@ -166,7 +166,7 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
policyResponseError: undefined,
|
||||
};
|
||||
} else {
|
||||
// if previous page was not host list or host details, load both list and details
|
||||
// if previous page was not endpoint list or endpoint details, load both list and details
|
||||
return {
|
||||
...state,
|
||||
location: action.payload,
|
||||
|
@ -180,14 +180,14 @@ export const hostListReducer: ImmutableReducer<HostState, AppAction> = (
|
|||
};
|
||||
}
|
||||
}
|
||||
// otherwise we are not on a host list or details page
|
||||
// otherwise we are not on a endpoint list or details page
|
||||
return {
|
||||
...state,
|
||||
location: action.payload,
|
||||
error: undefined,
|
||||
detailsError: undefined,
|
||||
policyResponseError: undefined,
|
||||
hostsExist: true,
|
||||
endpointsExist: true,
|
||||
};
|
||||
}
|
||||
return state;
|
||||
|
|
|
@ -14,36 +14,36 @@ import {
|
|||
HostPolicyResponseConfiguration,
|
||||
HostPolicyResponseActionStatus,
|
||||
} from '../../../../../common/endpoint/types';
|
||||
import { HostState, HostIndexUIQueryParams } from '../types';
|
||||
import { MANAGEMENT_ROUTING_HOSTS_PATH } from '../../../common/constants';
|
||||
import { EndpointState, EndpointIndexUIQueryParams } from '../types';
|
||||
import { MANAGEMENT_ROUTING_ENDPOINTS_PATH } from '../../../common/constants';
|
||||
|
||||
const PAGE_SIZES = Object.freeze([10, 20, 50]);
|
||||
|
||||
export const listData = (state: Immutable<HostState>) => state.hosts;
|
||||
export const listData = (state: Immutable<EndpointState>) => state.hosts;
|
||||
|
||||
export const pageIndex = (state: Immutable<HostState>): number => state.pageIndex;
|
||||
export const pageIndex = (state: Immutable<EndpointState>): number => state.pageIndex;
|
||||
|
||||
export const pageSize = (state: Immutable<HostState>): number => state.pageSize;
|
||||
export const pageSize = (state: Immutable<EndpointState>): number => state.pageSize;
|
||||
|
||||
export const totalHits = (state: Immutable<HostState>): number => state.total;
|
||||
export const totalHits = (state: Immutable<EndpointState>): number => state.total;
|
||||
|
||||
export const listLoading = (state: Immutable<HostState>): boolean => state.loading;
|
||||
export const listLoading = (state: Immutable<EndpointState>): boolean => state.loading;
|
||||
|
||||
export const listError = (state: Immutable<HostState>) => state.error;
|
||||
export const listError = (state: Immutable<EndpointState>) => state.error;
|
||||
|
||||
export const detailsData = (state: Immutable<HostState>) => state.details;
|
||||
export const detailsData = (state: Immutable<EndpointState>) => state.details;
|
||||
|
||||
export const detailsLoading = (state: Immutable<HostState>): boolean => state.detailsLoading;
|
||||
export const detailsLoading = (state: Immutable<EndpointState>): boolean => state.detailsLoading;
|
||||
|
||||
export const detailsError = (state: Immutable<HostState>) => state.detailsError;
|
||||
export const detailsError = (state: Immutable<EndpointState>) => state.detailsError;
|
||||
|
||||
export const policyItems = (state: Immutable<HostState>) => state.policyItems;
|
||||
export const policyItems = (state: Immutable<EndpointState>) => state.policyItems;
|
||||
|
||||
export const policyItemsLoading = (state: Immutable<HostState>) => state.policyItemsLoading;
|
||||
export const policyItemsLoading = (state: Immutable<EndpointState>) => state.policyItemsLoading;
|
||||
|
||||
export const selectedPolicyId = (state: Immutable<HostState>) => state.selectedPolicyId;
|
||||
export const selectedPolicyId = (state: Immutable<EndpointState>) => state.selectedPolicyId;
|
||||
|
||||
export const endpointPackageInfo = (state: Immutable<HostState>) => state.endpointPackageInfo;
|
||||
export const endpointPackageInfo = (state: Immutable<EndpointState>) => state.endpointPackageInfo;
|
||||
|
||||
export const endpointPackageVersion = createSelector(
|
||||
endpointPackageInfo,
|
||||
|
@ -53,14 +53,14 @@ export const endpointPackageVersion = createSelector(
|
|||
/**
|
||||
* Returns the full policy response from the endpoint after a user modifies a policy.
|
||||
*/
|
||||
const detailsPolicyAppliedResponse = (state: Immutable<HostState>) =>
|
||||
const detailsPolicyAppliedResponse = (state: Immutable<EndpointState>) =>
|
||||
state.policyResponse && state.policyResponse.Endpoint.policy.applied;
|
||||
|
||||
/**
|
||||
* Returns the response configurations from the endpoint after a user modifies a policy.
|
||||
*/
|
||||
export const policyResponseConfigurations: (
|
||||
state: Immutable<HostState>
|
||||
state: Immutable<EndpointState>
|
||||
) => undefined | Immutable<HostPolicyResponseConfiguration> = createSelector(
|
||||
detailsPolicyAppliedResponse,
|
||||
(applied) => {
|
||||
|
@ -72,7 +72,7 @@ export const policyResponseConfigurations: (
|
|||
* Returns a map of the number of failed and warning policy response actions per configuration.
|
||||
*/
|
||||
export const policyResponseFailedOrWarningActionCount: (
|
||||
state: Immutable<HostState>
|
||||
state: Immutable<EndpointState>
|
||||
) => Map<string, number> = createSelector(detailsPolicyAppliedResponse, (applied) => {
|
||||
const failureOrWarningByConfigType = new Map<string, number>();
|
||||
if (applied?.response?.configurations !== undefined && applied?.actions !== undefined) {
|
||||
|
@ -98,7 +98,7 @@ export const policyResponseFailedOrWarningActionCount: (
|
|||
* Returns the actions taken by the endpoint for each response configuration after a user modifies a policy.
|
||||
*/
|
||||
export const policyResponseActions: (
|
||||
state: Immutable<HostState>
|
||||
state: Immutable<EndpointState>
|
||||
) => undefined | Immutable<HostPolicyResponseAppliedAction[]> = createSelector(
|
||||
detailsPolicyAppliedResponse,
|
||||
(applied) => {
|
||||
|
@ -106,32 +106,32 @@ export const policyResponseActions: (
|
|||
}
|
||||
);
|
||||
|
||||
export const policyResponseLoading = (state: Immutable<HostState>): boolean =>
|
||||
export const policyResponseLoading = (state: Immutable<EndpointState>): boolean =>
|
||||
state.policyResponseLoading;
|
||||
|
||||
export const policyResponseError = (state: Immutable<HostState>) => state.policyResponseError;
|
||||
export const policyResponseError = (state: Immutable<EndpointState>) => state.policyResponseError;
|
||||
|
||||
export const isOnHostPage = (state: Immutable<HostState>) => {
|
||||
export const isOnEndpointPage = (state: Immutable<EndpointState>) => {
|
||||
return (
|
||||
matchPath(state.location?.pathname ?? '', {
|
||||
path: MANAGEMENT_ROUTING_HOSTS_PATH,
|
||||
path: MANAGEMENT_ROUTING_ENDPOINTS_PATH,
|
||||
exact: true,
|
||||
}) !== null
|
||||
);
|
||||
};
|
||||
|
||||
export const uiQueryParams: (
|
||||
state: Immutable<HostState>
|
||||
) => Immutable<HostIndexUIQueryParams> = createSelector(
|
||||
(state: Immutable<HostState>) => state.location,
|
||||
(location: Immutable<HostState>['location']) => {
|
||||
const data: HostIndexUIQueryParams = { page_index: '0', page_size: '10' };
|
||||
state: Immutable<EndpointState>
|
||||
) => Immutable<EndpointIndexUIQueryParams> = createSelector(
|
||||
(state: Immutable<EndpointState>) => state.location,
|
||||
(location: Immutable<EndpointState>['location']) => {
|
||||
const data: EndpointIndexUIQueryParams = { page_index: '0', page_size: '10' };
|
||||
if (location) {
|
||||
// Removes the `?` from the beginning of query string if it exists
|
||||
const query = querystring.parse(location.search.slice(1));
|
||||
|
||||
const keys: Array<keyof HostIndexUIQueryParams> = [
|
||||
'selected_host',
|
||||
const keys: Array<keyof EndpointIndexUIQueryParams> = [
|
||||
'selected_endpoint',
|
||||
'page_size',
|
||||
'page_index',
|
||||
'show',
|
||||
|
@ -171,15 +171,15 @@ export const uiQueryParams: (
|
|||
}
|
||||
);
|
||||
|
||||
export const hasSelectedHost: (state: Immutable<HostState>) => boolean = createSelector(
|
||||
export const hasSelectedEndpoint: (state: Immutable<EndpointState>) => boolean = createSelector(
|
||||
uiQueryParams,
|
||||
({ selected_host: selectedHost }) => {
|
||||
return selectedHost !== undefined;
|
||||
({ selected_endpoint: selectedEndpoint }) => {
|
||||
return selectedEndpoint !== undefined;
|
||||
}
|
||||
);
|
||||
|
||||
/** What policy details panel view to show */
|
||||
export const showView: (state: HostState) => 'policy_response' | 'details' = createSelector(
|
||||
export const showView: (state: EndpointState) => 'policy_response' | 'details' = createSelector(
|
||||
uiQueryParams,
|
||||
(searchParams) => {
|
||||
return searchParams.show === 'policy_response' ? 'policy_response' : 'details';
|
||||
|
@ -189,7 +189,7 @@ export const showView: (state: HostState) => 'policy_response' | 'details' = cre
|
|||
/**
|
||||
* Returns the Policy Response overall status
|
||||
*/
|
||||
export const policyResponseStatus: (state: Immutable<HostState>) => string = createSelector(
|
||||
export const policyResponseStatus: (state: Immutable<EndpointState>) => string = createSelector(
|
||||
(state) => state.policyResponse,
|
||||
(policyResponse) => {
|
||||
return (policyResponse && policyResponse?.Endpoint?.policy?.applied?.status) || '';
|
||||
|
@ -197,15 +197,16 @@ export const policyResponseStatus: (state: Immutable<HostState>) => string = cre
|
|||
);
|
||||
|
||||
/**
|
||||
* returns the list of known non-existing polices that may have been in the Host API response.
|
||||
* returns the list of known non-existing polices that may have been in the Endpoint API response.
|
||||
* @param state
|
||||
*/
|
||||
export const nonExistingPolicies: (
|
||||
state: Immutable<HostState>
|
||||
) => Immutable<HostState['nonExistingPolicies']> = (state) => state.nonExistingPolicies;
|
||||
state: Immutable<EndpointState>
|
||||
) => Immutable<EndpointState['nonExistingPolicies']> = (state) => state.nonExistingPolicies;
|
||||
|
||||
/**
|
||||
* Return boolean that indicates whether hosts exist
|
||||
* Return boolean that indicates whether endpoints exist
|
||||
* @param state
|
||||
*/
|
||||
export const hostsExist: (state: Immutable<HostState>) => boolean = (state) => state.hostsExist;
|
||||
export const endpointsExist: (state: Immutable<EndpointState>) => boolean = (state) =>
|
||||
state.endpointsExist;
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import { ServerApiError } from '../../../common/types';
|
||||
import { GetPackagesResponse } from '../../../../../ingest_manager/common';
|
||||
|
||||
export interface HostState {
|
||||
export interface EndpointState {
|
||||
/** list of host **/
|
||||
hosts: HostInfo[];
|
||||
/** number of items per page */
|
||||
|
@ -53,15 +53,15 @@ export interface HostState {
|
|||
/** tracks the list of policies IDs used in Host metadata that may no longer exist */
|
||||
nonExistingPolicies: Record<string, boolean>;
|
||||
/** Tracks whether hosts exist and helps control if onboarding should be visible */
|
||||
hostsExist: boolean;
|
||||
endpointsExist: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query params on the host page parsed from the URL
|
||||
*/
|
||||
export interface HostIndexUIQueryParams {
|
||||
/** Selected host id shows host details flyout */
|
||||
selected_host?: string;
|
||||
export interface EndpointIndexUIQueryParams {
|
||||
/** Selected endpoint id shows host details flyout */
|
||||
selected_endpoint?: string;
|
||||
/** How many items to show in list */
|
||||
page_size?: string;
|
||||
/** Which page to show */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import { EuiLink, EuiLinkAnchorProps } from '@elastic/eui';
|
||||
import { useHostSelector } from '../hooks';
|
||||
import { useEndpointSelector } from '../hooks';
|
||||
import { nonExistingPolicies } from '../../store/selectors';
|
||||
import { getPolicyDetailPath } from '../../../../common/routing';
|
||||
import { useFormatUrl } from '../../../../../common/components/link_to';
|
||||
|
@ -18,12 +18,12 @@ import { useNavigateByRouterEventHandler } from '../../../../../common/hooks/end
|
|||
* the `nonExistingPolicies` value in the store. If it does not exist, then regular
|
||||
* text is returned.
|
||||
*/
|
||||
export const HostPolicyLink = memo<
|
||||
export const EndpointPolicyLink = memo<
|
||||
Omit<EuiLinkAnchorProps, 'href'> & {
|
||||
policyId: string;
|
||||
}
|
||||
>(({ policyId, children, onClick, ...otherProps }) => {
|
||||
const missingPolicies = useHostSelector(nonExistingPolicies);
|
||||
const missingPolicies = useEndpointSelector(nonExistingPolicies);
|
||||
const { formatUrl } = useFormatUrl(SecurityPageName.administration);
|
||||
const { toRoutePath, toRouteUrl } = useMemo(() => {
|
||||
const toPath = getPolicyDetailPath(policyId);
|
||||
|
@ -50,4 +50,4 @@ export const HostPolicyLink = memo<
|
|||
);
|
||||
});
|
||||
|
||||
HostPolicyLink.displayName = 'HostPolicyLink';
|
||||
EndpointPolicyLink.displayName = 'EndpointPolicyLink';
|
|
@ -19,18 +19,18 @@ import React, { memo, useMemo } from 'react';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { HostMetadata } from '../../../../../../common/endpoint/types';
|
||||
import { useHostSelector, useAgentDetailsIngestUrl } from '../hooks';
|
||||
import { useEndpointSelector, useAgentDetailsIngestUrl } from '../hooks';
|
||||
import { useNavigateToAppEventHandler } from '../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { policyResponseStatus, uiQueryParams } from '../../store/selectors';
|
||||
import { POLICY_STATUS_TO_HEALTH_COLOR } from '../host_constants';
|
||||
import { FormattedDateAndTime } from '../../../../../common/components/endpoint/formatted_date_time';
|
||||
import { useNavigateByRouterEventHandler } from '../../../../../common/hooks/endpoint/use_navigate_by_router_event_handler';
|
||||
import { LinkToApp } from '../../../../../common/components/endpoint/link_to_app';
|
||||
import { getHostDetailsPath } from '../../../../common/routing';
|
||||
import { getEndpointDetailsPath } from '../../../../common/routing';
|
||||
import { SecurityPageName } from '../../../../../app/types';
|
||||
import { useFormatUrl } from '../../../../../common/components/link_to';
|
||||
import { AgentDetailsReassignConfigAction } from '../../../../../../../ingest_manager/public';
|
||||
import { HostPolicyLink } from '../components/host_policy_link';
|
||||
import { EndpointPolicyLink } from '../components/endpoint_policy_link';
|
||||
|
||||
const HostIds = styled(EuiListGroupItem)`
|
||||
margin-top: 0;
|
||||
|
@ -51,15 +51,15 @@ const LinkToExternalApp = styled.div`
|
|||
|
||||
const openReassignFlyoutSearch = '?openReassignFlyout=true';
|
||||
|
||||
export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
||||
export const EndpointDetails = memo(({ details }: { details: HostMetadata }) => {
|
||||
const agentId = details.elastic.agent.id;
|
||||
const {
|
||||
url: agentDetailsUrl,
|
||||
appId: ingestAppId,
|
||||
appPath: agentDetailsAppPath,
|
||||
} = useAgentDetailsIngestUrl(agentId);
|
||||
const queryParams = useHostSelector(uiQueryParams);
|
||||
const policyStatus = useHostSelector(
|
||||
const queryParams = useEndpointSelector(uiQueryParams);
|
||||
const policyStatus = useEndpointSelector(
|
||||
policyResponseStatus
|
||||
) as keyof typeof POLICY_STATUS_TO_HEALTH_COLOR;
|
||||
const { formatUrl } = useFormatUrl(SecurityPageName.administration);
|
||||
|
@ -67,13 +67,13 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
const detailsResultsUpper = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.os', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.os', {
|
||||
defaultMessage: 'OS',
|
||||
}),
|
||||
description: details.host.os.full,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.lastSeen', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.lastSeen', {
|
||||
defaultMessage: 'Last Seen',
|
||||
}),
|
||||
description: <FormattedDateAndTime date={new Date(details['@timestamp'])} />,
|
||||
|
@ -83,19 +83,19 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
|
||||
const [policyResponseUri, policyResponseRoutePath] = useMemo(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { selected_host, show, ...currentUrlParams } = queryParams;
|
||||
const { selected_endpoint, show, ...currentUrlParams } = queryParams;
|
||||
return [
|
||||
formatUrl(
|
||||
getHostDetailsPath({
|
||||
name: 'hostPolicyResponse',
|
||||
getEndpointDetailsPath({
|
||||
name: 'endpointPolicyResponse',
|
||||
...currentUrlParams,
|
||||
selected_host: details.host.id,
|
||||
selected_endpoint: details.host.id,
|
||||
})
|
||||
),
|
||||
getHostDetailsPath({
|
||||
name: 'hostPolicyResponse',
|
||||
getEndpointDetailsPath({
|
||||
name: 'endpointPolicyResponse',
|
||||
...currentUrlParams,
|
||||
selected_host: details.host.id,
|
||||
selected_endpoint: details.host.id,
|
||||
}),
|
||||
];
|
||||
}, [details.host.id, formatUrl, queryParams]);
|
||||
|
@ -110,7 +110,10 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
onDoneNavigateTo: [
|
||||
'securitySolution:administration',
|
||||
{
|
||||
path: getHostDetailsPath({ name: 'hostDetails', selected_host: details.host.id }),
|
||||
path: getEndpointDetailsPath({
|
||||
name: 'endpointDetails',
|
||||
selected_endpoint: details.host.id,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -121,22 +124,22 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
const detailsResultsPolicy = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policy', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.policy', {
|
||||
defaultMessage: 'Integration',
|
||||
}),
|
||||
description: (
|
||||
<>
|
||||
<HostPolicyLink
|
||||
<EndpointPolicyLink
|
||||
policyId={details.Endpoint.policy.applied.id}
|
||||
data-test-subj="policyDetailsValue"
|
||||
>
|
||||
{details.Endpoint.policy.applied.name}
|
||||
</HostPolicyLink>
|
||||
</EndpointPolicyLink>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policyStatus', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.policyStatus', {
|
||||
defaultMessage: 'Configuration response',
|
||||
}),
|
||||
description: (
|
||||
|
@ -152,7 +155,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
>
|
||||
<EuiText size="m">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.host.details.policyStatusValue"
|
||||
id="xpack.securitySolution.endpoint.details.policyStatusValue"
|
||||
defaultMessage="{policyStatus, select, success {Success} warning {Warning} failure {Failed} other {Unknown}}"
|
||||
values={{ policyStatus }}
|
||||
/>
|
||||
|
@ -166,7 +169,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
const detailsResultsLower = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.ipAddress', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.ipAddress', {
|
||||
defaultMessage: 'IP Address',
|
||||
}),
|
||||
description: (
|
||||
|
@ -178,13 +181,13 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.hostname', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.hostname', {
|
||||
defaultMessage: 'Hostname',
|
||||
}),
|
||||
description: details.host.hostname,
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.endpointVersion', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.endpointVersion', {
|
||||
defaultMessage: 'Endpoint Version',
|
||||
}),
|
||||
description: details.agent.version,
|
||||
|
@ -197,13 +200,13 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
<EuiDescriptionList
|
||||
type="column"
|
||||
listItems={detailsResultsUpper}
|
||||
data-test-subj="hostDetailsUpperList"
|
||||
data-test-subj="endpointDetailsUpperList"
|
||||
/>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
<EuiDescriptionList
|
||||
type="column"
|
||||
listItems={detailsResultsPolicy}
|
||||
data-test-subj="hostDetailsPolicyList"
|
||||
data-test-subj="endpointDetailsPolicyList"
|
||||
/>
|
||||
<LinkToExternalApp>
|
||||
<LinkToApp
|
||||
|
@ -211,11 +214,11 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
appPath={agentDetailsWithFlyoutPath}
|
||||
href={agentDetailsWithFlyoutUrl}
|
||||
onClick={handleReassignEndpointsClick}
|
||||
data-test-subj="hostDetailsLinkToIngest"
|
||||
data-test-subj="endpointDetailsLinkToIngest"
|
||||
>
|
||||
<EuiIcon type="savedObjectsApp" className="linkToAppIcon" />
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.host.details.linkToIngestTitle"
|
||||
id="xpack.securitySolution.endpoint.details.linkToIngestTitle"
|
||||
defaultMessage="Reassign Configuration"
|
||||
/>
|
||||
<EuiIcon type="popout" className="linkToAppPopoutIcon" />
|
||||
|
@ -225,10 +228,10 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
|
|||
<EuiDescriptionList
|
||||
type="column"
|
||||
listItems={detailsResultsLower}
|
||||
data-test-subj="hostDetailsLowerList"
|
||||
data-test-subj="endpointDetailsLowerList"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
HostDetails.displayName = 'HostDetails';
|
||||
EndpointDetails.displayName = 'EndpointDetails';
|
|
@ -19,7 +19,7 @@ import { useHistory } from 'react-router-dom';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useToasts } from '../../../../../common/lib/kibana';
|
||||
import { useHostSelector } from '../hooks';
|
||||
import { useEndpointSelector } from '../hooks';
|
||||
import { urlFromQueryParams } from '../url_from_query_params';
|
||||
import {
|
||||
uiQueryParams,
|
||||
|
@ -33,36 +33,39 @@ import {
|
|||
policyResponseError,
|
||||
policyResponseLoading,
|
||||
} from '../../store/selectors';
|
||||
import { HostDetails } from './host_details';
|
||||
import { EndpointDetails } from './endpoint_details';
|
||||
import { PolicyResponse } from './policy_response';
|
||||
import { HostMetadata } from '../../../../../../common/endpoint/types';
|
||||
import { FlyoutSubHeader, FlyoutSubHeaderProps } from './components/flyout_sub_header';
|
||||
import { useNavigateByRouterEventHandler } from '../../../../../common/hooks/endpoint/use_navigate_by_router_event_handler';
|
||||
import { getHostListPath } from '../../../../common/routing';
|
||||
import { getEndpointListPath } from '../../../../common/routing';
|
||||
import { SecurityPageName } from '../../../../../app/types';
|
||||
import { useFormatUrl } from '../../../../../common/components/link_to';
|
||||
|
||||
export const HostDetailsFlyout = memo(() => {
|
||||
export const EndpointDetailsFlyout = memo(() => {
|
||||
const history = useHistory();
|
||||
const toasts = useToasts();
|
||||
const queryParams = useHostSelector(uiQueryParams);
|
||||
const { selected_host: selectedHost, ...queryParamsWithoutSelectedHost } = queryParams;
|
||||
const details = useHostSelector(detailsData);
|
||||
const loading = useHostSelector(detailsLoading);
|
||||
const error = useHostSelector(detailsError);
|
||||
const show = useHostSelector(showView);
|
||||
const queryParams = useEndpointSelector(uiQueryParams);
|
||||
const {
|
||||
selected_endpoint: selectedEndpoint,
|
||||
...queryParamsWithoutSelectedEndpoint
|
||||
} = queryParams;
|
||||
const details = useEndpointSelector(detailsData);
|
||||
const loading = useEndpointSelector(detailsLoading);
|
||||
const error = useEndpointSelector(detailsError);
|
||||
const show = useEndpointSelector(showView);
|
||||
|
||||
const handleFlyoutClose = useCallback(() => {
|
||||
history.push(urlFromQueryParams(queryParamsWithoutSelectedHost));
|
||||
}, [history, queryParamsWithoutSelectedHost]);
|
||||
history.push(urlFromQueryParams(queryParamsWithoutSelectedEndpoint));
|
||||
}, [history, queryParamsWithoutSelectedEndpoint]);
|
||||
|
||||
useEffect(() => {
|
||||
if (error !== undefined) {
|
||||
toasts.addDanger({
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.details.errorTitle', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.details.errorTitle', {
|
||||
defaultMessage: 'Could not find host',
|
||||
}),
|
||||
text: i18n.translate('xpack.securitySolution.endpoint.host.details.errorBody', {
|
||||
text: i18n.translate('xpack.securitySolution.endpoint.details.errorBody', {
|
||||
defaultMessage: 'Please exit the flyout and select an available host.',
|
||||
}),
|
||||
});
|
||||
|
@ -73,12 +76,12 @@ export const HostDetailsFlyout = memo(() => {
|
|||
<EuiFlyout
|
||||
onClose={handleFlyoutClose}
|
||||
style={{ zIndex: 4001 }}
|
||||
data-test-subj="hostDetailsFlyout"
|
||||
data-test-subj="endpointDetailsFlyout"
|
||||
size="s"
|
||||
>
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
<EuiTitle size="s">
|
||||
<h2 data-test-subj="hostDetailsFlyoutTitle">
|
||||
<h2 data-test-subj="endpointDetailsFlyoutTitle">
|
||||
{loading ? <EuiLoadingContent lines={1} /> : details?.host?.hostname}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
|
@ -93,8 +96,8 @@ export const HostDetailsFlyout = memo(() => {
|
|||
<>
|
||||
{show === 'details' && (
|
||||
<>
|
||||
<EuiFlyoutBody data-test-subj="hostDetailsFlyoutBody">
|
||||
<HostDetails details={details} />
|
||||
<EuiFlyoutBody data-test-subj="endpointDetailsFlyoutBody">
|
||||
<EndpointDetails details={details} />
|
||||
</EuiFlyoutBody>
|
||||
</>
|
||||
)}
|
||||
|
@ -105,31 +108,31 @@ export const HostDetailsFlyout = memo(() => {
|
|||
);
|
||||
});
|
||||
|
||||
HostDetailsFlyout.displayName = 'HostDetailsFlyout';
|
||||
EndpointDetailsFlyout.displayName = 'EndpointDetailsFlyout';
|
||||
|
||||
const PolicyResponseFlyoutPanel = memo<{
|
||||
hostMeta: HostMetadata;
|
||||
}>(({ hostMeta }) => {
|
||||
const { show, ...queryParams } = useHostSelector(uiQueryParams);
|
||||
const responseConfig = useHostSelector(policyResponseConfigurations);
|
||||
const responseActions = useHostSelector(policyResponseActions);
|
||||
const responseAttentionCount = useHostSelector(policyResponseFailedOrWarningActionCount);
|
||||
const loading = useHostSelector(policyResponseLoading);
|
||||
const error = useHostSelector(policyResponseError);
|
||||
const { show, ...queryParams } = useEndpointSelector(uiQueryParams);
|
||||
const responseConfig = useEndpointSelector(policyResponseConfigurations);
|
||||
const responseActions = useEndpointSelector(policyResponseActions);
|
||||
const responseAttentionCount = useEndpointSelector(policyResponseFailedOrWarningActionCount);
|
||||
const loading = useEndpointSelector(policyResponseLoading);
|
||||
const error = useEndpointSelector(policyResponseError);
|
||||
const { formatUrl } = useFormatUrl(SecurityPageName.administration);
|
||||
const [detailsUri, detailsRoutePath] = useMemo(
|
||||
() => [
|
||||
formatUrl(
|
||||
getHostListPath({
|
||||
name: 'hostList',
|
||||
getEndpointListPath({
|
||||
name: 'endpointList',
|
||||
...queryParams,
|
||||
selected_host: hostMeta.host.id,
|
||||
selected_endpoint: hostMeta.host.id,
|
||||
})
|
||||
),
|
||||
getHostListPath({
|
||||
name: 'hostList',
|
||||
getEndpointListPath({
|
||||
name: 'endpointList',
|
||||
...queryParams,
|
||||
selected_host: hostMeta.host.id,
|
||||
selected_endpoint: hostMeta.host.id,
|
||||
}),
|
||||
],
|
||||
[hostMeta.host.id, formatUrl, queryParams]
|
||||
|
@ -137,7 +140,7 @@ const PolicyResponseFlyoutPanel = memo<{
|
|||
const backToDetailsClickHandler = useNavigateByRouterEventHandler(detailsRoutePath);
|
||||
const backButtonProp = useMemo((): FlyoutSubHeaderProps['backButton'] => {
|
||||
return {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.host.policyResponse.backLinkTitle', {
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.policyResponse.backLinkTitle', {
|
||||
defaultMessage: 'Endpoint Details',
|
||||
}),
|
||||
href: detailsUri,
|
||||
|
@ -149,13 +152,13 @@ const PolicyResponseFlyoutPanel = memo<{
|
|||
<>
|
||||
<FlyoutSubHeader
|
||||
backButton={backButtonProp}
|
||||
data-test-subj="hostDetailsPolicyResponseFlyoutHeader"
|
||||
data-test-subj="endpointDetailsPolicyResponseFlyoutHeader"
|
||||
/>
|
||||
<EuiFlyoutBody data-test-subj="hostDetailsPolicyResponseFlyoutBody">
|
||||
<EuiText data-test-subj="hostDetailsPolicyResponseFlyoutTitle">
|
||||
<EuiFlyoutBody data-test-subj="endpointDetailsPolicyResponseFlyoutBody">
|
||||
<EuiText data-test-subj="endpointDetailsPolicyResponseFlyoutTitle">
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.host.policyResponse.title"
|
||||
id="xpack.securitySolution.endpoint.policyResponse.title"
|
||||
defaultMessage="Configuration Response"
|
||||
/>
|
||||
</h4>
|
||||
|
@ -164,7 +167,7 @@ const PolicyResponseFlyoutPanel = memo<{
|
|||
<EuiEmptyPrompt
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostDetails.noPolicyResponse"
|
||||
id="xpack.securitySolution.endpoint.details.noPolicyResponse"
|
||||
defaultMessage="No configuration response available"
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ const ResponseActions = memo(
|
|||
<EuiAccordion
|
||||
id={action + index}
|
||||
key={action + index}
|
||||
data-test-subj="hostDetailsPolicyResponseActionsAccordion"
|
||||
data-test-subj="endpointDetailsPolicyResponseActionsAccordion"
|
||||
className="policyResponseActionsAccordion"
|
||||
buttonContent={
|
||||
<EuiText
|
||||
|
@ -150,7 +150,7 @@ export const PolicyResponse = memo(
|
|||
<PolicyResponseConfigAccordion
|
||||
id={generateId(`id_${key}`)}
|
||||
key={generateId(`key_${key}`)}
|
||||
data-test-subj="hostDetailsPolicyResponseConfigAccordion"
|
||||
data-test-subj="endpointDetailsPolicyResponseConfigAccordion"
|
||||
buttonContent={
|
||||
<EuiText size="s">
|
||||
<p>{formatResponse(key)}</p>
|
||||
|
@ -162,7 +162,7 @@ export const PolicyResponse = memo(
|
|||
attentionCount > 0 && (
|
||||
<EuiNotificationBadge
|
||||
className="policyResponseAttentionBadge"
|
||||
data-test-subj="hostDetailsPolicyResponseAttentionBadge"
|
||||
data-test-subj="endpointDetailsPolicyResponseAttentionBadge"
|
||||
>
|
||||
{attentionCount}
|
||||
</EuiNotificationBadge>
|
||||
|
|
|
@ -9,198 +9,189 @@ import { i18n } from '@kbn/i18n';
|
|||
const policyResponses: Array<[string, string]> = [
|
||||
[
|
||||
'configure_dns_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_dns_events',
|
||||
{ defaultMessage: 'Configure DNS Events' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.configure_dns_events', {
|
||||
defaultMessage: 'Configure DNS Events',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'configure_elasticsearch_connection',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_elasticsearch_connection',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_elasticsearch_connection',
|
||||
{ defaultMessage: 'Configure Elastic Search Connection' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'configure_file_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_file_events',
|
||||
{ defaultMessage: 'Configure File Events' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.configure_file_events', {
|
||||
defaultMessage: 'Configure File Events',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'configure_imageload_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_imageload_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_imageload_events',
|
||||
{ defaultMessage: 'Configure Image Load Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'configure_kernel',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_kernel', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.configure_kernel', {
|
||||
defaultMessage: 'Configure Kernel',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'configure_logging',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_logging', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.configure_logging', {
|
||||
defaultMessage: 'Configure Logging',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'configure_malware',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_malware', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.configure_malware', {
|
||||
defaultMessage: 'Configure Malware',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'configure_network_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_network_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_network_events',
|
||||
{ defaultMessage: 'Configure Network Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'configure_process_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_process_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_process_events',
|
||||
{ defaultMessage: 'Configure Process Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'configure_registry_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_registry_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_registry_events',
|
||||
{ defaultMessage: 'Configure Registry Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'configure_security_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_security_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.configure_security_events',
|
||||
{ defaultMessage: 'Configure Security Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'connect_kernel',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.connect_kernel', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.connect_kernel', {
|
||||
defaultMessage: 'Connect Kernel',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'detect_async_image_load_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_async_image_load_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.detect_async_image_load_events',
|
||||
{ defaultMessage: 'Detect Async Image Load Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'detect_file_open_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_open_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.detect_file_open_events',
|
||||
{ defaultMessage: 'Detect File Open Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'detect_file_write_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_write_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.detect_file_write_events',
|
||||
{ defaultMessage: 'Detect File Write Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'detect_network_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_network_events',
|
||||
{ defaultMessage: 'Detect Network Events' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.detect_network_events', {
|
||||
defaultMessage: 'Detect Network Events',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'detect_process_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_process_events',
|
||||
{ defaultMessage: 'Detect Process Events' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.detect_process_events', {
|
||||
defaultMessage: 'Detect Process Events',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'detect_registry_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_registry_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.detect_registry_events',
|
||||
{ defaultMessage: 'Detect Registry Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'detect_sync_image_load_events',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_sync_image_load_events',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.detect_sync_image_load_events',
|
||||
{ defaultMessage: 'Detect Sync Image Load Events' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'download_global_artifacts',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.download_global_artifacts',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.download_global_artifacts',
|
||||
{ defaultMessage: 'Download Global Artifacts' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'download_user_artifacts',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.download_user_artifacts',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.download_user_artifacts',
|
||||
{ defaultMessage: 'Download User Artifacts' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'load_config',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.load_config', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.load_config', {
|
||||
defaultMessage: 'Load Config',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'load_malware_model',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.load_malware_model',
|
||||
{ defaultMessage: 'Load Malware Model' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.load_malware_model', {
|
||||
defaultMessage: 'Load Malware Model',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'read_elasticsearch_config',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.read_elasticsearch_config',
|
||||
'xpack.securitySolution.endpoint.details.policyResponse.read_elasticsearch_config',
|
||||
{ defaultMessage: 'Read ElasticSearch Config' }
|
||||
),
|
||||
],
|
||||
[
|
||||
'read_events_config',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.read_events_config',
|
||||
{ defaultMessage: 'Read Events Config' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.read_events_config', {
|
||||
defaultMessage: 'Read Events Config',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'read_kernel_config',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.read_kernel_config',
|
||||
{ defaultMessage: 'Read Kernel Config' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.read_kernel_config', {
|
||||
defaultMessage: 'Read Kernel Config',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'read_logging_config',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.read_logging_config',
|
||||
{ defaultMessage: 'Read Logging Config' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.read_logging_config', {
|
||||
defaultMessage: 'Read Logging Config',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'read_malware_config',
|
||||
i18n.translate(
|
||||
'xpack.securitySolution.endpoint.hostDetails.policyResponse.read_malware_config',
|
||||
{ defaultMessage: 'Read Malware Config' }
|
||||
),
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.read_malware_config', {
|
||||
defaultMessage: 'Read Malware Config',
|
||||
}),
|
||||
],
|
||||
[
|
||||
'workflow',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.workflow', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.workflow', {
|
||||
defaultMessage: 'Workflow',
|
||||
}),
|
||||
],
|
||||
|
@ -211,43 +202,43 @@ const responseMap = new Map<string, string>(policyResponses);
|
|||
// Additional values used in the Policy Response UI
|
||||
responseMap.set(
|
||||
'success',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.success', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.success', {
|
||||
defaultMessage: 'Success',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'warning',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.warning', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.warning', {
|
||||
defaultMessage: 'Warning',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'failure',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.failed', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.failed', {
|
||||
defaultMessage: 'Failed',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'logging',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.logging', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.logging', {
|
||||
defaultMessage: 'Logging',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'streaming',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.streaming', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.streaming', {
|
||||
defaultMessage: 'Streaming',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'malware',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.malware', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.malware', {
|
||||
defaultMessage: 'Malware',
|
||||
})
|
||||
);
|
||||
responseMap.set(
|
||||
'events',
|
||||
i18n.translate('xpack.securitySolution.endpoint.hostDetails.policyResponse.events', {
|
||||
i18n.translate('xpack.securitySolution.endpoint.details.policyResponse.events', {
|
||||
defaultMessage: 'Events',
|
||||
})
|
||||
);
|
||||
|
|
|
@ -7,16 +7,18 @@
|
|||
import { useSelector } from 'react-redux';
|
||||
import { useMemo } from 'react';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { HostState } from '../types';
|
||||
import { EndpointState } from '../types';
|
||||
import {
|
||||
MANAGEMENT_STORE_HOSTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_ENDPOINTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_GLOBAL_NAMESPACE,
|
||||
} from '../../../common/constants';
|
||||
import { State } from '../../../../common/store';
|
||||
export function useHostSelector<TSelected>(selector: (state: HostState) => TSelected) {
|
||||
export function useEndpointSelector<TSelected>(selector: (state: EndpointState) => TSelected) {
|
||||
return useSelector(function (state: State) {
|
||||
return selector(
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_HOSTS_NAMESPACE] as HostState
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][
|
||||
MANAGEMENT_STORE_ENDPOINTS_NAMESPACE
|
||||
] as EndpointState
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
import React from 'react';
|
||||
import * as reactTestingLibrary from '@testing-library/react';
|
||||
|
||||
import { HostList } from './index';
|
||||
import { EndpointList } from './index';
|
||||
import {
|
||||
mockHostDetailsApiResult,
|
||||
mockHostResultList,
|
||||
setHostListApiMockImplementation,
|
||||
} from '../store/mock_host_result_list';
|
||||
mockEndpointDetailsApiResult,
|
||||
mockEndpointResultList,
|
||||
setEndpointListApiMockImplementation,
|
||||
} from '../store/mock_endpoint_result_list';
|
||||
import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint';
|
||||
import {
|
||||
HostInfo,
|
||||
|
@ -27,7 +27,7 @@ import { mockPolicyResultList } from '../../policy/store/policy_list/test_mock_u
|
|||
|
||||
jest.mock('../../../../common/components/link_to');
|
||||
|
||||
describe('when on the hosts page', () => {
|
||||
describe('when on the list page', () => {
|
||||
const docGenerator = new EndpointDocGenerator();
|
||||
let render: () => ReturnType<AppContextTestRender['render']>;
|
||||
let history: AppContextTestRender['history'];
|
||||
|
@ -38,9 +38,9 @@ describe('when on the hosts page', () => {
|
|||
beforeEach(() => {
|
||||
const mockedContext = createAppRootMockRenderer();
|
||||
({ history, store, coreStart, middlewareSpy } = mockedContext);
|
||||
render = () => mockedContext.render(<HostList />);
|
||||
render = () => mockedContext.render(<EndpointList />);
|
||||
reactTestingLibrary.act(() => {
|
||||
history.push('/hosts');
|
||||
history.push('/endpoints');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -50,10 +50,10 @@ describe('when on the hosts page', () => {
|
|||
expect(timelineFlyout).toBeNull();
|
||||
});
|
||||
|
||||
describe('when there are no hosts or polices', () => {
|
||||
describe('when there are no endpoints or polices', () => {
|
||||
beforeEach(() => {
|
||||
setHostListApiMockImplementation(coreStart.http, {
|
||||
hostsResults: [],
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: [],
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -70,8 +70,8 @@ describe('when on the hosts page', () => {
|
|||
|
||||
describe('when there are policies, but no hosts', () => {
|
||||
beforeEach(async () => {
|
||||
setHostListApiMockImplementation(coreStart.http, {
|
||||
hostsResults: [],
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: [],
|
||||
endpointPackageConfigs: mockPolicyResultList({ total: 3 }).items,
|
||||
});
|
||||
});
|
||||
|
@ -111,7 +111,7 @@ describe('when on the hosts page', () => {
|
|||
it('should not show the flyout', () => {
|
||||
const renderResult = render();
|
||||
expect.assertions(1);
|
||||
return renderResult.findByTestId('hostDetailsFlyout').catch((e) => {
|
||||
return renderResult.findByTestId('endpointDetailsFlyout').catch((e) => {
|
||||
expect(e).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
@ -122,7 +122,7 @@ describe('when on the hosts page', () => {
|
|||
let firstPolicyID: string;
|
||||
beforeEach(() => {
|
||||
reactTestingLibrary.act(() => {
|
||||
const hostListData = mockHostResultList({ total: 4 }).hosts;
|
||||
const hostListData = mockEndpointResultList({ total: 4 }).hosts;
|
||||
|
||||
firstPolicyID = hostListData[0].metadata.Endpoint.policy.applied.id;
|
||||
|
||||
|
@ -142,8 +142,8 @@ describe('when on the hosts page', () => {
|
|||
const ingestPackageConfigs = mockPolicyResultList({ total: 1 }).items;
|
||||
ingestPackageConfigs[0].id = firstPolicyID;
|
||||
|
||||
setHostListApiMockImplementation(coreStart.http, {
|
||||
hostsResults: hostListData,
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: hostListData,
|
||||
endpointPackageConfigs: ingestPackageConfigs,
|
||||
});
|
||||
});
|
||||
|
@ -152,7 +152,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display rows in the table', async () => {
|
||||
const renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const rows = await renderResult.findAllByRole('row');
|
||||
expect(rows).toHaveLength(5);
|
||||
|
@ -160,15 +160,15 @@ describe('when on the hosts page', () => {
|
|||
it('should show total', async () => {
|
||||
const renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const total = await renderResult.findByTestId('hostListTableTotal');
|
||||
const total = await renderResult.findByTestId('endpointListTableTotal');
|
||||
expect(total.textContent).toEqual('4 Hosts');
|
||||
});
|
||||
it('should display correct status', async () => {
|
||||
const renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const hostStatuses = await renderResult.findAllByTestId('rowHostStatus');
|
||||
|
||||
|
@ -194,7 +194,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display correct policy status', async () => {
|
||||
const renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const policyStatuses = await renderResult.findAllByTestId('rowPolicyStatus');
|
||||
|
||||
|
@ -213,7 +213,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display policy name as a link', async () => {
|
||||
const renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const firstPolicyName = (await renderResult.findAllByTestId('policyNameCellLink'))[0];
|
||||
expect(firstPolicyName).not.toBeNull();
|
||||
|
@ -225,7 +225,7 @@ describe('when on the hosts page', () => {
|
|||
beforeEach(async () => {
|
||||
renderResult = render();
|
||||
await reactTestingLibrary.act(async () => {
|
||||
await middlewareSpy.waitForAction('serverReturnedHostList');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointList');
|
||||
});
|
||||
const hostNameLinks = await renderResult.findAllByTestId('hostnameCellLink');
|
||||
if (hostNameLinks.length) {
|
||||
|
@ -234,7 +234,7 @@ describe('when on the hosts page', () => {
|
|||
});
|
||||
|
||||
it('should show the flyout', () => {
|
||||
return renderResult.findByTestId('hostDetailsFlyout').then((flyout) => {
|
||||
return renderResult.findByTestId('endpointDetailsFlyout').then((flyout) => {
|
||||
expect(flyout).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
@ -298,12 +298,12 @@ describe('when on the hosts page', () => {
|
|||
return policyResponse;
|
||||
};
|
||||
|
||||
const dispatchServerReturnedHostPolicyResponse = (
|
||||
const dispatchServerReturnedEndpointPolicyResponse = (
|
||||
overallStatus: HostPolicyResponseActionStatus = HostPolicyResponseActionStatus.success
|
||||
) => {
|
||||
reactTestingLibrary.act(() => {
|
||||
store.dispatch({
|
||||
type: 'serverReturnedHostPolicyResponse',
|
||||
type: 'serverReturnedEndpointPolicyResponse',
|
||||
payload: {
|
||||
policy_response: createPolicyResponse(overallStatus),
|
||||
},
|
||||
|
@ -316,7 +316,7 @@ describe('when on the hosts page', () => {
|
|||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
host_status,
|
||||
metadata: { host, ...details },
|
||||
} = mockHostDetailsApiResult();
|
||||
} = mockEndpointDetailsApiResult();
|
||||
|
||||
hostDetails = {
|
||||
host_status,
|
||||
|
@ -334,18 +334,18 @@ describe('when on the hosts page', () => {
|
|||
const policy = docGenerator.generatePolicyPackageConfig();
|
||||
policy.id = hostDetails.metadata.Endpoint.policy.applied.id;
|
||||
|
||||
setHostListApiMockImplementation(coreStart.http, {
|
||||
hostsResults: [hostDetails],
|
||||
setEndpointListApiMockImplementation(coreStart.http, {
|
||||
endpointsResults: [hostDetails],
|
||||
endpointPackageConfigs: [policy],
|
||||
});
|
||||
|
||||
reactTestingLibrary.act(() => {
|
||||
history.push('/hosts?selected_host=1');
|
||||
history.push('/endpoints?selected_endpoint=1');
|
||||
});
|
||||
|
||||
renderAndWaitForData = async () => {
|
||||
const renderResult = render();
|
||||
await middlewareSpy.waitForAction('serverReturnedHostDetails');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointDetails');
|
||||
return renderResult;
|
||||
};
|
||||
});
|
||||
|
@ -355,7 +355,7 @@ describe('when on the hosts page', () => {
|
|||
|
||||
it('should show the flyout', async () => {
|
||||
const renderResult = await renderAndWaitForData();
|
||||
return renderResult.findByTestId('hostDetailsFlyout').then((flyout) => {
|
||||
return renderResult.findByTestId('endpointDetailsFlyout').then((flyout) => {
|
||||
expect(flyout).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
@ -387,7 +387,7 @@ describe('when on the hosts page', () => {
|
|||
const policyStatusLink = await renderResult.findByTestId('policyStatusValue');
|
||||
expect(policyStatusLink).not.toBeNull();
|
||||
expect(policyStatusLink.getAttribute('href')).toEqual(
|
||||
'/hosts?page_index=0&page_size=10&selected_host=1&show=policy_response'
|
||||
'/endpoints?page_index=0&page_size=10&selected_endpoint=1&show=policy_response'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -400,14 +400,14 @@ describe('when on the hosts page', () => {
|
|||
});
|
||||
const changedUrlAction = await userChangedUrlChecker;
|
||||
expect(changedUrlAction.payload.search).toEqual(
|
||||
'?page_index=0&page_size=10&selected_host=1&show=policy_response'
|
||||
'?page_index=0&page_size=10&selected_endpoint=1&show=policy_response'
|
||||
);
|
||||
});
|
||||
|
||||
it('should display Success overall policy status', async () => {
|
||||
const renderResult = await renderAndWaitForData();
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse(HostPolicyResponseActionStatus.success);
|
||||
dispatchServerReturnedEndpointPolicyResponse(HostPolicyResponseActionStatus.success);
|
||||
});
|
||||
const policyStatusLink = await renderResult.findByTestId('policyStatusValue');
|
||||
expect(policyStatusLink.textContent).toEqual('Success');
|
||||
|
@ -421,7 +421,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display Warning overall policy status', async () => {
|
||||
const renderResult = await renderAndWaitForData();
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse(HostPolicyResponseActionStatus.warning);
|
||||
dispatchServerReturnedEndpointPolicyResponse(HostPolicyResponseActionStatus.warning);
|
||||
});
|
||||
const policyStatusLink = await renderResult.findByTestId('policyStatusValue');
|
||||
expect(policyStatusLink.textContent).toEqual('Warning');
|
||||
|
@ -435,7 +435,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display Failed overall policy status', async () => {
|
||||
const renderResult = await renderAndWaitForData();
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse(HostPolicyResponseActionStatus.failure);
|
||||
dispatchServerReturnedEndpointPolicyResponse(HostPolicyResponseActionStatus.failure);
|
||||
});
|
||||
const policyStatusLink = await renderResult.findByTestId('policyStatusValue');
|
||||
expect(policyStatusLink.textContent).toEqual('Failed');
|
||||
|
@ -449,7 +449,7 @@ describe('when on the hosts page', () => {
|
|||
it('should display Unknown overall policy status', async () => {
|
||||
const renderResult = await renderAndWaitForData();
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse('' as HostPolicyResponseActionStatus);
|
||||
dispatchServerReturnedEndpointPolicyResponse('' as HostPolicyResponseActionStatus);
|
||||
});
|
||||
const policyStatusLink = await renderResult.findByTestId('policyStatusValue');
|
||||
expect(policyStatusLink.textContent).toEqual('Unknown');
|
||||
|
@ -463,7 +463,7 @@ describe('when on the hosts page', () => {
|
|||
it('should include the link to reassignment in Ingest', async () => {
|
||||
coreStart.application.getUrlForApp.mockReturnValue('/app/ingestManager');
|
||||
const renderResult = await renderAndWaitForData();
|
||||
const linkToReassign = await renderResult.findByTestId('hostDetailsLinkToIngest');
|
||||
const linkToReassign = await renderResult.findByTestId('endpointDetailsLinkToIngest');
|
||||
expect(linkToReassign).not.toBeNull();
|
||||
expect(linkToReassign.textContent).toEqual('Reassign Configuration');
|
||||
expect(linkToReassign.getAttribute('href')).toEqual(
|
||||
|
@ -475,7 +475,7 @@ describe('when on the hosts page', () => {
|
|||
beforeEach(async () => {
|
||||
coreStart.application.getUrlForApp.mockReturnValue('/app/ingestManager');
|
||||
const renderResult = await renderAndWaitForData();
|
||||
const linkToReassign = await renderResult.findByTestId('hostDetailsLinkToIngest');
|
||||
const linkToReassign = await renderResult.findByTestId('endpointDetailsLinkToIngest');
|
||||
reactTestingLibrary.act(() => {
|
||||
reactTestingLibrary.fireEvent.click(linkToReassign);
|
||||
});
|
||||
|
@ -491,7 +491,7 @@ describe('when on the hosts page', () => {
|
|||
beforeEach(async () => {
|
||||
coreStart.http.post.mockImplementation(async (requestOptions) => {
|
||||
if (requestOptions.path === '/api/endpoint/metadata') {
|
||||
return mockHostResultList({ total: 0 });
|
||||
return mockEndpointResultList({ total: 0 });
|
||||
}
|
||||
throw new Error(`POST to '${requestOptions.path}' does not have a mock response!`);
|
||||
});
|
||||
|
@ -502,44 +502,44 @@ describe('when on the hosts page', () => {
|
|||
reactTestingLibrary.fireEvent.click(policyStatusLink);
|
||||
});
|
||||
await userChangedUrlChecker;
|
||||
await middlewareSpy.waitForAction('serverReturnedHostPolicyResponse');
|
||||
await middlewareSpy.waitForAction('serverReturnedEndpointPolicyResponse');
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse();
|
||||
dispatchServerReturnedEndpointPolicyResponse();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(reactTestingLibrary.cleanup);
|
||||
|
||||
it('should hide the host details panel', async () => {
|
||||
const hostDetailsFlyout = await renderResult.queryByTestId('hostDetailsFlyoutBody');
|
||||
expect(hostDetailsFlyout).toBeNull();
|
||||
const endpointDetailsFlyout = await renderResult.queryByTestId('endpointDetailsFlyoutBody');
|
||||
expect(endpointDetailsFlyout).toBeNull();
|
||||
});
|
||||
|
||||
it('should display policy response sub-panel', async () => {
|
||||
expect(
|
||||
await renderResult.findByTestId('hostDetailsPolicyResponseFlyoutHeader')
|
||||
await renderResult.findByTestId('endpointDetailsPolicyResponseFlyoutHeader')
|
||||
).not.toBeNull();
|
||||
expect(
|
||||
await renderResult.findByTestId('hostDetailsPolicyResponseFlyoutBody')
|
||||
await renderResult.findByTestId('endpointDetailsPolicyResponseFlyoutBody')
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should include the sub-panel title', async () => {
|
||||
expect(
|
||||
(await renderResult.findByTestId('hostDetailsPolicyResponseFlyoutTitle')).textContent
|
||||
(await renderResult.findByTestId('endpointDetailsPolicyResponseFlyoutTitle')).textContent
|
||||
).toBe('Configuration Response');
|
||||
});
|
||||
|
||||
it('should show a configuration section for each protection', async () => {
|
||||
const configAccordions = await renderResult.findAllByTestId(
|
||||
'hostDetailsPolicyResponseConfigAccordion'
|
||||
'endpointDetailsPolicyResponseConfigAccordion'
|
||||
);
|
||||
expect(configAccordions).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should show an actions section for each configuration', async () => {
|
||||
const actionAccordions = await renderResult.findAllByTestId(
|
||||
'hostDetailsPolicyResponseActionsAccordion'
|
||||
'endpointDetailsPolicyResponseActionsAccordion'
|
||||
);
|
||||
const action = await renderResult.findAllByTestId('policyResponseAction');
|
||||
const statusHealth = await renderResult.findAllByTestId('policyResponseStatusHealth');
|
||||
|
@ -557,14 +557,14 @@ describe('when on the hosts page', () => {
|
|||
);
|
||||
reactTestingLibrary.act(() => {
|
||||
store.dispatch({
|
||||
type: 'serverReturnedHostPolicyResponse',
|
||||
type: 'serverReturnedEndpointPolicyResponse',
|
||||
payload: {
|
||||
policy_response: policyResponse,
|
||||
},
|
||||
});
|
||||
});
|
||||
return renderResult
|
||||
.findAllByTestId('hostDetailsPolicyResponseAttentionBadge')
|
||||
.findAllByTestId('endpointDetailsPolicyResponseAttentionBadge')
|
||||
.catch((e) => {
|
||||
expect(e).not.toBeNull();
|
||||
});
|
||||
|
@ -572,28 +572,28 @@ describe('when on the hosts page', () => {
|
|||
|
||||
it('should show a numbered badge if at least one action failed', async () => {
|
||||
const policyResponseActionDispatched = middlewareSpy.waitForAction(
|
||||
'serverReturnedHostPolicyResponse'
|
||||
'serverReturnedEndpointPolicyResponse'
|
||||
);
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse(HostPolicyResponseActionStatus.failure);
|
||||
dispatchServerReturnedEndpointPolicyResponse(HostPolicyResponseActionStatus.failure);
|
||||
});
|
||||
await policyResponseActionDispatched;
|
||||
const attentionBadge = await renderResult.findAllByTestId(
|
||||
'hostDetailsPolicyResponseAttentionBadge'
|
||||
'endpointDetailsPolicyResponseAttentionBadge'
|
||||
);
|
||||
expect(attentionBadge).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should show a numbered badge if at least one action has a warning', async () => {
|
||||
const policyResponseActionDispatched = middlewareSpy.waitForAction(
|
||||
'serverReturnedHostPolicyResponse'
|
||||
'serverReturnedEndpointPolicyResponse'
|
||||
);
|
||||
reactTestingLibrary.act(() => {
|
||||
dispatchServerReturnedHostPolicyResponse(HostPolicyResponseActionStatus.warning);
|
||||
dispatchServerReturnedEndpointPolicyResponse(HostPolicyResponseActionStatus.warning);
|
||||
});
|
||||
await policyResponseActionDispatched;
|
||||
const attentionBadge = await renderResult.findAllByTestId(
|
||||
'hostDetailsPolicyResponseAttentionBadge'
|
||||
'endpointDetailsPolicyResponseAttentionBadge'
|
||||
);
|
||||
expect(attentionBadge).not.toBeNull();
|
||||
});
|
||||
|
@ -602,7 +602,7 @@ describe('when on the hosts page', () => {
|
|||
const subHeaderBackLink = await renderResult.findByTestId('flyoutSubHeaderBackButton');
|
||||
expect(subHeaderBackLink.textContent).toBe('Endpoint Details');
|
||||
expect(subHeaderBackLink.getAttribute('href')).toBe(
|
||||
'/hosts?page_index=0&page_size=10&selected_host=1'
|
||||
'/endpoints?page_index=0&page_size=10&selected_endpoint=1'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -614,7 +614,7 @@ describe('when on the hosts page', () => {
|
|||
});
|
||||
const changedUrlAction = await userChangedUrlChecker;
|
||||
expect(changedUrlAction.payload.search).toEqual(
|
||||
'?page_index=0&page_size=10&selected_host=1'
|
||||
'?page_index=0&page_size=10&selected_endpoint=1'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ import { i18n } from '@kbn/i18n';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { HostDetailsFlyout } from './details';
|
||||
import { EndpointDetailsFlyout } from './details';
|
||||
import * as selectors from '../store/selectors';
|
||||
import { useHostSelector } from './hooks';
|
||||
import { useEndpointSelector } from './hooks';
|
||||
import {
|
||||
HOST_STATUS_TO_HEALTH_COLOR,
|
||||
POLICY_STATUS_TO_HEALTH_COLOR,
|
||||
|
@ -46,12 +46,12 @@ import {
|
|||
AgentConfigDetailsDeployAgentAction,
|
||||
} from '../../../../../../ingest_manager/public';
|
||||
import { SecurityPageName } from '../../../../app/types';
|
||||
import { getHostListPath, getHostDetailsPath } from '../../../common/routing';
|
||||
import { getEndpointListPath, getEndpointDetailsPath } from '../../../common/routing';
|
||||
import { useFormatUrl } from '../../../../common/components/link_to';
|
||||
import { HostAction } from '../store/action';
|
||||
import { HostPolicyLink } from './components/host_policy_link';
|
||||
import { EndpointAction } from '../store/action';
|
||||
import { EndpointPolicyLink } from './components/endpoint_policy_link';
|
||||
|
||||
const HostListNavLink = memo<{
|
||||
const EndpointListNavLink = memo<{
|
||||
name: string;
|
||||
href: string;
|
||||
route: string;
|
||||
|
@ -71,10 +71,10 @@ const HostListNavLink = memo<{
|
|||
</EuiLink>
|
||||
);
|
||||
});
|
||||
HostListNavLink.displayName = 'HostListNavLink';
|
||||
EndpointListNavLink.displayName = 'EndpointListNavLink';
|
||||
|
||||
const selector = (createStructuredSelector as CreateStructuredSelector)(selectors);
|
||||
export const HostList = () => {
|
||||
export const EndpointList = () => {
|
||||
const history = useHistory();
|
||||
const {
|
||||
listData,
|
||||
|
@ -84,16 +84,16 @@ export const HostList = () => {
|
|||
listLoading: loading,
|
||||
listError,
|
||||
uiQueryParams: queryParams,
|
||||
hasSelectedHost,
|
||||
hasSelectedEndpoint,
|
||||
policyItems,
|
||||
selectedPolicyId,
|
||||
policyItemsLoading,
|
||||
endpointPackageVersion,
|
||||
hostsExist,
|
||||
} = useHostSelector(selector);
|
||||
endpointsExist,
|
||||
} = useEndpointSelector(selector);
|
||||
const { formatUrl, search } = useFormatUrl(SecurityPageName.administration);
|
||||
|
||||
const dispatch = useDispatch<(a: HostAction) => void>();
|
||||
const dispatch = useDispatch<(a: EndpointAction) => void>();
|
||||
|
||||
const paginationSetup = useMemo(() => {
|
||||
return {
|
||||
|
@ -108,10 +108,10 @@ export const HostList = () => {
|
|||
const onTableChange = useCallback(
|
||||
({ page }: { page: { index: number; size: number } }) => {
|
||||
const { index, size } = page;
|
||||
// FIXME: PT: if host details is open, table is not displaying correct number of rows
|
||||
// FIXME: PT: if endpoint details is open, table is not displaying correct number of rows
|
||||
history.push(
|
||||
getHostListPath({
|
||||
name: 'hostList',
|
||||
getEndpointListPath({
|
||||
name: 'endpointList',
|
||||
...queryParams,
|
||||
page_index: JSON.stringify(index),
|
||||
page_size: JSON.stringify(size),
|
||||
|
@ -130,12 +130,12 @@ export const HostList = () => {
|
|||
state: {
|
||||
onCancelNavigateTo: [
|
||||
'securitySolution:administration',
|
||||
{ path: getHostListPath({ name: 'hostList' }) },
|
||||
{ path: getEndpointListPath({ name: 'endpointList' }) },
|
||||
],
|
||||
onCancelUrl: formatUrl(getHostListPath({ name: 'hostList' })),
|
||||
onCancelUrl: formatUrl(getEndpointListPath({ name: 'endpointList' })),
|
||||
onSaveNavigateTo: [
|
||||
'securitySolution:administration',
|
||||
{ path: getHostListPath({ name: 'hostList' }) },
|
||||
{ path: getEndpointListPath({ name: 'endpointList' }) },
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ export const HostList = () => {
|
|||
state: {
|
||||
onDoneNavigateTo: [
|
||||
'securitySolution:administration',
|
||||
{ path: getHostListPath({ name: 'hostList' }) },
|
||||
{ path: getEndpointListPath({ name: 'endpointList' }) },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
@ -183,28 +183,28 @@ export const HostList = () => {
|
|||
);
|
||||
|
||||
const columns: Array<EuiBasicTableColumn<Immutable<HostInfo>>> = useMemo(() => {
|
||||
const lastActiveColumnName = i18n.translate('xpack.securitySolution.endpointList.lastActive', {
|
||||
const lastActiveColumnName = i18n.translate('xpack.securitySolution.endpoint.list.lastActive', {
|
||||
defaultMessage: 'Last Active',
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
field: 'metadata.host',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.hostname', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.hostname', {
|
||||
defaultMessage: 'Hostname',
|
||||
}),
|
||||
render: ({ hostname, id }: HostInfo['metadata']['host']) => {
|
||||
const toRoutePath = getHostDetailsPath(
|
||||
const toRoutePath = getEndpointDetailsPath(
|
||||
{
|
||||
...queryParams,
|
||||
name: 'hostDetails',
|
||||
selected_host: id,
|
||||
name: 'endpointDetails',
|
||||
selected_endpoint: id,
|
||||
},
|
||||
search
|
||||
);
|
||||
const toRouteUrl = formatUrl(toRoutePath);
|
||||
return (
|
||||
<HostListNavLink
|
||||
<EndpointListNavLink
|
||||
name={hostname}
|
||||
href={toRouteUrl}
|
||||
route={toRoutePath}
|
||||
|
@ -215,8 +215,8 @@ export const HostList = () => {
|
|||
},
|
||||
{
|
||||
field: 'host_status',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.hostStatus', {
|
||||
defaultMessage: 'Host Status',
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.hostStatus', {
|
||||
defaultMessage: 'Agent Status',
|
||||
}),
|
||||
// eslint-disable-next-line react/display-name
|
||||
render: (hostStatus: HostInfo['host_status']) => {
|
||||
|
@ -227,7 +227,7 @@ export const HostList = () => {
|
|||
className="eui-textTruncate"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointList.hostStatusValue"
|
||||
id="xpack.securitySolution.endpoint.list.hostStatusValue"
|
||||
defaultMessage="{hostStatus, select, online {Online} error {Error} unenrolling {Unenrolling} other {Offline}}"
|
||||
values={{ hostStatus }}
|
||||
/>
|
||||
|
@ -237,33 +237,33 @@ export const HostList = () => {
|
|||
},
|
||||
{
|
||||
field: 'metadata.Endpoint.policy.applied',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.policy', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.policy', {
|
||||
defaultMessage: 'Integration',
|
||||
}),
|
||||
truncateText: true,
|
||||
// eslint-disable-next-line react/display-name
|
||||
render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied']) => {
|
||||
return (
|
||||
<HostPolicyLink
|
||||
<EndpointPolicyLink
|
||||
policyId={policy.id}
|
||||
className="eui-textTruncate"
|
||||
data-test-subj="policyNameCellLink"
|
||||
>
|
||||
{policy.name}
|
||||
</HostPolicyLink>
|
||||
</EndpointPolicyLink>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'metadata.Endpoint.policy.applied',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.policyStatus', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.policyStatus', {
|
||||
defaultMessage: 'Configuration Status',
|
||||
}),
|
||||
render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied'], item: HostInfo) => {
|
||||
const toRoutePath = getHostDetailsPath({
|
||||
name: 'hostPolicyResponse',
|
||||
const toRoutePath = getEndpointDetailsPath({
|
||||
name: 'endpointPolicyResponse',
|
||||
...queryParams,
|
||||
selected_host: item.metadata.host.id,
|
||||
selected_endpoint: item.metadata.host.id,
|
||||
});
|
||||
const toRouteUrl = formatUrl(toRoutePath);
|
||||
return (
|
||||
|
@ -272,7 +272,7 @@ export const HostList = () => {
|
|||
className="eui-textTruncate"
|
||||
data-test-subj="rowPolicyStatus"
|
||||
>
|
||||
<HostListNavLink
|
||||
<EndpointListNavLink
|
||||
name={POLICY_STATUS_TO_TEXT[policy.status]}
|
||||
href={toRouteUrl}
|
||||
route={toRoutePath}
|
||||
|
@ -284,14 +284,14 @@ export const HostList = () => {
|
|||
},
|
||||
{
|
||||
field: 'metadata.host.os.name',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.os', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.os', {
|
||||
defaultMessage: 'Operating System',
|
||||
}),
|
||||
truncateText: true,
|
||||
},
|
||||
{
|
||||
field: 'metadata.host.ip',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.ip', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.ip', {
|
||||
defaultMessage: 'IP Address',
|
||||
}),
|
||||
// eslint-disable-next-line react/display-name
|
||||
|
@ -309,7 +309,7 @@ export const HostList = () => {
|
|||
},
|
||||
{
|
||||
field: 'metadata.agent.version',
|
||||
name: i18n.translate('xpack.securitySolution.endpointList.endpointVersion', {
|
||||
name: i18n.translate('xpack.securitySolution.endpoint.list.endpointVersion', {
|
||||
defaultMessage: 'Version',
|
||||
}),
|
||||
},
|
||||
|
@ -330,10 +330,10 @@ export const HostList = () => {
|
|||
}, [formatUrl, queryParams, search]);
|
||||
|
||||
const renderTableOrEmptyState = useMemo(() => {
|
||||
if (hostsExist) {
|
||||
if (endpointsExist) {
|
||||
return (
|
||||
<EuiBasicTable
|
||||
data-test-subj="hostListTable"
|
||||
data-test-subj="endpointListTable"
|
||||
items={[...listData]}
|
||||
columns={columns}
|
||||
error={listError?.message}
|
||||
|
@ -359,7 +359,7 @@ export const HostList = () => {
|
|||
}
|
||||
}, [
|
||||
loading,
|
||||
hostsExist,
|
||||
endpointsExist,
|
||||
policyItemsLoading,
|
||||
policyItems,
|
||||
listData,
|
||||
|
@ -377,7 +377,7 @@ export const HostList = () => {
|
|||
return (
|
||||
<ManagementPageView
|
||||
viewType="list"
|
||||
data-test-subj="hostPage"
|
||||
data-test-subj="endpointPage"
|
||||
headerLeft={
|
||||
<>
|
||||
<EuiFlexGroup alignItems="center" responsive={false}>
|
||||
|
@ -385,15 +385,15 @@ export const HostList = () => {
|
|||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="pageViewHeaderLeftTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.hostList.pageTitle"
|
||||
defaultMessage="Hosts"
|
||||
id="xpack.securitySolution.endpoint.list.pageTitle"
|
||||
defaultMessage="Endpoints"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBetaBadge
|
||||
label={i18n.translate('xpack.securitySolution.endpoint.hostList.beta', {
|
||||
label={i18n.translate('xpack.securitySolution.endpoint.list.beta', {
|
||||
defaultMessage: 'Beta',
|
||||
})}
|
||||
/>
|
||||
|
@ -403,7 +403,7 @@ export const HostList = () => {
|
|||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.hostList.pageSubTitle"
|
||||
id="xpack.securitySolution.endpoint.list.pageSubTitle"
|
||||
defaultMessage="Hosts running Elastic Endpoint Security"
|
||||
/>
|
||||
</p>
|
||||
|
@ -411,12 +411,12 @@ export const HostList = () => {
|
|||
</>
|
||||
}
|
||||
>
|
||||
{hasSelectedHost && <HostDetailsFlyout />}
|
||||
{hasSelectedEndpoint && <EndpointDetailsFlyout />}
|
||||
{listData && listData.length > 0 && (
|
||||
<>
|
||||
<EuiText color="subdued" size="xs" data-test-subj="hostListTableTotal">
|
||||
<EuiText color="subdued" size="xs" data-test-subj="endpointListTableTotal">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointList.totalCount"
|
||||
id="xpack.securitySolution.endpoint.list.totalCount"
|
||||
defaultMessage="{totalItemCount, plural, one {# Host} other {# Hosts}}"
|
||||
values={{ totalItemCount }}
|
||||
/>
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
// eslint-disable-next-line import/no-nodejs-modules
|
||||
import querystring from 'querystring';
|
||||
|
||||
import { HostIndexUIQueryParams } from '../types';
|
||||
import { EndpointIndexUIQueryParams } from '../types';
|
||||
import { AppLocation } from '../../../../../common/endpoint/types';
|
||||
|
||||
export function urlFromQueryParams(queryParams: HostIndexUIQueryParams): Partial<AppLocation> {
|
||||
export function urlFromQueryParams(queryParams: EndpointIndexUIQueryParams): Partial<AppLocation> {
|
||||
const search = querystring.stringify(queryParams);
|
||||
return {
|
||||
search,
|
||||
|
|
|
@ -30,7 +30,7 @@ describe('when in the Admistration tab', () => {
|
|||
it('should display the Management view when Ingest is ON', async () => {
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
const renderResult = render();
|
||||
const hostPage = await renderResult.findByTestId('hostPage');
|
||||
expect(hostPage).not.toBeNull();
|
||||
const endpointPage = await renderResult.findByTestId('endpointPage');
|
||||
expect(endpointPage).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,24 +13,24 @@ import { EuiText, EuiEmptyPrompt } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { PolicyContainer } from './policy';
|
||||
import {
|
||||
MANAGEMENT_ROUTING_HOSTS_PATH,
|
||||
MANAGEMENT_ROUTING_ENDPOINTS_PATH,
|
||||
MANAGEMENT_ROUTING_POLICIES_PATH,
|
||||
MANAGEMENT_ROUTING_ROOT_PATH,
|
||||
} from '../common/constants';
|
||||
import { NotFoundPage } from '../../app/404';
|
||||
import { HostsContainer } from './endpoint_hosts';
|
||||
import { getHostListPath } from '../common/routing';
|
||||
import { EndpointsContainer } from './endpoint_hosts';
|
||||
import { getEndpointListPath } from '../common/routing';
|
||||
import { APP_ID, SecurityPageName } from '../../../common/constants';
|
||||
import { GetUrlForApp } from '../../common/components/navigation/types';
|
||||
import { AdministrationRouteSpyState } from '../../common/utils/route/types';
|
||||
import { ADMINISTRATION } from '../../app/home/translations';
|
||||
import { AdministrationSubTab } from '../types';
|
||||
import { HOSTS_TAB, POLICIES_TAB } from '../common/translations';
|
||||
import { ENDPOINTS_TAB, POLICIES_TAB } from '../common/translations';
|
||||
import { SpyRoute } from '../../common/utils/route/spy_routes';
|
||||
import { useIngestEnabledCheck } from '../../common/hooks/endpoint/ingest_enabled';
|
||||
|
||||
const TabNameMappedToI18nKey: Record<string, string> = {
|
||||
[AdministrationSubTab.hosts]: HOSTS_TAB,
|
||||
[AdministrationSubTab.endpoints]: ENDPOINTS_TAB,
|
||||
[AdministrationSubTab.policies]: POLICIES_TAB,
|
||||
};
|
||||
|
||||
|
@ -102,13 +102,13 @@ export const ManagementContainer = memo(() => {
|
|||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={MANAGEMENT_ROUTING_HOSTS_PATH} component={HostsContainer} />
|
||||
<Route path={MANAGEMENT_ROUTING_ENDPOINTS_PATH} component={EndpointsContainer} />
|
||||
<Route path={MANAGEMENT_ROUTING_POLICIES_PATH} component={PolicyContainer} />
|
||||
<Route
|
||||
path={MANAGEMENT_ROUTING_ROOT_PATH}
|
||||
exact
|
||||
render={() => {
|
||||
history.replace(getHostListPath({ name: 'hostList' }));
|
||||
history.replace(getEndpointListPath({ name: 'endpointList' }));
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -34,7 +34,7 @@ export const AgentsSummary = memo<AgentsSummaryProps>((props) => {
|
|||
title: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle',
|
||||
{
|
||||
defaultMessage: 'Hosts',
|
||||
defaultMessage: 'Endpoints',
|
||||
}
|
||||
),
|
||||
health: '',
|
||||
|
|
|
@ -10,7 +10,7 @@ import { mount } from 'enzyme';
|
|||
import { PolicyDetails } from './policy_details';
|
||||
import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data';
|
||||
import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint';
|
||||
import { getPolicyDetailPath, getHostListPath } from '../../../common/routing';
|
||||
import { getPolicyDetailPath, getEndpointListPath } from '../../../common/routing';
|
||||
import { policyListApiPathHandlers } from '../store/policy_list/test_mock_utils';
|
||||
|
||||
jest.mock('../../../../common/components/link_to');
|
||||
|
@ -19,7 +19,7 @@ describe('Policy Details', () => {
|
|||
type FindReactWrapperResponse = ReturnType<ReturnType<typeof render>['find']>;
|
||||
|
||||
const policyDetailsPathUrl = getPolicyDetailPath('1');
|
||||
const hostListPath = getHostListPath({ name: 'hostList' });
|
||||
const endpointListPath = getEndpointListPath({ name: 'endpointList' });
|
||||
const sleep = (ms = 100) => new Promise((wakeup) => setTimeout(wakeup, ms));
|
||||
const generator = new EndpointDocGenerator();
|
||||
let history: AppContextTestRender['history'];
|
||||
|
@ -129,7 +129,7 @@ describe('Policy Details', () => {
|
|||
|
||||
const backToListButton = pageHeaderLeft.find('EuiButtonEmpty');
|
||||
expect(backToListButton.prop('iconType')).toBe('arrowLeft');
|
||||
expect(backToListButton.prop('href')).toBe(hostListPath);
|
||||
expect(backToListButton.prop('href')).toBe(endpointListPath);
|
||||
expect(backToListButton.text()).toBe('Back to endpoint hosts');
|
||||
|
||||
const pageTitle = pageHeaderLeft.find('[data-test-subj="pageViewHeaderLeftTitle"]');
|
||||
|
@ -143,7 +143,7 @@ describe('Policy Details', () => {
|
|||
);
|
||||
expect(history.location.pathname).toEqual(policyDetailsPathUrl);
|
||||
backToListButton.simulate('click', { button: 0 });
|
||||
expect(history.location.pathname).toEqual(hostListPath);
|
||||
expect(history.location.pathname).toEqual(endpointListPath);
|
||||
});
|
||||
it('should display agent stats', async () => {
|
||||
await asyncActions;
|
||||
|
@ -153,7 +153,7 @@ describe('Policy Details', () => {
|
|||
);
|
||||
const agentsSummary = headerRight.find('EuiFlexGroup[data-test-subj="policyAgentsSummary"]');
|
||||
expect(agentsSummary).toHaveLength(1);
|
||||
expect(agentsSummary.text()).toBe('Hosts5Online3Offline1Error1');
|
||||
expect(agentsSummary.text()).toBe('Endpoints5Online3Offline1Error1');
|
||||
});
|
||||
it('should display cancel button', async () => {
|
||||
await asyncActions;
|
||||
|
@ -175,7 +175,7 @@ describe('Policy Details', () => {
|
|||
const navigateToAppMockedCalls = coreStart.application.navigateToApp.mock.calls;
|
||||
expect(navigateToAppMockedCalls[navigateToAppMockedCalls.length - 1]).toEqual([
|
||||
'securitySolution:administration',
|
||||
{ path: hostListPath },
|
||||
{ path: endpointListPath },
|
||||
]);
|
||||
});
|
||||
it('should display save button', async () => {
|
||||
|
|
|
@ -43,7 +43,7 @@ import { PageViewHeaderTitle } from '../../../../common/components/endpoint/page
|
|||
import { ManagementPageView } from '../../../components/management_page_view';
|
||||
import { SpyRoute } from '../../../../common/utils/route/spy_routes';
|
||||
import { SecurityPageName } from '../../../../app/types';
|
||||
import { getHostListPath } from '../../../common/routing';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
import { useFormatUrl } from '../../../../common/components/link_to';
|
||||
import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { MANAGEMENT_APP_ID } from '../../../common/constants';
|
||||
|
@ -71,7 +71,7 @@ export const PolicyDetails = React.memo(() => {
|
|||
const [showConfirm, setShowConfirm] = useState<boolean>(false);
|
||||
const [routeState, setRouteState] = useState<PolicyDetailsRouteState>();
|
||||
const policyName = policyItem?.name ?? '';
|
||||
const hostListRouterPath = getHostListPath({ name: 'hostList' });
|
||||
const hostListRouterPath = getEndpointListPath({ name: 'endpointList' });
|
||||
|
||||
// Handle showing update statuses
|
||||
useEffect(() => {
|
||||
|
|
|
@ -12,19 +12,19 @@ import {
|
|||
import { policyListMiddlewareFactory } from '../pages/policy/store/policy_list';
|
||||
import { policyDetailsMiddlewareFactory } from '../pages/policy/store/policy_details';
|
||||
import {
|
||||
MANAGEMENT_STORE_HOSTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_ENDPOINTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_GLOBAL_NAMESPACE,
|
||||
MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE,
|
||||
MANAGEMENT_STORE_POLICY_LIST_NAMESPACE,
|
||||
} from '../common/constants';
|
||||
import { hostMiddlewareFactory } from '../pages/endpoint_hosts/store/middleware';
|
||||
import { endpointMiddlewareFactory } from '../pages/endpoint_hosts/store/middleware';
|
||||
|
||||
const policyListSelector = (state: State) =>
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_POLICY_LIST_NAMESPACE];
|
||||
const policyDetailsSelector = (state: State) =>
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE];
|
||||
const endpointsSelector = (state: State) =>
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_HOSTS_NAMESPACE];
|
||||
state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_ENDPOINTS_NAMESPACE];
|
||||
|
||||
export const managementMiddlewareFactory: SecuritySubPluginMiddlewareFactory = (
|
||||
coreStart,
|
||||
|
@ -39,6 +39,6 @@ export const managementMiddlewareFactory: SecuritySubPluginMiddlewareFactory = (
|
|||
policyDetailsSelector,
|
||||
policyDetailsMiddlewareFactory(coreStart, depsStart)
|
||||
),
|
||||
substateMiddlewareFactory(endpointsSelector, hostMiddlewareFactory(coreStart, depsStart)),
|
||||
substateMiddlewareFactory(endpointsSelector, endpointMiddlewareFactory(coreStart, depsStart)),
|
||||
];
|
||||
};
|
||||
|
|
|
@ -14,14 +14,17 @@ import {
|
|||
initialPolicyListState,
|
||||
} from '../pages/policy/store/policy_list/reducer';
|
||||
import {
|
||||
MANAGEMENT_STORE_HOSTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_ENDPOINTS_NAMESPACE,
|
||||
MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE,
|
||||
MANAGEMENT_STORE_POLICY_LIST_NAMESPACE,
|
||||
} from '../common/constants';
|
||||
import { ImmutableCombineReducers } from '../../common/store';
|
||||
import { Immutable } from '../../../common/endpoint/types';
|
||||
import { ManagementState } from '../types';
|
||||
import { hostListReducer, initialHostListState } from '../pages/endpoint_hosts/store/reducer';
|
||||
import {
|
||||
endpointListReducer,
|
||||
initialEndpointListState,
|
||||
} from '../pages/endpoint_hosts/store/reducer';
|
||||
|
||||
const immutableCombineReducers: ImmutableCombineReducers = combineReducers;
|
||||
|
||||
|
@ -31,7 +34,7 @@ const immutableCombineReducers: ImmutableCombineReducers = combineReducers;
|
|||
export const mockManagementState: Immutable<ManagementState> = {
|
||||
[MANAGEMENT_STORE_POLICY_LIST_NAMESPACE]: initialPolicyListState(),
|
||||
[MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: initialPolicyDetailsState(),
|
||||
[MANAGEMENT_STORE_HOSTS_NAMESPACE]: initialHostListState,
|
||||
[MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: initialEndpointListState,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,5 +43,5 @@ export const mockManagementState: Immutable<ManagementState> = {
|
|||
export const managementReducer = immutableCombineReducers({
|
||||
[MANAGEMENT_STORE_POLICY_LIST_NAMESPACE]: policyListReducer,
|
||||
[MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: policyDetailsReducer,
|
||||
[MANAGEMENT_STORE_HOSTS_NAMESPACE]: hostListReducer,
|
||||
[MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: endpointListReducer,
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { CombinedState } from 'redux';
|
||||
import { SecurityPageName } from '../app/types';
|
||||
import { PolicyListState, PolicyDetailsState } from './pages/policy/types';
|
||||
import { HostState } from './pages/endpoint_hosts/types';
|
||||
import { EndpointState } from './pages/endpoint_hosts/types';
|
||||
|
||||
/**
|
||||
* The type for the management store global namespace. Used mostly internally to reference
|
||||
|
@ -18,14 +18,14 @@ export type ManagementStoreGlobalNamespace = 'management';
|
|||
export type ManagementState = CombinedState<{
|
||||
policyList: PolicyListState;
|
||||
policyDetails: PolicyDetailsState;
|
||||
hosts: HostState;
|
||||
endpoints: EndpointState;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* The management list of sub-tabs. Changes to these will impact the Router routes.
|
||||
*/
|
||||
export enum AdministrationSubTab {
|
||||
hosts = 'hosts',
|
||||
endpoints = 'endpoints',
|
||||
policies = 'policy',
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
import React, { memo } from 'react';
|
||||
import { EuiCallOut, EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { getHostListPath } from '../../../management/common/routing';
|
||||
import { getEndpointListPath } from '../../../management/common/routing';
|
||||
import { useNavigateToAppEventHandler } from '../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
import { useManagementFormatUrl } from '../../../management/components/hooks/use_management_format_url';
|
||||
import { MANAGEMENT_APP_ID } from '../../../management/common/constants';
|
||||
|
||||
export const EndpointNotice = memo<{ onDismiss: () => void }>(({ onDismiss }) => {
|
||||
const endpointsPath = getHostListPath({ name: 'hostList' });
|
||||
const endpointsPath = getEndpointListPath({ name: 'endpointList' });
|
||||
const endpointsLink = useManagementFormatUrl(endpointsPath);
|
||||
const handleGetStartedClick = useNavigateToAppEventHandler(MANAGEMENT_APP_ID, {
|
||||
path: endpointsPath,
|
||||
|
|
|
@ -16233,65 +16233,65 @@
|
|||
"xpack.securitySolution.editDataProvider.valuePlaceholder": "値",
|
||||
"xpack.securitySolution.emptyMessage": "Elastic セキュリティは無料かつオープンのElastic SIEMに、Elastic Endpointを搭載。脅威の防御と検知、脅威への対応を支援します。開始するには、セキュリティソリューション関連データをElastic Stackに追加する必要があります。詳細については、ご覧ください ",
|
||||
"xpack.securitySolution.emptyString.emptyStringDescription": "空の文字列",
|
||||
"xpack.securitySolution.endpoint.host.details.endpointVersion": "エンドポイントバージョン",
|
||||
"xpack.securitySolution.endpoint.host.details.errorBody": "フライアウトを終了して、利用可能なホストを選択してください。",
|
||||
"xpack.securitySolution.endpoint.host.details.errorTitle": "ホストが見つかりませんでした",
|
||||
"xpack.securitySolution.endpoint.host.details.hostname": "ホスト名",
|
||||
"xpack.securitySolution.endpoint.host.details.ipAddress": "IP アドレス",
|
||||
"xpack.securitySolution.endpoint.host.details.lastSeen": "前回の認識",
|
||||
"xpack.securitySolution.endpoint.host.details.linkToIngestTitle": "ポリシーの再割り当て",
|
||||
"xpack.securitySolution.endpoint.host.details.os": "OS",
|
||||
"xpack.securitySolution.endpoint.host.details.policy": "ポリシー",
|
||||
"xpack.securitySolution.endpoint.host.details.policyStatus": "ポリシーステータス",
|
||||
"xpack.securitySolution.endpoint.host.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失敗} other {不明}}",
|
||||
"xpack.securitySolution.endpoint.host.policyResponse.backLinkTitle": "エンドポイント詳細",
|
||||
"xpack.securitySolution.endpoint.host.policyResponse.title": "ポリシー応答",
|
||||
"xpack.securitySolution.endpoint.hostDetails.noPolicyResponse": "ポリシー応答がありません",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_dns_events": "DNSイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_elasticsearch_connection": "Elastic Search接続の構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_file_events": "ファイルイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_imageload_events": "画像読み込みイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_kernel": "カーネルの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_logging": "ロギングの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_malware": "マルウェアの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_network_events": "ネットワークイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_process_events": "プロセスイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_registry_events": "レジストリイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_security_events": "セキュリティイベントの構成",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.connect_kernel": "カーネルを接続",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_async_image_load_events": "非同期画像読み込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_open_events": "ファイルオープンイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_write_events": "ファイル書き込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_network_events": "ネットワークイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_process_events": "プロセスイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_registry_events": "レジストリイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_sync_image_load_events": "同期画像読み込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.download_global_artifacts": "グローバルアーチファクトをダウンロード",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.download_user_artifacts": "ユーザーアーチファクトをダウンロード",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.events": "イベント",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.failed": "失敗",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.load_config": "構成の読み込み",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.load_malware_model": "マルウェアモデルの読み込み",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.logging": "ログ",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.malware": "マルウェア",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_elasticsearch_config": "Elasticsearch構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_events_config": "イベント構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_kernel_config": "カーネル構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_logging_config": "ロギング構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_malware_config": "マルウェア構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.streaming": "ストリーム中…",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.success": "成功",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.warning": "警告",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.workflow": "ワークフロー",
|
||||
"xpack.securitySolution.endpoint.hostList.beta": "ベータ",
|
||||
"xpack.securitySolution.endpoint.hostList.loadingPolicies": "ポリシー構成を読み込んでいます…",
|
||||
"xpack.securitySolution.endpoint.hostList.noEndpointsInstructions": "セキュリティポリシーを作成しました。以下のステップに従い、エージェントでElastic Endpoint Security機能を有効にする必要があります。",
|
||||
"xpack.securitySolution.endpoint.hostList.noEndpointsPrompt": "エージェントでElastic Endpoint Securityを有効にする",
|
||||
"xpack.securitySolution.endpoint.hostList.noPolicies": "ポリシーがありません。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepOne": "既存のポリシーは以下のリストのとおりです。これは後から変更できます。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepOneTitle": "ホストの保護で使用するポリシーを選択",
|
||||
"xpack.securitySolution.endpoint.hostList.stepTwo": "開始するために必要なコマンドが提供されます。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepTwoTitle": "Ingest Manager経由でEndpoint Securityによって有効にされたエージェントを登録",
|
||||
"xpack.securitySolution.endpoint.details.endpointVersion": "エンドポイントバージョン",
|
||||
"xpack.securitySolution.endpoint.details.errorBody": "フライアウトを終了して、利用可能なホストを選択してください。",
|
||||
"xpack.securitySolution.endpoint.details.errorTitle": "ホストが見つかりませんでした",
|
||||
"xpack.securitySolution.endpoint.details.hostname": "ホスト名",
|
||||
"xpack.securitySolution.endpoint.details.ipAddress": "IP アドレス",
|
||||
"xpack.securitySolution.endpoint.details.lastSeen": "前回の認識",
|
||||
"xpack.securitySolution.endpoint.details.linkToIngestTitle": "ポリシーの再割り当て",
|
||||
"xpack.securitySolution.endpoint.details.os": "OS",
|
||||
"xpack.securitySolution.endpoint.details.policy": "ポリシー",
|
||||
"xpack.securitySolution.endpoint.details.policyStatus": "ポリシーステータス",
|
||||
"xpack.securitySolution.endpoint.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失敗} other {不明}}",
|
||||
"xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "エンドポイント詳細",
|
||||
"xpack.securitySolution.endpoint.policyResponse.title": "ポリシー応答",
|
||||
"xpack.securitySolution.endpoint.details.noPolicyResponse": "ポリシー応答がありません",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_dns_events": "DNSイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_elasticsearch_connection": "Elastic Search接続の構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_file_events": "ファイルイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_imageload_events": "画像読み込みイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_kernel": "カーネルの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_logging": "ロギングの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_malware": "マルウェアの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_network_events": "ネットワークイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_process_events": "プロセスイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_registry_events": "レジストリイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_security_events": "セキュリティイベントの構成",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.connect_kernel": "カーネルを接続",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_async_image_load_events": "非同期画像読み込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_file_open_events": "ファイルオープンイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_file_write_events": "ファイル書き込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_network_events": "ネットワークイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_process_events": "プロセスイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_registry_events": "レジストリイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_sync_image_load_events": "同期画像読み込みイベントを検出",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.download_global_artifacts": "グローバルアーチファクトをダウンロード",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.download_user_artifacts": "ユーザーアーチファクトをダウンロード",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.events": "イベント",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.failed": "失敗",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.load_config": "構成の読み込み",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.load_malware_model": "マルウェアモデルの読み込み",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.logging": "ログ",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.malware": "マルウェア",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_elasticsearch_config": "Elasticsearch構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_events_config": "イベント構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_kernel_config": "カーネル構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_logging_config": "ロギング構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_malware_config": "マルウェア構成を読み取る",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.streaming": "ストリーム中…",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.success": "成功",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.warning": "警告",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.workflow": "ワークフロー",
|
||||
"xpack.securitySolution.endpoint.list.beta": "ベータ",
|
||||
"xpack.securitySolution.endpoint.list.loadingPolicies": "ポリシー構成を読み込んでいます…",
|
||||
"xpack.securitySolution.endpoint.list.noEndpointsInstructions": "セキュリティポリシーを作成しました。以下のステップに従い、エージェントでElastic Endpoint Security機能を有効にする必要があります。",
|
||||
"xpack.securitySolution.endpoint.list.noEndpointsPrompt": "エージェントでElastic Endpoint Securityを有効にする",
|
||||
"xpack.securitySolution.endpoint.list.noPolicies": "ポリシーがありません。",
|
||||
"xpack.securitySolution.endpoint.list.stepOne": "既存のポリシーは以下のリストのとおりです。これは後から変更できます。",
|
||||
"xpack.securitySolution.endpoint.list.stepOneTitle": "ホストの保護で使用するポリシーを選択",
|
||||
"xpack.securitySolution.endpoint.list.stepTwo": "開始するために必要なコマンドが提供されます。",
|
||||
"xpack.securitySolution.endpoint.list.stepTwoTitle": "Ingest Manager経由でEndpoint Securityによって有効にされたエージェントを登録",
|
||||
"xpack.securitySolution.endpoint.ingestManager.createPackageConfig.endpointConfiguration": "このエージェント構成を使用するすべてのエージェントは基本ポリシーを使用します。セキュリティアプリでこのポリシーを変更できます。Fleetはこれらの変更をエージェントにデプロイします。",
|
||||
"xpack.securitySolution.endpoint.ingestToastMessage": "Ingest Managerが設定中に失敗しました。",
|
||||
"xpack.securitySolution.endpoint.ingestToastTitle": "アプリを初期化できませんでした",
|
||||
|
@ -16412,16 +16412,16 @@
|
|||
"xpack.securitySolution.endpoint.resolver.runningTrigger": "トリガーの実行中",
|
||||
"xpack.securitySolution.endpoint.resolver.terminatedProcess": "プロセスを中断しました",
|
||||
"xpack.securitySolution.endpoint.resolver.terminatedTrigger": "トリガーを中断しました",
|
||||
"xpack.securitySolution.endpointList.endpointVersion": "バージョン",
|
||||
"xpack.securitySolution.endpointList.hostname": "ホスト名",
|
||||
"xpack.securitySolution.endpointList.hostStatus": "ホストステータス",
|
||||
"xpack.securitySolution.endpointList.hostStatusValue": "{hostStatus, select, online {オンライン} error {エラー} other {オフライン}}",
|
||||
"xpack.securitySolution.endpointList.ip": "IP アドレス",
|
||||
"xpack.securitySolution.endpointList.lastActive": "前回のアーカイブ",
|
||||
"xpack.securitySolution.endpointList.os": "オペレーティングシステム",
|
||||
"xpack.securitySolution.endpointList.policy": "ポリシー",
|
||||
"xpack.securitySolution.endpointList.policyStatus": "ポリシーステータス",
|
||||
"xpack.securitySolution.endpointList.totalCount": "{totalItemCount, plural, one {# ホスト} other {# ホスト}}",
|
||||
"xpack.securitySolution.endpoint.list.endpointVersion": "バージョン",
|
||||
"xpack.securitySolution.endpoint.list.hostname": "ホスト名",
|
||||
"xpack.securitySolution.endpoint.list.hostStatus": "ホストステータス",
|
||||
"xpack.securitySolution.endpoint.list.hostStatusValue": "{hostStatus, select, online {オンライン} error {エラー} other {オフライン}}",
|
||||
"xpack.securitySolution.endpoint.list.ip": "IP アドレス",
|
||||
"xpack.securitySolution.endpoint.list.lastActive": "前回のアーカイブ",
|
||||
"xpack.securitySolution.endpoint.list.os": "オペレーティングシステム",
|
||||
"xpack.securitySolution.endpoint.list.policy": "ポリシー",
|
||||
"xpack.securitySolution.endpoint.list.policyStatus": "ポリシーステータス",
|
||||
"xpack.securitySolution.endpoint.list.totalCount": "{totalItemCount, plural, one {# ホスト} other {# ホスト}}",
|
||||
"xpack.securitySolution.endpointManagement.noPermissionsSubText": "Ingest Managerが無効である可能性があります。この機能を使用するには、Ingest Managerを有効にする必要があります。Ingest Managerを有効にする権限がない場合は、Kibana管理者に連絡してください。",
|
||||
"xpack.securitySolution.endpointManagemnet.noPermissionsText": "Elastic Security Administrationを使用するために必要なKibana権限がありません。",
|
||||
"xpack.securitySolution.enpdoint.resolver.panelutils.betaBadgeLabel": "BETA",
|
||||
|
@ -16610,8 +16610,8 @@
|
|||
"xpack.securitySolution.host.details.overview.platformTitle": "プラットフォーム",
|
||||
"xpack.securitySolution.host.details.overview.regionTitle": "地域",
|
||||
"xpack.securitySolution.host.details.versionLabel": "バージョン",
|
||||
"xpack.securitySolution.hostList.pageSubTitle": "Elastic Endpoint Securityを実行しているホスト",
|
||||
"xpack.securitySolution.hostList.pageTitle": "ホスト",
|
||||
"xpack.securitySolution.endpoint.list.pageSubTitle": "Elastic Endpoint Securityを実行しているホスト",
|
||||
"xpack.securitySolution.endpoint.list.pageTitle": "ホスト",
|
||||
"xpack.securitySolution.hosts.kqlPlaceholder": "例:host.name: \"foo\"",
|
||||
"xpack.securitySolution.hosts.navigation.alertsTitle": "外部アラート",
|
||||
"xpack.securitySolution.hosts.navigation.allHostsTitle": "すべてのホスト",
|
||||
|
@ -16623,7 +16623,7 @@
|
|||
"xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "認証データをクエリできませんでした",
|
||||
"xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "イベントデータをクエリできませんでした",
|
||||
"xpack.securitySolution.hosts.pageTitle": "ホスト",
|
||||
"xpack.securitySolution.hostsTab": "ホスト",
|
||||
"xpack.securitySolution.endpointsTab": "ホスト",
|
||||
"xpack.securitySolution.hostsTable.firstLastSeenToolTip": "選択された日付範囲との相関付けです",
|
||||
"xpack.securitySolution.hostsTable.hostsTitle": "すべてのホスト",
|
||||
"xpack.securitySolution.hostsTable.lastSeenTitle": "前回の認識",
|
||||
|
|
|
@ -16238,65 +16238,65 @@
|
|||
"xpack.securitySolution.editDataProvider.valuePlaceholder": "值",
|
||||
"xpack.securitySolution.emptyMessage": "Elastic Security 将免费且开放的 Elastic SIEM 和 Elastic Endpoint Security 整合在一起,从而防御、检测并响应威胁。首先,您需要将安全解决方案相关数据添加到 Elastic Stack。有关更多信息,请查看我们的 ",
|
||||
"xpack.securitySolution.emptyString.emptyStringDescription": "空字符串",
|
||||
"xpack.securitySolution.endpoint.host.details.endpointVersion": "Endpoint 版本",
|
||||
"xpack.securitySolution.endpoint.host.details.errorBody": "请退出浮出控件并选择可用主机。",
|
||||
"xpack.securitySolution.endpoint.host.details.errorTitle": "找不到主机",
|
||||
"xpack.securitySolution.endpoint.host.details.hostname": "主机名",
|
||||
"xpack.securitySolution.endpoint.host.details.ipAddress": "IP 地址",
|
||||
"xpack.securitySolution.endpoint.host.details.lastSeen": "最后看到时间",
|
||||
"xpack.securitySolution.endpoint.host.details.linkToIngestTitle": "重新分配策略",
|
||||
"xpack.securitySolution.endpoint.host.details.os": "OS",
|
||||
"xpack.securitySolution.endpoint.host.details.policy": "政策",
|
||||
"xpack.securitySolution.endpoint.host.details.policyStatus": "策略状态",
|
||||
"xpack.securitySolution.endpoint.host.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失败} other {未知}}",
|
||||
"xpack.securitySolution.endpoint.host.policyResponse.backLinkTitle": "终端详情",
|
||||
"xpack.securitySolution.endpoint.host.policyResponse.title": "策略响应",
|
||||
"xpack.securitySolution.endpoint.hostDetails.noPolicyResponse": "没有可用的策略响应",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_dns_events": "配置 DNS 事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_elasticsearch_connection": "配置 Elastic 搜索连接",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_file_events": "配置文件事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_imageload_events": "配置映像加载事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_kernel": "配置内核",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_logging": "配置日志记录",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_malware": "配置恶意软件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_network_events": "配置网络事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_process_events": "配置进程事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_registry_events": "配置注册表事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_security_events": "配置安全事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.connect_kernel": "连接内核",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_async_image_load_events": "检测异步映像加载事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_open_events": "检测文件打开事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_write_events": "检测文件写入事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_network_events": "检测网络事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_process_events": "检测进程事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_registry_events": "检测注册表事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_sync_image_load_events": "检测同步映像加载事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.download_global_artifacts": "下载全局项目",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.download_user_artifacts": "下面用户项目",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.events": "事件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.failed": "失败",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.load_config": "加载配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.load_malware_model": "加载恶意软件模型",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.logging": "日志",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.malware": "恶意软件",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_elasticsearch_config": "读取 ElasticSearch 配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_events_config": "读取时间配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_kernel_config": "读取内核配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_logging_config": "读取日志配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.read_malware_config": "读取恶意软件配置",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.streaming": "流式传输",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.success": "成功",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.warning": "警告",
|
||||
"xpack.securitySolution.endpoint.hostDetails.policyResponse.workflow": "工作流",
|
||||
"xpack.securitySolution.endpoint.hostList.beta": "公测版",
|
||||
"xpack.securitySolution.endpoint.hostList.loadingPolicies": "正在加载政策配置",
|
||||
"xpack.securitySolution.endpoint.hostList.noEndpointsInstructions": "您已创建安全策略。现在您需要按照下面的步骤在代理上启用 Elastic Endpoint Security 功能。",
|
||||
"xpack.securitySolution.endpoint.hostList.noEndpointsPrompt": "在您的代理上启用 Elastic Endpoint Security",
|
||||
"xpack.securitySolution.endpoint.hostList.noPolicies": "没有策略。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepOne": "现有策略在下面列出。之后可以对其进行更改。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepOneTitle": "选择要用于保护主机的策略",
|
||||
"xpack.securitySolution.endpoint.hostList.stepTwo": "为了让您入门,将会为您提供必要的命令。",
|
||||
"xpack.securitySolution.endpoint.hostList.stepTwoTitle": "通过采集管理器注册启用 Endpoint Security 的代理",
|
||||
"xpack.securitySolution.endpoint.details.endpointVersion": "Endpoint 版本",
|
||||
"xpack.securitySolution.endpoint.details.errorBody": "请退出浮出控件并选择可用主机。",
|
||||
"xpack.securitySolution.endpoint.details.errorTitle": "找不到主机",
|
||||
"xpack.securitySolution.endpoint.details.hostname": "主机名",
|
||||
"xpack.securitySolution.endpoint.details.ipAddress": "IP 地址",
|
||||
"xpack.securitySolution.endpoint.details.lastSeen": "最后看到时间",
|
||||
"xpack.securitySolution.endpoint.details.linkToIngestTitle": "重新分配策略",
|
||||
"xpack.securitySolution.endpoint.details.os": "OS",
|
||||
"xpack.securitySolution.endpoint.details.policy": "政策",
|
||||
"xpack.securitySolution.endpoint.details.policyStatus": "策略状态",
|
||||
"xpack.securitySolution.endpoint.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失败} other {未知}}",
|
||||
"xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "终端详情",
|
||||
"xpack.securitySolution.endpoint.policyResponse.title": "策略响应",
|
||||
"xpack.securitySolution.endpoint.details.noPolicyResponse": "没有可用的策略响应",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_dns_events": "配置 DNS 事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_elasticsearch_connection": "配置 Elastic 搜索连接",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_file_events": "配置文件事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_imageload_events": "配置映像加载事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_kernel": "配置内核",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_logging": "配置日志记录",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_malware": "配置恶意软件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_network_events": "配置网络事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_process_events": "配置进程事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_registry_events": "配置注册表事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.configure_security_events": "配置安全事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.connect_kernel": "连接内核",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_async_image_load_events": "检测异步映像加载事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_file_open_events": "检测文件打开事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_file_write_events": "检测文件写入事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_network_events": "检测网络事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_process_events": "检测进程事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_registry_events": "检测注册表事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.detect_sync_image_load_events": "检测同步映像加载事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.download_global_artifacts": "下载全局项目",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.download_user_artifacts": "下面用户项目",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.events": "事件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.failed": "失败",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.load_config": "加载配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.load_malware_model": "加载恶意软件模型",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.logging": "日志",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.malware": "恶意软件",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_elasticsearch_config": "读取 ElasticSearch 配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_events_config": "读取时间配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_kernel_config": "读取内核配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_logging_config": "读取日志配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.read_malware_config": "读取恶意软件配置",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.streaming": "流式传输",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.success": "成功",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.warning": "警告",
|
||||
"xpack.securitySolution.endpoint.details.policyResponse.workflow": "工作流",
|
||||
"xpack.securitySolution.endpoint.list.beta": "公测版",
|
||||
"xpack.securitySolution.endpoint.list.loadingPolicies": "正在加载政策配置",
|
||||
"xpack.securitySolution.endpoint.list.noEndpointsInstructions": "您已创建安全策略。现在您需要按照下面的步骤在代理上启用 Elastic Endpoint Security 功能。",
|
||||
"xpack.securitySolution.endpoint.list.noEndpointsPrompt": "在您的代理上启用 Elastic Endpoint Security",
|
||||
"xpack.securitySolution.endpoint.list.noPolicies": "没有策略。",
|
||||
"xpack.securitySolution.endpoint.list.stepOne": "现有策略在下面列出。之后可以对其进行更改。",
|
||||
"xpack.securitySolution.endpoint.list.stepOneTitle": "选择要用于保护主机的策略",
|
||||
"xpack.securitySolution.endpoint.list.stepTwo": "为了让您入门,将会为您提供必要的命令。",
|
||||
"xpack.securitySolution.endpoint.list.stepTwoTitle": "通过采集管理器注册启用 Endpoint Security 的代理",
|
||||
"xpack.securitySolution.endpoint.ingestManager.createPackageConfig.endpointConfiguration": "使用此代理配置的任何代理都会使用基本策略。可以在 Security 应用中对此策略进行更改,Fleet 会将这些更改部署到代理。",
|
||||
"xpack.securitySolution.endpoint.ingestToastMessage": "采集管理器在其设置期间失败。",
|
||||
"xpack.securitySolution.endpoint.ingestToastTitle": "应用无法初始化",
|
||||
|
@ -16418,16 +16418,16 @@
|
|||
"xpack.securitySolution.endpoint.resolver.runningTrigger": "正在运行的触发器",
|
||||
"xpack.securitySolution.endpoint.resolver.terminatedProcess": "已终止进程",
|
||||
"xpack.securitySolution.endpoint.resolver.terminatedTrigger": "已终止触发器",
|
||||
"xpack.securitySolution.endpointList.endpointVersion": "版本",
|
||||
"xpack.securitySolution.endpointList.hostname": "主机名",
|
||||
"xpack.securitySolution.endpointList.hostStatus": "主机状态",
|
||||
"xpack.securitySolution.endpointList.hostStatusValue": "{hostStatus, select, online {联机} error {错误} other {脱机}}",
|
||||
"xpack.securitySolution.endpointList.ip": "IP 地址",
|
||||
"xpack.securitySolution.endpointList.lastActive": "上次活动时间",
|
||||
"xpack.securitySolution.endpointList.os": "操作系统",
|
||||
"xpack.securitySolution.endpointList.policy": "政策",
|
||||
"xpack.securitySolution.endpointList.policyStatus": "策略状态",
|
||||
"xpack.securitySolution.endpointList.totalCount": "{totalItemCount, plural, one {# 个主机} other {# 个主机}}",
|
||||
"xpack.securitySolution.endpoint.list.endpointVersion": "版本",
|
||||
"xpack.securitySolution.endpoint.list.hostname": "主机名",
|
||||
"xpack.securitySolution.endpoint.list.hostStatus": "主机状态",
|
||||
"xpack.securitySolution.endpoint.list.hostStatusValue": "{hostStatus, select, online {联机} error {错误} other {脱机}}",
|
||||
"xpack.securitySolution.endpoint.list.ip": "IP 地址",
|
||||
"xpack.securitySolution.endpoint.list.lastActive": "上次活动时间",
|
||||
"xpack.securitySolution.endpoint.list.os": "操作系统",
|
||||
"xpack.securitySolution.endpoint.list.policy": "政策",
|
||||
"xpack.securitySolution.endpoint.list.policyStatus": "策略状态",
|
||||
"xpack.securitySolution.endpoint.list.totalCount": "{totalItemCount, plural, one {# 个主机} other {# 个主机}}",
|
||||
"xpack.securitySolution.endpointManagement.noPermissionsSubText": "似乎采集管理器已禁用。必须启用采集管理器,才能使用此功能。如果您无权启用采集管理器,请联系您的 Kibana 管理员。",
|
||||
"xpack.securitySolution.endpointManagemnet.noPermissionsText": "您没有所需的 Kibana 权限,无法使用 Elastic Security 管理",
|
||||
"xpack.securitySolution.enpdoint.resolver.panelutils.betaBadgeLabel": "公测版",
|
||||
|
@ -16616,8 +16616,8 @@
|
|||
"xpack.securitySolution.host.details.overview.platformTitle": "平台",
|
||||
"xpack.securitySolution.host.details.overview.regionTitle": "地区",
|
||||
"xpack.securitySolution.host.details.versionLabel": "版本",
|
||||
"xpack.securitySolution.hostList.pageSubTitle": "运行 Elastic Endpoint Security 的主机",
|
||||
"xpack.securitySolution.hostList.pageTitle": "主机",
|
||||
"xpack.securitySolution.endpoint.list.pageSubTitle": "运行 Elastic Endpoint Security 的主机",
|
||||
"xpack.securitySolution.endpoint.list.pageTitle": "主机",
|
||||
"xpack.securitySolution.hosts.kqlPlaceholder": "例如 host.name:“foo”",
|
||||
"xpack.securitySolution.hosts.navigation.alertsTitle": "外部告警",
|
||||
"xpack.securitySolution.hosts.navigation.allHostsTitle": "所有主机",
|
||||
|
@ -16629,7 +16629,7 @@
|
|||
"xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "无法查询身份验证数据",
|
||||
"xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "无法查询事件数据",
|
||||
"xpack.securitySolution.hosts.pageTitle": "主机",
|
||||
"xpack.securitySolution.hostsTab": "主机",
|
||||
"xpack.securitySolution.endpointsTab": "主机",
|
||||
"xpack.securitySolution.hostsTable.firstLastSeenToolTip": "相对于选定日期范围",
|
||||
"xpack.securitySolution.hostsTable.hostsTitle": "所有主机",
|
||||
"xpack.securitySolution.hostsTable.lastSeenTitle": "最后看到时间",
|
||||
|
|
|
@ -13,14 +13,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
const esArchiver = getService('esArchiver');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('host list', function () {
|
||||
describe('endpoint list', function () {
|
||||
this.tags('ciGroup7');
|
||||
const sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
describe('when there is data,', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('endpoint/metadata/api_feature', { useCreate: true });
|
||||
await pageObjects.endpoint.navigateToHostList();
|
||||
await pageObjects.endpoint.navigateToEndpointList();
|
||||
});
|
||||
after(async () => {
|
||||
await deleteMetadataStream(getService);
|
||||
|
@ -28,14 +28,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
|
||||
it('finds page title', async () => {
|
||||
const title = await testSubjects.getVisibleText('pageViewHeaderLeftTitle');
|
||||
expect(title).to.equal('Hosts');
|
||||
expect(title).to.equal('Endpoints');
|
||||
});
|
||||
|
||||
it('displays table data', async () => {
|
||||
const expectedData = [
|
||||
[
|
||||
'Hostname',
|
||||
'Host Status',
|
||||
'Agent Status',
|
||||
'Integration',
|
||||
'Configuration Status',
|
||||
'Operating System',
|
||||
|
@ -74,70 +74,76 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
'Jan 24, 2020 @ 16:06:09.541',
|
||||
],
|
||||
];
|
||||
const tableData = await pageObjects.endpointPageUtils.tableData('hostListTable');
|
||||
const tableData = await pageObjects.endpointPageUtils.tableData('endpointListTable');
|
||||
expect(tableData).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('does not show the details flyout initially', async () => {
|
||||
await testSubjects.missingOrFail('hostDetailsFlyout');
|
||||
await testSubjects.missingOrFail('endpointDetailsFlyout');
|
||||
});
|
||||
|
||||
describe('when the hostname is clicked on,', () => {
|
||||
it('display the details flyout', async () => {
|
||||
await (await testSubjects.find('hostnameCellLink')).click();
|
||||
await testSubjects.existOrFail('hostDetailsUpperList');
|
||||
await testSubjects.existOrFail('hostDetailsLowerList');
|
||||
await testSubjects.existOrFail('endpointDetailsUpperList');
|
||||
await testSubjects.existOrFail('endpointDetailsLowerList');
|
||||
});
|
||||
|
||||
it('updates the details flyout when a new hostname is selected from the list', async () => {
|
||||
// display flyout for the first host in the list
|
||||
// display flyout for the first endpoint in the list
|
||||
await (await testSubjects.findAll('hostnameCellLink'))[0].click();
|
||||
await testSubjects.existOrFail('hostDetailsFlyoutTitle');
|
||||
const hostDetailTitle0 = await testSubjects.getVisibleText('hostDetailsFlyoutTitle');
|
||||
// select the 2nd host in the host list
|
||||
await testSubjects.existOrFail('endpointDetailsFlyoutTitle');
|
||||
const endpointDetailTitle0 = await testSubjects.getVisibleText(
|
||||
'endpointDetailsFlyoutTitle'
|
||||
);
|
||||
// select the 2nd endpoint in the endpoint list
|
||||
await (await testSubjects.findAll('hostnameCellLink'))[1].click();
|
||||
await pageObjects.endpoint.waitForVisibleTextToChange(
|
||||
'hostDetailsFlyoutTitle',
|
||||
hostDetailTitle0
|
||||
'endpointDetailsFlyoutTitle',
|
||||
endpointDetailTitle0
|
||||
);
|
||||
const hostDetailTitle1 = await testSubjects.getVisibleText('hostDetailsFlyoutTitle');
|
||||
expect(hostDetailTitle1).to.not.eql(hostDetailTitle0);
|
||||
const endpointDetailTitle1 = await testSubjects.getVisibleText(
|
||||
'endpointDetailsFlyoutTitle'
|
||||
);
|
||||
expect(endpointDetailTitle1).to.not.eql(endpointDetailTitle0);
|
||||
});
|
||||
|
||||
it('has the same flyout info when the same hostname is selected', async () => {
|
||||
// display flyout for the first host in the list
|
||||
// display flyout for the first endpoint in the list
|
||||
await (await testSubjects.findAll('hostnameCellLink'))[1].click();
|
||||
await testSubjects.existOrFail('hostDetailsFlyoutTitle');
|
||||
const hostDetailTitleInitial = await testSubjects.getVisibleText(
|
||||
'hostDetailsFlyoutTitle'
|
||||
await testSubjects.existOrFail('endpointDetailsFlyoutTitle');
|
||||
const endpointDetailTitleInitial = await testSubjects.getVisibleText(
|
||||
'endpointDetailsFlyoutTitle'
|
||||
);
|
||||
// select the same host in the host list
|
||||
// select the same endpoint in the endpoint list
|
||||
await (await testSubjects.findAll('hostnameCellLink'))[1].click();
|
||||
await sleep(500); // give page time to refresh and verify it did not change
|
||||
const hostDetailTitleNew = await testSubjects.getVisibleText('hostDetailsFlyoutTitle');
|
||||
expect(hostDetailTitleNew).to.equal(hostDetailTitleInitial);
|
||||
const endpointDetailTitleNew = await testSubjects.getVisibleText(
|
||||
'endpointDetailsFlyoutTitle'
|
||||
);
|
||||
expect(endpointDetailTitleNew).to.equal(endpointDetailTitleInitial);
|
||||
});
|
||||
|
||||
// The integration does not work properly yet. Skipping this test for now.
|
||||
it.skip('navigates to ingest fleet when the Reassign Configuration link is clicked', async () => {
|
||||
await (await testSubjects.find('hostnameCellLink')).click();
|
||||
await (await testSubjects.find('hostDetailsLinkToIngest')).click();
|
||||
await (await testSubjects.find('endpointDetailsLinkToIngest')).click();
|
||||
await testSubjects.existOrFail('fleetAgentListTable');
|
||||
});
|
||||
});
|
||||
|
||||
// This set of tests fails the flyout does not open in the before() and will be fixed in soon
|
||||
describe.skip('has a url with a host id', () => {
|
||||
describe.skip("has a url with an endpoint host's id", () => {
|
||||
before(async () => {
|
||||
await pageObjects.endpoint.navigateToHostList(
|
||||
await pageObjects.endpoint.navigateToEndpointList(
|
||||
'selected_host=fc0ff548-feba-41b6-8367-65e8790d0eaf'
|
||||
);
|
||||
});
|
||||
|
||||
it('shows a flyout', async () => {
|
||||
await testSubjects.existOrFail('hostDetailsFlyoutBody');
|
||||
await testSubjects.existOrFail('hostDetailsUpperList');
|
||||
await testSubjects.existOrFail('hostDetailsLowerList');
|
||||
await testSubjects.existOrFail('endpointDetailsFlyoutBody');
|
||||
await testSubjects.existOrFail('endpointDetailsUpperList');
|
||||
await testSubjects.existOrFail('endpointDetailsLowerList');
|
||||
});
|
||||
|
||||
it('displays details row headers', async () => {
|
||||
|
@ -151,13 +157,15 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
'Hostname',
|
||||
'Sensor Version',
|
||||
];
|
||||
const keys = await pageObjects.endpoint.hostFlyoutDescriptionKeys('hostDetailsFlyout');
|
||||
const keys = await pageObjects.endpoint.endpointFlyoutDescriptionKeys(
|
||||
'endpointDetailsFlyout'
|
||||
);
|
||||
expect(keys).to.eql(expectedData);
|
||||
});
|
||||
|
||||
it('displays details row descriptions', async () => {
|
||||
const values = await pageObjects.endpoint.hostFlyoutDescriptionValues(
|
||||
'hostDetailsFlyout'
|
||||
const values = await pageObjects.endpoint.endpointFlyoutDescriptionValues(
|
||||
'endpointDetailsFlyout'
|
||||
);
|
||||
|
||||
expect(values).to.eql([
|
||||
|
@ -178,7 +186,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
before(async () => {
|
||||
// clear out the data and reload the page
|
||||
await deleteMetadataStream(getService);
|
||||
await pageObjects.endpoint.navigateToHostList();
|
||||
await pageObjects.endpoint.navigateToEndpointList();
|
||||
});
|
||||
it('displays empty Policy Table page.', async () => {
|
||||
await testSubjects.existOrFail('emptyPolicyTable');
|
||||
|
|
|
@ -81,7 +81,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await pageObjects.policy.confirmAndSave();
|
||||
|
||||
await testSubjects.existOrFail('policyDetailsSuccessMessage');
|
||||
await pageObjects.endpoint.navigateToHostList();
|
||||
await pageObjects.endpoint.navigateToEndpointList();
|
||||
await pageObjects.policy.navigateToPolicyDetails(policyInfo.packageConfig.id);
|
||||
|
||||
expect(await (await testSubjects.find('policyWindowsEvent_process')).isSelected()).to.equal(
|
||||
|
|
|
@ -14,12 +14,12 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider
|
|||
|
||||
return {
|
||||
/**
|
||||
* Navigate to the Hosts list page
|
||||
* Navigate to the Endpoints list page
|
||||
*/
|
||||
async navigateToHostList(searchParams?: string) {
|
||||
async navigateToEndpointList(searchParams?: string) {
|
||||
await pageObjects.common.navigateToUrlWithBrowserHistory(
|
||||
'securitySolutionManagement',
|
||||
`/hosts${searchParams ? `?${searchParams}` : ''}`
|
||||
`/endpoints${searchParams ? `?${searchParams}` : ''}`
|
||||
);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
},
|
||||
|
@ -51,7 +51,7 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider
|
|||
});
|
||||
},
|
||||
|
||||
async hostFlyoutDescriptionKeys(dataTestSubj: string) {
|
||||
async endpointFlyoutDescriptionKeys(dataTestSubj: string) {
|
||||
await testSubjects.exists(dataTestSubj);
|
||||
const detailsData: WebElementWrapper = await testSubjects.find(dataTestSubj);
|
||||
const $ = await detailsData.parseDomContent();
|
||||
|
@ -65,7 +65,7 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider
|
|||
);
|
||||
},
|
||||
|
||||
async hostFlyoutDescriptionValues(dataTestSubj: string) {
|
||||
async endpointFlyoutDescriptionValues(dataTestSubj: string) {
|
||||
await testSubjects.exists(dataTestSubj);
|
||||
const detailsData: WebElementWrapper = await testSubjects.find(dataTestSubj);
|
||||
const $ = await detailsData.parseDomContent();
|
||||
|
|
Loading…
Reference in a new issue