[SECURITY_SOLUTION] adjust policy onboarding view, check for Ingest permissions (#70536)
* adjust policy onboarding view * correct test subj * fix tests * re-enable tests * add no permissions view * adjust onbording look * adjust text * use ingest hook, add tests * adjust text * address comments * beta badges * fix test * correct timeline flyout Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
d58f52de2b
commit
09da11047d
|
@ -7,7 +7,7 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useRouteSpy } from '../route/use_route_spy';
|
||||
|
||||
const hideTimelineForRoutes = [`/cases/configure`, '/management'];
|
||||
const hideTimelineForRoutes = [`/cases/configure`, '/administration'];
|
||||
|
||||
export const useShowTimeline = () => {
|
||||
const [{ pageName, pathName }] = useRouteSpy();
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
EuiSelectable,
|
||||
EuiSelectableMessage,
|
||||
EuiSelectableProps,
|
||||
EuiIcon,
|
||||
EuiLoadingSpinner,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -35,71 +36,121 @@ const PolicyEmptyState = React.memo<{
|
|||
onActionClick: (event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;
|
||||
actionDisabled?: boolean;
|
||||
}>(({ loading, onActionClick, actionDisabled }) => {
|
||||
const policySteps = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.policyList.stepOneTitle', {
|
||||
defaultMessage: 'Head over to Ingest Manager.',
|
||||
}),
|
||||
children: (
|
||||
<EuiText color="subdued" size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.stepOne"
|
||||
defaultMessage="Here, you’ll add the Elastic Endpoint Security Integration to your Agent Configuration."
|
||||
/>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.policyList.stepTwoTitle', {
|
||||
defaultMessage: 'We’ll create a recommended security policy for you.',
|
||||
}),
|
||||
children: (
|
||||
<EuiText color="subdued" size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.stepTwo"
|
||||
defaultMessage="You can edit this policy in the “Policies” tab after you’ve added the Elastic Endpoint integration."
|
||||
/>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.policyList.stepThreeTitle', {
|
||||
defaultMessage: 'Enroll your agents through Fleet.',
|
||||
}),
|
||||
children: (
|
||||
<EuiText color="subdued" size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.stepThree"
|
||||
defaultMessage="If you haven’t already, enroll your agents through Fleet using the same agent configuration."
|
||||
/>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<ManagementEmptyState
|
||||
loading={loading}
|
||||
onActionClick={onActionClick}
|
||||
actionDisabled={actionDisabled}
|
||||
dataTestSubj="emptyPolicyTable"
|
||||
steps={policySteps}
|
||||
headerComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.noPolicyPrompt"
|
||||
defaultMessage="Looks like you're not using the Elastic Endpoint"
|
||||
/>
|
||||
}
|
||||
bodyComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.noPolicyInstructions"
|
||||
defaultMessage="Elastic Endpoint Security gives you the power to keep your endpoints safe from attack, as well as unparalleled visibility into any threat in your environment."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<div data-test-subj="emptyPolicyTable">
|
||||
{loading ? (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLoadingSpinner size="xl" className="essentialAnimation" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<EuiFlexGroup data-test-subj="policyOnboardingInstructions">
|
||||
<EuiFlexItem>
|
||||
<EuiText>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingTitle"
|
||||
defaultMessage="Get started with Elastic Endpoint Security"
|
||||
/>
|
||||
</h3>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiText size="s" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingSectionOne"
|
||||
defaultMessage="Elastic Endpoint Security gives you the power to keep your endpoints safe from attack, as well as unparalleled visibility into any threat in your environment."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiText size="s" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingSectionTwo"
|
||||
defaultMessage="You’ll be able to view and manage hosts in your environment running the Elastic Endpoint from this page."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false} style={{ marginRight: '10px' }}>
|
||||
<EuiIcon type="search" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} style={{ marginLeft: '0' }}>
|
||||
<EuiText>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingHostTitle"
|
||||
defaultMessage="Hosts"
|
||||
/>
|
||||
</h4>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingHostInfo"
|
||||
defaultMessage="Hosts running the Elastic Endpoint"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false} style={{ marginRight: '10px' }}>
|
||||
<EuiIcon type="tableDensityExpanded" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} style={{ marginLeft: '0' }}>
|
||||
<EuiText>
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingPolicyTitle"
|
||||
defaultMessage="Policies"
|
||||
/>
|
||||
</h4>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingPolicyInfo"
|
||||
defaultMessage="View and configure protections"
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiText size="s" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.onboardingSectionThree"
|
||||
defaultMessage="To get started, you’ll have to add the Elastic Endpoint integration to your Agents. Let’s do that now!"
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xl" />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
onClick={onActionClick}
|
||||
isDisabled={actionDisabled}
|
||||
data-test-subj="onboardingStartButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.actionButtonText"
|
||||
defaultMessage="Add Endpoint Security"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiIcon type="logoSecurity" size="xl" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -114,17 +165,17 @@ const HostsEmptyState = React.memo<{
|
|||
() => [
|
||||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.hostList.stepOneTitle', {
|
||||
defaultMessage: 'Select a policy you created from the list below.',
|
||||
defaultMessage: 'Select the policy you want to use to protect your hosts',
|
||||
}),
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued" size="xs">
|
||||
<EuiText color="subdued" size="m" grow={false}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.stepOne"
|
||||
defaultMessage="These are existing policies."
|
||||
defaultMessage="Existing policies are listed below. This can be changed later."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiSelectable
|
||||
options={selectionOptions}
|
||||
singleSelection="always"
|
||||
|
@ -158,38 +209,54 @@ const HostsEmptyState = React.memo<{
|
|||
{
|
||||
title: i18n.translate('xpack.securitySolution.endpoint.hostList.stepTwoTitle', {
|
||||
defaultMessage:
|
||||
'Head over to Ingest to deploy your Agent with Endpoint Security enabled.',
|
||||
'Enroll your agents enabled with Endpoint Security through Ingest Manager',
|
||||
}),
|
||||
status: actionDisabled ? 'disabled' : '',
|
||||
children: (
|
||||
<EuiText color="subdued" size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.stepTwo"
|
||||
defaultMessage="You'll be given a command in Ingest to get you started."
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiText color="subdued" size="m" grow={false}>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.stepTwo"
|
||||
defaultMessage="You’ll be provided with the necessary commands to get started."
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
onClick={onActionClick}
|
||||
isDisabled={actionDisabled}
|
||||
data-test-subj="onboardingStartButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.emptyCreateNewButton"
|
||||
defaultMessage="Enroll Agent"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
),
|
||||
},
|
||||
],
|
||||
[selectionOptions, handleSelectableOnChange, loading]
|
||||
[selectionOptions, handleSelectableOnChange, loading, actionDisabled, onActionClick]
|
||||
);
|
||||
|
||||
return (
|
||||
<ManagementEmptyState
|
||||
loading={loading}
|
||||
onActionClick={onActionClick}
|
||||
actionDisabled={actionDisabled}
|
||||
dataTestSubj="emptyHostsTable"
|
||||
steps={policySteps}
|
||||
headerComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.noHostsPrompt"
|
||||
defaultMessage="You have a policy, but no hosts are deployed!"
|
||||
id="xpack.securitySolution.endpoint.hostList.noEndpointsPrompt"
|
||||
defaultMessage="Enable Elastic Endpoint Security on your agents"
|
||||
/>
|
||||
}
|
||||
bodyComponent={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.hostList.noHostsInstructions"
|
||||
defaultMessage="Elastic Endpoint Security gives you the power to keep your hosts safe from attack, as well as unparalleled visibility into any threat in your environment."
|
||||
id="xpack.securitySolution.endpoint.hostList.noEndpointsInstructions"
|
||||
defaultMessage="You’ve created your security policy. Now you need to enable the Elastic Endpoint Security capabilities on your agents following the steps below."
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
@ -198,80 +265,45 @@ const HostsEmptyState = React.memo<{
|
|||
|
||||
const ManagementEmptyState = React.memo<{
|
||||
loading: boolean;
|
||||
onActionClick?: (event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => void;
|
||||
actionDisabled?: boolean;
|
||||
actionButton?: JSX.Element;
|
||||
dataTestSubj: string;
|
||||
steps?: ManagementStep[];
|
||||
headerComponent: JSX.Element;
|
||||
bodyComponent: JSX.Element;
|
||||
}>(
|
||||
({
|
||||
loading,
|
||||
onActionClick,
|
||||
actionDisabled,
|
||||
dataTestSubj,
|
||||
steps,
|
||||
actionButton,
|
||||
headerComponent,
|
||||
bodyComponent,
|
||||
}) => {
|
||||
return (
|
||||
<div data-test-subj={dataTestSubj}>
|
||||
{loading ? (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLoadingSpinner size="xl" className="essentialAnimation" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<>
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiTitle size="m">
|
||||
<h2 style={TEXT_ALIGN_CENTER}>{headerComponent}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiText textAlign="center" color="subdued" size="s">
|
||||
{bodyComponent}
|
||||
</EuiText>
|
||||
<EuiSpacer size="xxl" />
|
||||
{steps && (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSteps steps={steps} data-test-subj={'onboardingSteps'} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
}>(({ loading, dataTestSubj, steps, headerComponent, bodyComponent }) => {
|
||||
return (
|
||||
<div data-test-subj={dataTestSubj}>
|
||||
{loading ? (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLoadingSpinner size="xl" className="essentialAnimation" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<>
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiTitle size="m">
|
||||
<h2 style={TEXT_ALIGN_CENTER}>{headerComponent}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="xxl" />
|
||||
<EuiText textAlign="center" color="subdued" size="m">
|
||||
{bodyComponent}
|
||||
</EuiText>
|
||||
<EuiSpacer size="xxl" />
|
||||
{steps && (
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<>
|
||||
{actionButton ? (
|
||||
actionButton
|
||||
) : (
|
||||
<EuiButton
|
||||
fill
|
||||
onClick={onActionClick}
|
||||
isDisabled={actionDisabled}
|
||||
data-test-subj="onboardingStartButton"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.policyList.emptyCreateNewButton"
|
||||
defaultMessage="Click here to get started"
|
||||
/>
|
||||
</EuiButton>
|
||||
)}
|
||||
</>
|
||||
<EuiSteps steps={steps} data-test-subj={'onboardingSteps'} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
PolicyEmptyState.displayName = 'PolicyEmptyState';
|
||||
HostsEmptyState.displayName = 'HostsEmptyState';
|
||||
ManagementEmptyState.displayName = 'ManagementEmptyState';
|
||||
|
||||
export { PolicyEmptyState, HostsEmptyState, ManagementEmptyState };
|
||||
export { PolicyEmptyState, HostsEmptyState };
|
||||
|
|
|
@ -16,6 +16,9 @@ import {
|
|||
EuiHealth,
|
||||
EuiToolTip,
|
||||
EuiSelectableProps,
|
||||
EuiBetaBadge,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
} from '@elastic/eui';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -374,14 +377,25 @@ export const HostList = () => {
|
|||
data-test-subj="hostPage"
|
||||
headerLeft={
|
||||
<>
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="pageViewHeaderLeftTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.hostList.pageTitle"
|
||||
defaultMessage="Hosts"
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="pageViewHeaderLeftTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.hostList.pageTitle"
|
||||
defaultMessage="Hosts"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBetaBadge
|
||||
label={i18n.translate('xpack.securitySolution.endpoint.hostList.beta', {
|
||||
defaultMessage: 'Beta',
|
||||
})}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { ManagementContainer } from './index';
|
||||
import { AppContextTestRender, createAppRootMockRenderer } from '../../common/mock/endpoint';
|
||||
import { useIngestEnabledCheck } from '../../common/hooks/endpoint/ingest_enabled';
|
||||
|
||||
jest.mock('../../common/hooks/endpoint/ingest_enabled');
|
||||
|
||||
describe('when in the Admistration tab', () => {
|
||||
let render: () => ReturnType<AppContextTestRender['render']>;
|
||||
|
||||
beforeEach(() => {
|
||||
const mockedContext = createAppRootMockRenderer();
|
||||
render = () => mockedContext.render(<ManagementContainer />);
|
||||
});
|
||||
|
||||
it('should display the No Permissions view when Ingest is OFF', async () => {
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: false });
|
||||
const renderResult = render();
|
||||
const noIngestPermissions = await renderResult.findByTestId('noIngestPermissions');
|
||||
expect(noIngestPermissions).not.toBeNull();
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
|
@ -7,6 +7,8 @@
|
|||
import React, { memo } from 'react';
|
||||
import { useHistory, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { EuiText, EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { PolicyContainer } from './policy';
|
||||
import {
|
||||
MANAGEMENT_ROUTING_HOSTS_PATH,
|
||||
|
@ -16,9 +18,49 @@ import {
|
|||
import { NotFoundPage } from '../../app/404';
|
||||
import { HostsContainer } from './endpoint_hosts';
|
||||
import { getHostListPath } from '../common/routing';
|
||||
import { SpyRoute } from '../../common/utils/route/spy_routes';
|
||||
import { SecurityPageName } from '../../app/types';
|
||||
import { useIngestEnabledCheck } from '../../common/hooks/endpoint/ingest_enabled';
|
||||
|
||||
const NoPermissions = memo(() => {
|
||||
return (
|
||||
<>
|
||||
<EuiEmptyPrompt
|
||||
iconType="alert"
|
||||
iconColor="danger"
|
||||
titleSize="l"
|
||||
data-test-subj="noIngestPermissions"
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointManagemnet.noPermissionsText"
|
||||
defaultMessage="You do not have the required Kibana permissions to use Elastic Security Administration"
|
||||
/>
|
||||
}
|
||||
body={
|
||||
<p>
|
||||
<EuiText color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpointManagemnet.noPermissionsSubText"
|
||||
defaultMessage="It looks like Ingest Manager is disabled. Ingest Manager must be enabled to use this feature. If you do not have permissions to enable Ingest Manager, contact your Kibana administrator."
|
||||
/>
|
||||
</EuiText>
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<SpyRoute pageName={SecurityPageName.management} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
NoPermissions.displayName = 'NoPermissions';
|
||||
|
||||
export const ManagementContainer = memo(() => {
|
||||
const history = useHistory();
|
||||
const { allEnabled: isIngestEnabled } = useIngestEnabledCheck();
|
||||
|
||||
if (!isIngestEnabled) {
|
||||
return <Route path="*" component={NoPermissions} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={MANAGEMENT_ROUTING_HOSTS_PATH} component={HostsContainer} />
|
||||
|
|
|
@ -37,9 +37,9 @@ describe('when on the policies page', () => {
|
|||
expect(table).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should display the onboarding steps', async () => {
|
||||
it('should display the instructions', async () => {
|
||||
const renderResult = render();
|
||||
const onboardingSteps = await renderResult.findByTestId('onboardingSteps');
|
||||
const onboardingSteps = await renderResult.findByTestId('policyOnboardingInstructions');
|
||||
expect(onboardingSteps).not.toBeNull();
|
||||
});
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
EuiConfirmModal,
|
||||
EuiCallOut,
|
||||
EuiButton,
|
||||
EuiBetaBadge,
|
||||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -395,14 +396,25 @@ export const PolicyList = React.memo(() => {
|
|||
data-test-subj="policyListPage"
|
||||
headerLeft={
|
||||
<>
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="pageViewHeaderLeftTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.policyList.pageTitle"
|
||||
defaultMessage="Policies"
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="pageViewHeaderLeftTitle">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.policyList.pageTitle"
|
||||
defaultMessage="Policies"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBetaBadge
|
||||
label={i18n.translate('xpack.securitySolution.endpoint.policyList.beta', {
|
||||
defaultMessage: 'Beta',
|
||||
})}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
|
|
|
@ -104,6 +104,7 @@ describe('Overview', () => {
|
|||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(false));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -128,6 +129,7 @@ describe('Overview', () => {
|
|||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(false));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -152,6 +154,7 @@ describe('Overview', () => {
|
|||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(true));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -171,6 +174,7 @@ describe('Overview', () => {
|
|||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(true));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -190,6 +194,27 @@ describe('Overview', () => {
|
|||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(false));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: true });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<MemoryRouter>
|
||||
<Overview />
|
||||
</MemoryRouter>
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="endpoint-prompt-banner"]').exists()).toBe(false);
|
||||
});
|
||||
|
||||
test('it does NOT render the Endpoint banner when Ingest is NOT available', () => {
|
||||
(useWithSource as jest.Mock).mockReturnValue({
|
||||
indicesExist: true,
|
||||
indexPattern: {},
|
||||
});
|
||||
|
||||
const mockuseMessagesStorage: jest.Mock = useMessagesStorage as jest.Mock<UseMessagesStorage>;
|
||||
mockuseMessagesStorage.mockImplementation(() => endpointNoticeMessage(true));
|
||||
(useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: false });
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
|
|
@ -29,6 +29,7 @@ import { SecurityPageName } from '../../app/types';
|
|||
import { EndpointNotice } from '../components/endpoint_notice';
|
||||
import { useMessagesStorage } from '../../common/containers/local_storage/use_messages_storage';
|
||||
import { ENDPOINT_METADATA_INDEX } from '../../../common/constants';
|
||||
import { useIngestEnabledCheck } from '../../common/hooks/endpoint/ingest_enabled';
|
||||
|
||||
const DEFAULT_QUERY: Query = { query: '', language: 'kuery' };
|
||||
const NO_FILTERS: Filter[] = [];
|
||||
|
@ -64,6 +65,7 @@ const OverviewComponent: React.FC<PropsFromRedux> = ({
|
|||
setDismissMessage(true);
|
||||
addMessage('management', 'dismissEndpointNotice');
|
||||
}, [addMessage]);
|
||||
const { allEnabled: isIngestEnabled } = useIngestEnabledCheck();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -74,7 +76,7 @@ const OverviewComponent: React.FC<PropsFromRedux> = ({
|
|||
</FiltersGlobal>
|
||||
|
||||
<WrapperPage>
|
||||
{!dismissMessage && !metadataIndexExists && (
|
||||
{!dismissMessage && !metadataIndexExists && isIngestEnabled && (
|
||||
<>
|
||||
<EndpointNotice onDismiss={dismissEndpointNotice} />
|
||||
<EuiSpacer size="l" />
|
||||
|
|
Loading…
Reference in a new issue