mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Policy Details: Windows Eventing UI card Co-authored-by: kevinlog <kevin.logan@elastic.co>
This commit is contained in:
parent
420ee5c788
commit
a18633da23
13 changed files with 550 additions and 40 deletions
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 { PolicyConfig } from '../types';
|
||||
|
||||
/**
|
||||
* A typed Object.entries() function where the keys and values are typed based on the given object
|
||||
*/
|
||||
const entries = <T extends object>(o: T): Array<[keyof T, T[keyof T]]> =>
|
||||
Object.entries(o) as Array<[keyof T, T[keyof T]]>;
|
||||
type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> };
|
||||
|
||||
/**
|
||||
* Returns a deep copy of PolicyDetailsConfig
|
||||
*/
|
||||
export function clone(policyDetailsConfig: PolicyConfig): PolicyConfig {
|
||||
const clonedConfig: DeepPartial<PolicyConfig> = {};
|
||||
for (const [key, val] of entries(policyDetailsConfig)) {
|
||||
if (typeof val === 'object') {
|
||||
const valClone: Partial<typeof val> = {};
|
||||
clonedConfig[key] = valClone;
|
||||
for (const [key2, val2] of entries(val)) {
|
||||
if (typeof val2 === 'object') {
|
||||
valClone[key2] = {
|
||||
...val2,
|
||||
};
|
||||
} else {
|
||||
clonedConfig[key] = {
|
||||
...val,
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clonedConfig[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clonedConfig is typed as DeepPartial so we can construct the copy from an empty object
|
||||
*/
|
||||
return clonedConfig as PolicyConfig;
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { PolicyData } from '../../types';
|
||||
import { PolicyData, PolicyConfig } from '../../types';
|
||||
|
||||
interface ServerReturnedPolicyDetailsData {
|
||||
type: 'serverReturnedPolicyDetailsData';
|
||||
|
@ -13,4 +13,14 @@ interface ServerReturnedPolicyDetailsData {
|
|||
};
|
||||
}
|
||||
|
||||
export type PolicyDetailsAction = ServerReturnedPolicyDetailsData;
|
||||
/**
|
||||
* When users change a policy via forms, this action is dispatched with a payload that modifies the configuration of a cloned policy config.
|
||||
*/
|
||||
interface UserChangedPolicyConfig {
|
||||
type: 'userChangedPolicyConfig';
|
||||
payload: {
|
||||
policyConfig: PolicyConfig;
|
||||
};
|
||||
}
|
||||
|
||||
export type PolicyDetailsAction = ServerReturnedPolicyDetailsData | UserChangedPolicyConfig;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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 { PolicyDetailsState } from '../../types';
|
||||
import { createStore, Dispatch, Store } from 'redux';
|
||||
import { policyDetailsReducer, PolicyDetailsAction } from './index';
|
||||
import { policyConfig, windowsEventing } from './selectors';
|
||||
import { clone } from '../../models/policy_details_config';
|
||||
|
||||
describe('policy details: ', () => {
|
||||
let store: Store<PolicyDetailsState>;
|
||||
let getState: typeof store['getState'];
|
||||
let dispatch: Dispatch<PolicyDetailsAction>;
|
||||
|
||||
beforeEach(() => {
|
||||
store = createStore(policyDetailsReducer);
|
||||
getState = store.getState;
|
||||
dispatch = store.dispatch;
|
||||
|
||||
dispatch({
|
||||
type: 'serverReturnedPolicyDetailsData',
|
||||
payload: {
|
||||
policyItem: {
|
||||
id: '',
|
||||
name: '',
|
||||
description: '',
|
||||
config_id: '',
|
||||
enabled: true,
|
||||
output_id: '',
|
||||
inputs: [],
|
||||
namespace: '',
|
||||
package: {
|
||||
name: '',
|
||||
title: '',
|
||||
version: '',
|
||||
},
|
||||
revision: 1,
|
||||
},
|
||||
policyConfig: {
|
||||
windows: {
|
||||
malware: {
|
||||
mode: 'detect',
|
||||
},
|
||||
eventing: {
|
||||
process: false,
|
||||
network: false,
|
||||
},
|
||||
},
|
||||
mac: {
|
||||
malware: {
|
||||
mode: '',
|
||||
},
|
||||
eventing: {
|
||||
process: false,
|
||||
network: false,
|
||||
},
|
||||
},
|
||||
linux: {
|
||||
eventing: {
|
||||
process: false,
|
||||
network: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the user has enabled windows process eventing', () => {
|
||||
beforeEach(() => {
|
||||
const config = policyConfig(getState());
|
||||
if (!config) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
const newPayload1 = clone(config);
|
||||
newPayload1.windows.eventing.process = true;
|
||||
|
||||
dispatch({
|
||||
type: 'userChangedPolicyConfig',
|
||||
payload: { policyConfig: newPayload1 },
|
||||
});
|
||||
});
|
||||
|
||||
it('windows process eventing is enabled', async () => {
|
||||
expect(windowsEventing(getState())!.process).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { MiddlewareFactory, PolicyDetailsState } from '../../types';
|
||||
import { selectPolicyIdFromParams, isOnPolicyDetailsPage } from './selectors';
|
||||
import { policyIdFromParams, isOnPolicyDetailsPage } from './selectors';
|
||||
import { sendGetDatasource } from '../../services/ingest';
|
||||
|
||||
export const policyDetailsMiddlewareFactory: MiddlewareFactory<PolicyDetailsState> = coreStart => {
|
||||
|
@ -16,7 +16,7 @@ export const policyDetailsMiddlewareFactory: MiddlewareFactory<PolicyDetailsStat
|
|||
const state = getState();
|
||||
|
||||
if (action.type === 'userChangedUrl' && isOnPolicyDetailsPage(state)) {
|
||||
const id = selectPolicyIdFromParams(state);
|
||||
const id = policyIdFromParams(state);
|
||||
|
||||
const { item: policyItem } = await sendGetDatasource(http, id);
|
||||
|
||||
|
@ -24,6 +24,19 @@ export const policyDetailsMiddlewareFactory: MiddlewareFactory<PolicyDetailsStat
|
|||
type: 'serverReturnedPolicyDetailsData',
|
||||
payload: {
|
||||
policyItem,
|
||||
policyConfig: {
|
||||
windows: {
|
||||
malware: {
|
||||
mode: 'detect',
|
||||
},
|
||||
eventing: {
|
||||
process: true,
|
||||
network: true,
|
||||
},
|
||||
},
|
||||
mac: {},
|
||||
linux: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { AppAction } from '../action';
|
|||
const initialPolicyDetailsState = (): PolicyDetailsState => {
|
||||
return {
|
||||
policyItem: undefined,
|
||||
policyConfig: undefined,
|
||||
isLoading: false,
|
||||
};
|
||||
};
|
||||
|
@ -34,5 +35,12 @@ export const policyDetailsReducer: Reducer<PolicyDetailsState, AppAction> = (
|
|||
};
|
||||
}
|
||||
|
||||
if (action.type === 'userChangedPolicyConfig') {
|
||||
return {
|
||||
...state,
|
||||
policyConfig: action.payload.policyConfig,
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
import { createSelector } from 'reselect';
|
||||
import { PolicyDetailsState } from '../../types';
|
||||
import { Immutable } from '../../../../../common/types';
|
||||
|
||||
export const selectPolicyDetails = (state: PolicyDetailsState) => state.policyItem;
|
||||
/** Returns the policy details */
|
||||
export const policyDetails = (state: PolicyDetailsState) => state.policyItem;
|
||||
|
||||
/** Returns a boolean of whether the user is on the policy details page or not */
|
||||
export const isOnPolicyDetailsPage = (state: PolicyDetailsState) => {
|
||||
if (state.location) {
|
||||
const pathnameParts = state.location.pathname.split('/');
|
||||
|
@ -18,7 +21,8 @@ export const isOnPolicyDetailsPage = (state: PolicyDetailsState) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const selectPolicyIdFromParams: (state: PolicyDetailsState) => string = createSelector(
|
||||
/** Returns the policyId from the url */
|
||||
export const policyIdFromParams: (state: PolicyDetailsState) => string = createSelector(
|
||||
(state: PolicyDetailsState) => state.location,
|
||||
(location: PolicyDetailsState['location']) => {
|
||||
if (location) {
|
||||
|
@ -27,3 +31,32 @@ export const selectPolicyIdFromParams: (state: PolicyDetailsState) => string = c
|
|||
return '';
|
||||
}
|
||||
);
|
||||
|
||||
/** Returns the policy configuration */
|
||||
export const policyConfig = (state: Immutable<PolicyDetailsState>) => state.policyConfig;
|
||||
|
||||
/** Returns an object of all the windows eventing configuration */
|
||||
export const windowsEventing = (state: PolicyDetailsState) => {
|
||||
const config = policyConfig(state);
|
||||
return config && config.windows.eventing;
|
||||
};
|
||||
|
||||
/** Returns the total number of possible windows eventing configurations */
|
||||
export const totalWindowsEventing = (state: PolicyDetailsState): number => {
|
||||
const config = policyConfig(state);
|
||||
if (config) {
|
||||
return Object.keys(config.windows.eventing).length;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/** Returns the number of selected windows eventing configurations */
|
||||
export const selectedWindowsEventing = (state: PolicyDetailsState): number => {
|
||||
const config = policyConfig(state);
|
||||
if (config) {
|
||||
return Object.values(config.windows.eventing).reduce((count, event) => {
|
||||
return event === true ? count + 1 : count;
|
||||
}, 0);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
|
|
@ -75,17 +75,77 @@ export interface PolicyListState {
|
|||
}
|
||||
|
||||
/**
|
||||
* Policy list store state
|
||||
* Policy details store state
|
||||
*/
|
||||
export interface PolicyDetailsState {
|
||||
/** A single policy item */
|
||||
policyItem: PolicyData | undefined;
|
||||
policyItem?: PolicyData;
|
||||
/** data is being retrieved from server */
|
||||
policyConfig?: PolicyConfig;
|
||||
isLoading: boolean;
|
||||
/** current location of the application */
|
||||
location?: Immutable<EndpointAppLocation>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Policy Details configuration
|
||||
*/
|
||||
export interface PolicyConfig {
|
||||
windows: WindowsPolicyConfig;
|
||||
mac: MacPolicyConfig;
|
||||
linux: LinuxPolicyConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows-specific policy configuration
|
||||
*/
|
||||
interface WindowsPolicyConfig {
|
||||
/** malware mode can be detect, prevent or prevent and notify user */
|
||||
malware: {
|
||||
mode: string;
|
||||
};
|
||||
eventing: {
|
||||
process: boolean;
|
||||
network: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mac-specific policy configuration
|
||||
*/
|
||||
interface MacPolicyConfig {
|
||||
/** malware mode can be detect, prevent or prevent and notify user */
|
||||
malware: {
|
||||
mode: string;
|
||||
};
|
||||
eventing: {
|
||||
process: boolean;
|
||||
network: boolean;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Linux-specific policy configuration
|
||||
*/
|
||||
interface LinuxPolicyConfig {
|
||||
eventing: {
|
||||
process: boolean;
|
||||
network: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/** OS used in Policy */
|
||||
export enum OS {
|
||||
windows = 'windows',
|
||||
mac = 'mac',
|
||||
linux = 'linux',
|
||||
}
|
||||
|
||||
/** Used in Policy */
|
||||
export enum EventingFields {
|
||||
process = 'process',
|
||||
network = 'network',
|
||||
}
|
||||
|
||||
export interface GlobalState {
|
||||
readonly hostList: HostListState;
|
||||
readonly alertList: AlertListState;
|
||||
|
|
|
@ -5,13 +5,26 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiTitle } from '@elastic/eui';
|
||||
import {
|
||||
EuiTitle,
|
||||
EuiPage,
|
||||
EuiPageBody,
|
||||
EuiPageHeader,
|
||||
EuiPageHeaderSection,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiText,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { usePolicyDetailsSelector } from './policy_hooks';
|
||||
import { selectPolicyDetails } from '../../store/policy_details/selectors';
|
||||
import { policyDetails } from '../../store/policy_details/selectors';
|
||||
import { WindowsEventing } from './policy_forms/eventing/windows';
|
||||
|
||||
export const PolicyDetails = React.memo(() => {
|
||||
const policyItem = usePolicyDetailsSelector(selectPolicyDetails);
|
||||
const policyItem = usePolicyDetailsSelector(policyDetails);
|
||||
|
||||
function policyName() {
|
||||
if (policyItem) {
|
||||
|
@ -29,8 +42,41 @@ export const PolicyDetails = React.memo(() => {
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="policyDetailsViewTitle">{policyName()}</h1>
|
||||
</EuiTitle>
|
||||
<EuiPage data-test-subj="policyDetailsPage">
|
||||
<EuiPageBody>
|
||||
<EuiPageHeader>
|
||||
<EuiPageHeaderSection>
|
||||
<EuiTitle size="m">
|
||||
<h1 data-test-subj="policyDetailsViewTitle">{policyName()}</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageHeaderSection>
|
||||
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty>
|
||||
<FormattedMessage
|
||||
id="xpack.endpoint.policy.details.cancel"
|
||||
defaultMessage="Cancel"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton fill={true} iconType="save">
|
||||
<FormattedMessage id="xpack.endpoint.policy.details.save" defaultMessage="Save" />
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPageHeader>
|
||||
<EuiText size="xs" color="subdued">
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.endpoint.policy.details.settings"
|
||||
defaultMessage="Settings"
|
||||
/>
|
||||
</h4>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xs" />
|
||||
<WindowsEventing />
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 {
|
||||
EuiCard,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiTitle,
|
||||
EuiHorizontalRule,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const PolicyDetailCard = styled.div`
|
||||
.policyDetailTitleOS {
|
||||
flex-grow: 2;
|
||||
}
|
||||
.policyDetailTitleFlexItem {
|
||||
margin: 0;
|
||||
}
|
||||
`;
|
||||
export const ConfigForm: React.FC<{
|
||||
type: string;
|
||||
supportedOss: string[];
|
||||
children: React.ReactNode;
|
||||
id: string;
|
||||
selectedEventing: number;
|
||||
totalEventing: number;
|
||||
}> = React.memo(({ type, supportedOss, children, id, selectedEventing, totalEventing }) => {
|
||||
const typeTitle = () => {
|
||||
return (
|
||||
<EuiFlexGroup direction="row" gutterSize="none" alignItems="center">
|
||||
<EuiFlexGroup direction="column" gutterSize="none">
|
||||
<EuiFlexItem className="policyDetailTitleFlexItem">
|
||||
<EuiTitle size="xxxs">
|
||||
<h6>
|
||||
<FormattedMessage id="xpack.endpoint.policyDetailType" defaultMessage="Type" />
|
||||
</h6>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className="policyDetailTitleFlexItem">
|
||||
<EuiText size="m">{type}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexGroup direction="column" gutterSize="none" className="policyDetailTitleOS">
|
||||
<EuiFlexItem className="policyDetailTitleFlexItem">
|
||||
<EuiTitle size="xxxs">
|
||||
<h6>
|
||||
<FormattedMessage
|
||||
id="xpack.endpoint.policyDetailOS"
|
||||
defaultMessage="Operating System"
|
||||
/>
|
||||
</h6>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className="policyDetailTitleFlexItem">
|
||||
<EuiText>{supportedOss.join(', ')}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.endpoint.policy.details.eventCollectionsEnabled"
|
||||
defaultMessage="{selectedEventing} / {totalEventing} event collections enabled"
|
||||
values={{ selectedEventing, totalEventing }}
|
||||
/>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
||||
const events = () => {
|
||||
return (
|
||||
<EuiTitle size="xxs">
|
||||
<h5>
|
||||
<FormattedMessage
|
||||
id="xpack.endpoint.policyDetailsConfig.eventingEvents"
|
||||
defaultMessage="Events"
|
||||
/>
|
||||
</h5>
|
||||
</EuiTitle>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<PolicyDetailCard>
|
||||
<EuiCard
|
||||
data-test-subj={id}
|
||||
textAlign="left"
|
||||
title={typeTitle()}
|
||||
description=""
|
||||
children={
|
||||
<>
|
||||
<EuiHorizontalRule margin="m" />
|
||||
{events()}
|
||||
<EuiSpacer size="s" />
|
||||
{children}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</PolicyDetailCard>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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, { useCallback } from 'react';
|
||||
import { EuiCheckbox } from '@elastic/eui';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { usePolicyDetailsSelector } from '../../policy_hooks';
|
||||
import { policyConfig, windowsEventing } from '../../../../store/policy_details/selectors';
|
||||
import { PolicyDetailsAction } from '../../../../store/policy_details';
|
||||
import { OS, EventingFields } from '../../../../types';
|
||||
import { clone } from '../../../../models/policy_details_config';
|
||||
|
||||
export const EventingCheckbox: React.FC<{
|
||||
id: string;
|
||||
name: string;
|
||||
os: OS;
|
||||
protectionField: EventingFields;
|
||||
}> = React.memo(({ id, name, os, protectionField }) => {
|
||||
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
|
||||
const eventing = usePolicyDetailsSelector(windowsEventing);
|
||||
const dispatch = useDispatch<(action: PolicyDetailsAction) => void>();
|
||||
|
||||
const handleRadioChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (policyDetailsConfig) {
|
||||
const newPayload = clone(policyDetailsConfig);
|
||||
newPayload[os].eventing[protectionField] = event.target.checked;
|
||||
|
||||
dispatch({
|
||||
type: 'userChangedPolicyConfig',
|
||||
payload: { policyConfig: newPayload },
|
||||
});
|
||||
}
|
||||
},
|
||||
[dispatch, os, policyDetailsConfig, protectionField]
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiCheckbox
|
||||
id={id}
|
||||
label={name}
|
||||
checked={eventing && eventing[protectionField]}
|
||||
onChange={handleRadioChange}
|
||||
/>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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, { useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EventingCheckbox } from './checkbox';
|
||||
import { OS, EventingFields } from '../../../../types';
|
||||
import { usePolicyDetailsSelector } from '../../policy_hooks';
|
||||
import {
|
||||
selectedWindowsEventing,
|
||||
totalWindowsEventing,
|
||||
} from '../../../../store/policy_details/selectors';
|
||||
import { ConfigForm } from '../config_form';
|
||||
|
||||
export const WindowsEventing = React.memo(() => {
|
||||
const checkboxes = useMemo(
|
||||
() => [
|
||||
{
|
||||
name: i18n.translate('xpack.endpoint.policyDetailsConfig.eventingProcess', {
|
||||
defaultMessage: 'Process',
|
||||
}),
|
||||
os: OS.windows,
|
||||
protectionField: EventingFields.process,
|
||||
},
|
||||
{
|
||||
name: i18n.translate('xpack.endpoint.policyDetailsConfig.eventingNetwork', {
|
||||
defaultMessage: 'Network',
|
||||
}),
|
||||
os: OS.windows,
|
||||
protectionField: EventingFields.network,
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const renderCheckboxes = () => {
|
||||
return checkboxes.map((item, index) => {
|
||||
return (
|
||||
<EventingCheckbox
|
||||
id={`eventing${item.name}`}
|
||||
name={item.name}
|
||||
key={index}
|
||||
os={item.os}
|
||||
protectionField={item.protectionField}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const selected = usePolicyDetailsSelector(selectedWindowsEventing);
|
||||
const total = usePolicyDetailsSelector(totalWindowsEventing);
|
||||
|
||||
return (
|
||||
<ConfigForm
|
||||
type={i18n.translate('xpack.endpoint.policy.details.eventCollection', {
|
||||
defaultMessage: 'Event Collection',
|
||||
})}
|
||||
supportedOss={[
|
||||
i18n.translate('xpack.endpoint.policy.details.windows', { defaultMessage: 'Windows' }),
|
||||
]}
|
||||
id="windowsEventingForm"
|
||||
children={renderCheckboxes()}
|
||||
selectedEventing={selected}
|
||||
totalEventing={total}
|
||||
/>
|
||||
);
|
||||
});
|
|
@ -14,7 +14,6 @@ export default function({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./header_nav'));
|
||||
loadTestFile(require.resolve('./host_list'));
|
||||
loadTestFile(require.resolve('./policy_list'));
|
||||
loadTestFile(require.resolve('./policy_details'));
|
||||
loadTestFile(require.resolve('./alerts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const pageObjects = getPageObjects(['common', 'endpoint']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
// Skipped until we can figure out how to load data for Ingest
|
||||
describe.skip('Endpoint Policy Details', function() {
|
||||
this.tags(['ciGroup7']);
|
||||
|
||||
it('loads the Policy Details Page', async () => {
|
||||
await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/policy/123');
|
||||
await testSubjects.existOrFail('policyDetailsViewTitle');
|
||||
|
||||
const policyDetailsNotFoundTitle = await testSubjects.getVisibleText('policyDetailsName');
|
||||
expect(policyDetailsNotFoundTitle).to.equal('policy with some protections 123');
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue