From 286f4648f9018f49905c14b44bf1aa7728ca897d Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 14 Dec 2020 21:10:00 +0100 Subject: [PATCH] [ILM] Rollover field redesign (#85579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * implement form-level support for using default rollover action * slight update to copy * added use default rollover switch and tooltips for detailed copy * fix legacy integration tests and do not unmount rollover field!! * remove unused import * fix client integration tests * updated form to use new isUsingRollover check * fix serialization of rollover * Update x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx Co-authored-by: Adam Locke * Update x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx Co-authored-by: Adam Locke * Update x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx Co-authored-by: Adam Locke Co-authored-by: Yulia Čech <6585477+yuliacech@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Adam Locke --- .../edit_policy/edit_policy.helpers.tsx | 3 + .../edit_policy/edit_policy.test.ts | 20 +- .../__jest__/components/edit_policy.test.tsx | 12 + .../common/types/policies.ts | 12 +- .../public/application/constants/policy.ts | 17 +- .../public/application/lib/index.ts | 2 + .../public/application/lib/rollover.ts | 18 + .../described_form_row/described_form_row.tsx | 4 +- .../components/phases/hot_phase/hot_phase.tsx | 325 ++++++++++-------- .../components/phases/shared_fields/index.ts | 2 - .../min_age_input_field.tsx | 13 +- .../searchable_snapshot_field.tsx | 9 +- .../phases/warm_phase/warm_phase.tsx | 10 +- .../sections/edit_policy/constants.ts | 2 + .../form/configuration_issues_context.tsx | 17 +- .../sections/edit_policy/form/deserializer.ts | 3 +- .../sections/edit_policy/form/schema.ts | 6 + .../edit_policy/form/serializer/serializer.ts | 8 +- .../application/sections/edit_policy/types.ts | 1 + 19 files changed, 300 insertions(+), 184 deletions(-) create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/lib/rollover.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx index abb33d109742c..7206fbfd547d4 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx @@ -111,6 +111,8 @@ export const setup = async (arg?: { appServicesContext: Partial { @@ -239,6 +241,7 @@ export const setup = async (arg?: { appServicesContext: Partial', () => { test('setting all values', async () => { const { actions } = testBed; + await actions.hot.toggleDefaultRollover(false); await actions.hot.setMaxSize('123', 'mb'); await actions.hot.setMaxDocs('123'); await actions.hot.setMaxAge('123', 'h'); @@ -177,7 +178,8 @@ describe('', () => { test('disabling rollover', async () => { const { actions } = testBed; - await actions.hot.toggleRollover(true); + await actions.hot.toggleDefaultRollover(false); + await actions.hot.toggleRollover(false); await actions.savePolicy(); const latestRequest = server.requests[server.requests.length - 1]; const policy = JSON.parse(JSON.parse(latestRequest.requestBody).body); @@ -212,6 +214,17 @@ describe('', () => { expect(actions.cold.searchableSnapshotsExists()).toBeTruthy(); expect(actions.cold.freezeExists()).toBeFalsy(); }); + + test('disabling rollover toggle, but enabling default rollover', async () => { + const { actions } = testBed; + await actions.hot.toggleDefaultRollover(false); + await actions.hot.toggleRollover(false); + await actions.hot.toggleDefaultRollover(true); + + expect(actions.hot.forceMergeFieldExists()).toBeTruthy(); + expect(actions.hot.shrinkExists()).toBeTruthy(); + expect(actions.hot.searchableSnapshotsExists()).toBeTruthy(); + }); }); }); @@ -766,7 +779,7 @@ describe('', () => { await act(async () => { testBed = await setup({ appServicesContext: { - license: licensingMock.createLicense({ license: { type: 'basic' } }), + license: licensingMock.createLicense({ license: { type: 'enterprise' } }), }, }); }); @@ -776,11 +789,12 @@ describe('', () => { }); test('hiding and disabling searchable snapshot field', async () => { const { actions } = testBed; + await actions.hot.toggleDefaultRollover(false); await actions.hot.toggleRollover(false); await actions.cold.enable(true); expect(actions.hot.searchableSnapshotsExists()).toBeFalsy(); - expect(actions.cold.searchableSnapshotDisabledDueToLicense()).toBeTruthy(); + expect(actions.cold.searchableSnapshotDisabledDueToRollover()).toBeTruthy(); }); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx index d7d38e3b92516..c54ccb9f85edf 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx @@ -113,7 +113,14 @@ const expectedErrorMessages = (rendered: ReactWrapper, expectedMessages: string[ expect(foundErrorMessage).toBe(true); }); }; +const noDefaultRollover = async (rendered: ReactWrapper) => { + await act(async () => { + findTestSubject(rendered, 'useDefaultRolloverSwitch').simulate('click'); + }); + rendered.update(); +}; const noRollover = async (rendered: ReactWrapper) => { + await noDefaultRollover(rendered); await act(async () => { findTestSubject(rendered, 'rolloverSwitch').simulate('click'); }); @@ -326,6 +333,7 @@ describe('edit policy', () => { describe('hot phase', () => { test('should show errors when trying to save with no max size, no max age and no max docs', async () => { const rendered = mountWithIntl(component); + await noDefaultRollover(rendered); expect(findTestSubject(rendered, 'rolloverSettingsRequired').exists()).toBeFalsy(); await setPolicyName(rendered, 'mypolicy'); const maxSizeInput = findTestSubject(rendered, 'hot-selectedMaxSizeStored'); @@ -349,6 +357,7 @@ describe('edit policy', () => { test('should show number above 0 required error when trying to save with -1 for max size', async () => { const rendered = mountWithIntl(component); await setPolicyName(rendered, 'mypolicy'); + await noDefaultRollover(rendered); const maxSizeInput = findTestSubject(rendered, 'hot-selectedMaxSizeStored'); await act(async () => { maxSizeInput.simulate('change', { target: { value: '-1' } }); @@ -360,6 +369,7 @@ describe('edit policy', () => { test('should show number above 0 required error when trying to save with 0 for max size', async () => { const rendered = mountWithIntl(component); await setPolicyName(rendered, 'mypolicy'); + await noDefaultRollover(rendered); const maxSizeInput = findTestSubject(rendered, 'hot-selectedMaxSizeStored'); await act(async () => { maxSizeInput.simulate('change', { target: { value: '-1' } }); @@ -370,6 +380,7 @@ describe('edit policy', () => { test('should show number above 0 required error when trying to save with -1 for max age', async () => { const rendered = mountWithIntl(component); await setPolicyName(rendered, 'mypolicy'); + await noDefaultRollover(rendered); const maxAgeInput = findTestSubject(rendered, 'hot-selectedMaxAge'); await act(async () => { maxAgeInput.simulate('change', { target: { value: '-1' } }); @@ -380,6 +391,7 @@ describe('edit policy', () => { test('should show number above 0 required error when trying to save with 0 for max age', async () => { const rendered = mountWithIntl(component); await setPolicyName(rendered, 'mypolicy'); + await noDefaultRollover(rendered); const maxAgeInput = findTestSubject(rendered, 'hot-selectedMaxAge'); await act(async () => { maxAgeInput.simulate('change', { target: { value: '0' } }); diff --git a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts index 4f7782a51b278..58468f06e3b2d 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts @@ -57,13 +57,15 @@ export interface SearchableSnapshotAction { force_merge_index?: boolean; } +export interface RolloverAction { + max_size?: string; + max_age?: string; + max_docs?: number; +} + export interface SerializedHotPhase extends SerializedPhase { actions: { - rollover?: { - max_size?: string; - max_age?: string; - max_docs?: number; - }; + rollover?: RolloverAction; forcemerge?: ForcemergeAction; readonly?: {}; shrink?: ShrinkAction; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts index 23d7387aa7076..a892a7a031a87 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts @@ -4,21 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SerializedPhase, DeletePhase, SerializedPolicy } from '../../../common/types'; +import { + SerializedPhase, + DeletePhase, + SerializedPolicy, + RolloverAction, +} from '../../../common/types'; export const defaultSetPriority: string = '100'; export const defaultPhaseIndexPriority: string = '50'; +export const defaultRolloverAction: RolloverAction = { + max_age: '30d', + max_size: '50gb', +}; + export const defaultPolicy: SerializedPolicy = { name: '', phases: { hot: { actions: { - rollover: { - max_age: '30d', - max_size: '50gb', - }, + rollover: defaultRolloverAction, }, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/index.ts index 1dabae1a0f0c4..274905342f815 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/lib/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/index.ts @@ -5,3 +5,5 @@ */ export * from './data_tiers'; + +export * from './rollover'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/rollover.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/rollover.ts new file mode 100644 index 0000000000000..1b85303c4bce0 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/rollover.ts @@ -0,0 +1,18 @@ +/* + * 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 { SerializedPolicy } from '../../../common/types'; +import { defaultRolloverAction } from '../constants'; + +export const isUsingDefaultRollover = (policy: SerializedPolicy): boolean => { + const rollover = policy?.phases?.hot?.actions?.rollover; + return Boolean( + rollover && + rollover.max_age === defaultRolloverAction.max_age && + rollover.max_docs === defaultRolloverAction.max_docs && + rollover.max_size === defaultRolloverAction.max_size + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx index 98c63437659fd..161729ae48057 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/described_form_row/described_form_row.tsx @@ -55,7 +55,9 @@ export const DescribedFormRow: FunctionComponent = ({ const [uncontrolledIsContentVisible, setUncontrolledIsContentVisible] = useState( () => switchProps?.initialValue ?? false ); - const isContentVisible = Boolean(switchProps?.checked ?? uncontrolledIsContentVisible); + const isContentVisible = Boolean( + switchProps === undefined || (switchProps?.checked ?? uncontrolledIsContentVisible) + ); const renderToggle = () => { if (!switchProps) { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx index 77f36a237c0c4..ae8fecd1a1958 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/hot_phase/hot_phase.tsx @@ -16,6 +16,8 @@ import { EuiCallOut, EuiAccordion, EuiTextColor, + EuiSwitch, + EuiIconTip, } from '@elastic/eui'; import { Phases } from '../../../../../../../common/types'; @@ -24,19 +26,18 @@ import { useFormData, UseField, SelectField, NumericField } from '../../../../.. import { i18nTexts } from '../../../i18n_texts'; -import { ROLLOVER_EMPTY_VALIDATION } from '../../../form'; +import { ROLLOVER_EMPTY_VALIDATION, useConfigurationIssues } from '../../../form'; import { useEditPolicyContext } from '../../../edit_policy_context'; -import { ROLLOVER_FORM_PATHS } from '../../../constants'; +import { ROLLOVER_FORM_PATHS, isUsingDefaultRolloverPath } from '../../../constants'; -import { LearnMoreLink, ActiveBadge, ToggleFieldWithDescribedFormRow } from '../../'; +import { LearnMoreLink, ActiveBadge, DescribedFormRow } from '../../'; import { ForcemergeField, SetPriorityInputField, SearchableSnapshotField, - useRolloverPath, ReadonlyField, ShrinkField, } from '../shared_fields'; @@ -48,9 +49,10 @@ const hotProperty: keyof Phases = 'hot'; export const HotPhase: FunctionComponent = () => { const { license } = useEditPolicyContext(); const [formData] = useFormData({ - watch: useRolloverPath, + watch: isUsingDefaultRolloverPath, }); - const isRolloverEnabled = get(formData, useRolloverPath); + const { isUsingRollover } = useConfigurationIssues(); + const isUsingDefaultRollover = get(formData, isUsingDefaultRolloverPath); const [showEmptyRolloverFieldsError, setShowEmptyRolloverFieldsError] = useState(false); return ( @@ -89,7 +91,7 @@ export const HotPhase: FunctionComponent = () => { })} paddingSize="m" > - {i18n.translate('xpack.indexLifecycleMgmt.hotPhase.rolloverFieldTitle', { @@ -98,143 +100,192 @@ export const HotPhase: FunctionComponent = () => { } description={ - -

- {' '} - + +

+ {' '} + + } + docPath="indices-rollover-index.html" + /> +

+
+ + path={isUsingDefaultRolloverPath}> + {(field) => ( + <> + field.setValue(e.target.checked)} + data-test-subj="useDefaultRolloverSwitch" + /> +   + + } /> - } - docPath="indices-rollover-index.html" - /> -

- + + )} + + } - switchProps={{ - path: '_meta.hot.useRollover', - 'data-test-subj': 'rolloverSwitch', - }} fullWidth > - {isRolloverEnabled && ( - <> - - {showEmptyRolloverFieldsError && ( +
+ path="_meta.hot.useRollover"> + {(field) => ( <> - -
{i18nTexts.editPolicy.errors.rollOverConfigurationCallout.body}
-
- - - )} - - - - {(field) => { - const showErrorCallout = field.errors.some( - (e) => e.code === ROLLOVER_EMPTY_VALIDATION - ); - if (showErrorCallout !== showEmptyRolloverFieldsError) { - setShowEmptyRolloverFieldsError(showErrorCallout); - } - return ( - - ); - }} - - - - field.setValue(e.target.checked)} + data-test-subj="rolloverSwitch" /> - - - - - - - - - - - - + } /> - - - - - - - )} - - {isRolloverEnabled && ( + + )} + + {isUsingRollover && ( + <> + + {showEmptyRolloverFieldsError && ( + <> + +
{i18nTexts.editPolicy.errors.rollOverConfigurationCallout.body}
+
+ + + )} + + + + {(field) => { + const showErrorCallout = field.errors.some( + (e) => e.code === ROLLOVER_EMPTY_VALIDATION + ); + if (showErrorCallout !== showEmptyRolloverFieldsError) { + setShowEmptyRolloverFieldsError(showErrorCallout); + } + return ( + + ); + }} + + + + + + + + + + + + + + + + + + + + + + + )} +
+ + {isUsingRollover && ( <> {} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts index e56b0b21491f3..15167672265fd 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/index.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { useRolloverPath } from '../../../constants'; - export { DataTierAllocationField } from './data_tier_allocation_field'; export { ForcemergeField } from './forcemerge_field'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx index f37c387354418..59086ce572252 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/min_age_input_field/min_age_input_field.tsx @@ -4,21 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { FunctionComponent } from 'react'; -import { get } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { - useFormData, - UseField, - NumericField, - SelectField, -} from '../../../../../../../shared_imports'; +import { UseField, NumericField, SelectField } from '../../../../../../../shared_imports'; import { LearnMoreLink } from '../../../learn_more_link'; -import { useRolloverPath } from '../../../../constants'; +import { useConfigurationIssues } from '../../../../form'; import { getUnitsAriaLabelForPhase, getTimingLabelForPhase } from './util'; @@ -29,8 +23,7 @@ interface Props { } export const MinAgeInputField: FunctionComponent = ({ phase }): React.ReactElement => { - const [formData] = useFormData({ watch: useRolloverPath }); - const rolloverEnabled = get(formData, useRolloverPath); + const { isUsingRollover: rolloverEnabled } = useConfigurationIssues(); let daysOptionLabel; let hoursOptionLabel; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx index 2a55cee0794c5..3157c0a51accf 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx @@ -29,8 +29,6 @@ import { useConfigurationIssues } from '../../../../form'; import { i18nTexts } from '../../../../i18n_texts'; -import { useRolloverPath } from '../../../../constants'; - import { FieldLoadingError, DescribedFormRow, LearnMoreLink } from '../../../'; import { SearchableSnapshotDataProvider } from './searchable_snapshot_data_provider'; @@ -54,17 +52,16 @@ export const SearchableSnapshotField: FunctionComponent = ({ phase }) => services: { cloud }, } = useKibana(); const { getUrlForApp, policy, license } = useEditPolicyContext(); - const { isUsingSearchableSnapshotInHotPhase } = useConfigurationIssues(); + const { isUsingSearchableSnapshotInHotPhase, isUsingRollover } = useConfigurationIssues(); const searchableSnapshotPath = `phases.${phase}.actions.searchable_snapshot.snapshot_repository`; - const [formData] = useFormData({ watch: [searchableSnapshotPath, useRolloverPath] }); - const isRolloverEnabled = get(formData, useRolloverPath); + const [formData] = useFormData({ watch: searchableSnapshotPath }); const searchableSnapshotRepo = get(formData, searchableSnapshotPath); const isDisabledDueToLicense = !license.canUseSearchableSnapshot(); const isDisabledInColdDueToHotPhase = phase === 'cold' && isUsingSearchableSnapshotInHotPhase; - const isDisabledInColdDueToRollover = phase === 'cold' && !isRolloverEnabled; + const isDisabledInColdDueToRollover = phase === 'cold' && !isUsingRollover; const isDisabled = isDisabledDueToLicense || isDisabledInColdDueToHotPhase || isDisabledInColdDueToRollover; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx index 36a39eb7c110f..77078e94d7e98 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx @@ -21,7 +21,6 @@ import { useConfigurationIssues } from '../../../form'; import { ActiveBadge, DescribedFormRow } from '../../'; import { - useRolloverPath, MinAgeInputField, ForcemergeField, SetPriorityInputField, @@ -47,13 +46,12 @@ const formFieldPaths = { export const WarmPhase: FunctionComponent = () => { const { policy } = useEditPolicyContext(); - const { isUsingSearchableSnapshotInHotPhase } = useConfigurationIssues(); + const { isUsingSearchableSnapshotInHotPhase, isUsingRollover } = useConfigurationIssues(); const [formData] = useFormData({ - watch: [useRolloverPath, formFieldPaths.enabled, formFieldPaths.warmPhaseOnRollover], + watch: [formFieldPaths.enabled, formFieldPaths.warmPhaseOnRollover], }); const enabled = get(formData, formFieldPaths.enabled); - const hotPhaseRolloverEnabled = get(formData, useRolloverPath); const warmPhaseOnRollover = get(formData, formFieldPaths.warmPhaseOnRollover); return ( @@ -99,7 +97,7 @@ export const WarmPhase: FunctionComponent = () => { <> {enabled && ( <> - {hotPhaseRolloverEnabled && ( + {isUsingRollover && ( { }} /> )} - {(!warmPhaseOnRollover || !hotPhaseRolloverEnabled) && ( + {(!warmPhaseOnRollover || !isUsingRollover) && ( <> diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/constants.ts index a5d5f1c62847c..48ed38fc8a0d7 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/constants.ts @@ -6,6 +6,8 @@ export const useRolloverPath = '_meta.hot.useRollover'; +export const isUsingDefaultRolloverPath = '_meta.hot.isUsingDefaultRollover'; + /** * These strings describe the path to their respective values in the serialized * ILM form. diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_issues_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_issues_context.tsx index c31eb5bdaa329..3a66abebccc1a 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_issues_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/configuration_issues_context.tsx @@ -6,10 +6,17 @@ import { get } from 'lodash'; import React, { FunctionComponent, createContext, useContext } from 'react'; + import { useFormData } from '../../../../shared_imports'; +import { isUsingDefaultRolloverPath, useRolloverPath } from '../constants'; + export interface ConfigurationIssues { - isUsingForceMergeInHotPhase: boolean; + /** + * Whether the serialized policy will use rollover. This blocks certain actions in + * the form such as hot phase (forcemerge, shrink) and cold phase (searchable snapshot). + */ + isUsingRollover: boolean; /** * If this value is true, phases after hot cannot set shrink, forcemerge, freeze, or * searchable_snapshot actions. @@ -24,18 +31,18 @@ const ConfigurationIssuesContext = createContext(null as an const pathToHotPhaseSearchableSnapshot = 'phases.hot.actions.searchable_snapshot.snapshot_repository'; -const pathToHotForceMerge = 'phases.hot.actions.forcemerge.max_num_segments'; - export const ConfigurationIssuesProvider: FunctionComponent = ({ children }) => { const [formData] = useFormData({ - watch: [pathToHotPhaseSearchableSnapshot, pathToHotForceMerge], + watch: [pathToHotPhaseSearchableSnapshot, useRolloverPath, isUsingDefaultRolloverPath], }); + const isUsingDefaultRollover = get(formData, isUsingDefaultRolloverPath); + const rolloverSwitchEnabled = get(formData, useRolloverPath); return ( {children} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts index 0a85a376a9ab4..160c3987f8898 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts @@ -10,7 +10,7 @@ import { SerializedPolicy } from '../../../../../common/types'; import { splitSizeAndUnits } from '../../../lib/policies'; -import { determineDataTierAllocationType } from '../../../lib'; +import { determineDataTierAllocationType, isUsingDefaultRollover } from '../../../lib'; import { FormInternal } from '../types'; @@ -22,6 +22,7 @@ export const deserializer = (policy: SerializedPolicy): FormInternal => { const _meta: FormInternal['_meta'] = { hot: { useRollover: Boolean(hot?.actions?.rollover), + isUsingDefaultRollover: isUsingDefaultRollover(policy), bestCompression: hot?.actions?.forcemerge?.index_codec === 'best_compression', readonlyEnabled: Boolean(hot?.actions?.readonly), }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts index a292a888e78c4..ae2432971059c 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/schema.ts @@ -38,6 +38,12 @@ export const schema: FormSchema = { defaultMessage: 'Enable rollover', }), }, + isUsingDefaultRollover: { + defaultValue: true, + label: i18n.translate('xpack.indexLifecycleMgmt.hotPhase.isUsingDefaultRollover', { + defaultMessage: 'Use recommended defaults', + }), + }, maxStorageSizeUnit: { defaultValue: 'gb', }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts index 75935f149534e..2a7689b42554e 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts @@ -6,11 +6,11 @@ import { produce } from 'immer'; -import { merge } from 'lodash'; +import { merge, cloneDeep } from 'lodash'; import { SerializedPolicy } from '../../../../../../common/types'; -import { defaultPolicy } from '../../../../constants'; +import { defaultPolicy, defaultRolloverAction } from '../../../../constants'; import { FormInternal } from '../../types'; @@ -42,7 +42,9 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( if (draft.phases.hot?.actions) { const hotPhaseActions = draft.phases.hot.actions; - if (hotPhaseActions.rollover && _meta.hot.useRollover) { + if (_meta.hot.isUsingDefaultRollover) { + hotPhaseActions.rollover = cloneDeep(defaultRolloverAction); + } else if (hotPhaseActions.rollover && _meta.hot.useRollover) { if (updatedPolicy.phases.hot!.actions.rollover?.max_age) { hotPhaseActions.rollover.max_age = `${hotPhaseActions.rollover.max_age}${_meta.hot.maxAgeUnit}`; } else { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts index f04acea0bbf0a..4dfd7503b9973 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts @@ -23,6 +23,7 @@ export interface ForcemergeFields { interface HotPhaseMetaFields extends ForcemergeFields { useRollover: boolean; + isUsingDefaultRollover: boolean; maxStorageSizeUnit?: string; maxAgeUnit?: string; readonlyEnabled: boolean;