Add support for max_primary_shard_docs to ILM (#137364) (#137521)

(cherry picked from commit 0f011b9423)

Co-authored-by: CJ Cenizal <cj.cenizal@elastic.co>
This commit is contained in:
Kibana Machine 2022-07-28 15:46:00 -04:00 committed by GitHub
parent dcc4ad744b
commit a0b2246b1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 192 additions and 67 deletions

View file

@ -36,11 +36,12 @@ describe('<EditPolicy /> hot phase validation', () => {
});
describe('rollover', () => {
test(`doesn't allow no max primary shard size, no max index size, no max age, no max docs`, async () => {
test(`doesn't allow no max primary shard size, no max primary docs, no max age, no max docs, no max index size`, async () => {
await actions.rollover.toggleDefault();
expect(actions.rollover.hasSettingRequiredCallout()).toBeFalsy();
await actions.rollover.setMaxPrimaryShardSize('');
await actions.rollover.setMaxPrimaryShardDocs('');
await actions.rollover.setMaxAge('');
await actions.rollover.setMaxDocs('');
await actions.rollover.setMaxSize('');
@ -50,94 +51,131 @@ describe('<EditPolicy /> hot phase validation', () => {
expect(actions.rollover.hasSettingRequiredCallout()).toBeTruthy();
});
test(`doesn't allow -1 for max primary shard size`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardSize('-1');
describe('max primary shard size', () => {
test(`doesn't allow -1`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardSize('-1');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardSize('0');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
});
test(`doesn't allow 0 for max primary shard size`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardSize('0');
describe('max primary docs size', () => {
test(`doesn't allow -1`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardDocs('-1');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardDocs('0');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow decimals`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxPrimaryShardDocs('5.5');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.integerRequired]);
});
});
test(`doesn't allow -1 for max size`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxSize('-1');
describe('max size', () => {
test(`doesn't allow -1`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxSize('-1');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxSize('0');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
});
test(`doesn't allow 0 for max size`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxSize('0');
describe('max age', () => {
test(`doesn't allow -1`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('-1');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('0');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow decimals`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('5.5');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.integerRequired]);
});
});
test(`doesn't allow -1 for max age`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('-1');
describe('max docs', () => {
test(`doesn't allow -1`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('-1');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0 for max age`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('0');
test(`doesn't allow 0`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('0');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow decimals for max age`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxAge('5.5');
test(`doesn't allow decimals`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('5.5');
actions.errors.waitForValidation();
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.integerRequired]);
});
test(`doesn't allow -1 for max docs`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('-1');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow 0 for max docs`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('0');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.numberGreatThan0Required]);
});
test(`doesn't allow decimals for max docs`, async () => {
await actions.rollover.toggleDefault();
await actions.rollover.setMaxDocs('5.5');
actions.errors.waitForValidation();
actions.errors.expectMessages([i18nTexts.editPolicy.errors.integerRequired]);
actions.errors.expectMessages([i18nTexts.editPolicy.errors.integerRequired]);
});
});
});

View file

@ -194,6 +194,7 @@ describe('<EditPolicy /> serialization', () => {
await actions.rollover.setMaxSize('123', 'mb');
await actions.rollover.setMaxDocs('123');
await actions.rollover.setMaxAge('123', 'h');
await actions.rollover.setMaxPrimaryShardDocs('123');
await actions.hot.toggleForceMerge();
await actions.hot.setForcemergeSegmentsCount('123');
await actions.hot.setBestCompression(true);
@ -215,6 +216,7 @@ describe('<EditPolicy /> serialization', () => {
rollover: {
max_age: '123h',
max_primary_shard_size: '50gb',
max_primary_shard_docs: 123,
max_docs: 123,
max_size: '123mb',
},

View file

@ -81,6 +81,7 @@ export const createRolloverActions = (testBed: TestBed) => {
toggle: createFormToggleAction(testBed, 'rolloverSwitch'),
toggleDefault: createFormToggleAction(testBed, 'useDefaultRolloverSwitch'),
setMaxPrimaryShardSize: createSetPrimaryShardSizeAction(testBed),
setMaxPrimaryShardDocs: createFormSetValueAction(testBed, 'hot-selectedMaxPrimaryShardDocs'),
setMaxDocs: createFormSetValueAction(testBed, 'hot-selectedMaxDocuments'),
setMaxAge: createSetMaxAgeAction(testBed),
setMaxSize: createSetMaxSizeAction(testBed),

View file

@ -80,6 +80,7 @@ export interface RolloverAction {
max_age?: string;
max_docs?: number;
max_primary_shard_size?: string;
max_primary_shard_docs?: number;
/**
* @deprecated This will be removed in versions 8+ of the stack
*/

View file

@ -14,6 +14,7 @@ export const isUsingDefaultRollover = (policy: SerializedPolicy): boolean => {
rollover &&
rollover.max_age === defaultRolloverAction.max_age &&
rollover.max_docs === defaultRolloverAction.max_docs &&
rollover.max_primary_shard_size === defaultRolloverAction.max_primary_shard_size
rollover.max_primary_shard_size === defaultRolloverAction.max_primary_shard_size &&
rollover.max_primary_shard_docs === defaultRolloverAction.max_primary_shard_docs
);
};

View file

@ -7,6 +7,8 @@
export { MaxPrimaryShardSizeField } from './max_primary_shard_size_field';
export { MaxPrimaryShardDocsField } from './max_primary_shard_docs_field';
export { MaxAgeField } from './max_age_field';
export { MaxDocumentCountField } from './max_document_count_field';

View file

@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { FunctionComponent } from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { NumericField } from '../../../../../../../shared_imports';
import { UseField } from '../../../../form';
import { ROLLOVER_FORM_PATHS } from '../../../../constants';
export const MaxPrimaryShardDocsField: FunctionComponent = () => {
return (
<EuiFlexGroup alignItems="flexStart" gutterSize="s">
<EuiFlexItem style={{ maxWidth: 400 }}>
<UseField
path={ROLLOVER_FORM_PATHS.maxPrimaryShardDocs}
component={NumericField}
componentProps={{
euiFieldProps: {
'data-test-subj': 'hot-selectedMaxPrimaryShardDocs',
min: 1,
},
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
};

View file

@ -35,6 +35,7 @@ import { Phase } from '../phase';
import { useRolloverValueRequiredValidation } from './use_rollover_value_required_validation';
import {
MaxPrimaryShardSizeField,
MaxPrimaryShardDocsField,
MaxAgeField,
MaxDocumentCountField,
MaxIndexSizeField,
@ -151,6 +152,9 @@ export const HotPhase: FunctionComponent = () => {
<MaxPrimaryShardSizeField />
<EuiSpacer />
<MaxPrimaryShardDocsField />
<EuiSpacer />
<MaxAgeField />
<EuiSpacer />

View file

@ -20,6 +20,7 @@ export const ROLLOVER_FORM_PATHS = {
maxAge: 'phases.hot.actions.rollover.max_age',
maxSize: 'phases.hot.actions.rollover.max_size',
maxPrimaryShardSize: 'phases.hot.actions.rollover.max_primary_shard_size',
maxPrimaryShardDocs: 'phases.hot.actions.rollover.max_primary_shard_docs',
};
/**

View file

@ -42,6 +42,7 @@ const originalPolicy: SerializedPolicy = {
rollover: {
max_age: '1d',
max_primary_shard_size: '33gb',
max_primary_shard_docs: 12,
max_docs: 1000,
max_size: '10gb',
},
@ -372,11 +373,15 @@ describe('deserializer and serializer', () => {
formInternal.phases.hot!.actions.rollover!.max_size = '';
formInternal.phases.hot!.actions.rollover!.max_age = '';
formInternal.phases.hot!.actions.rollover!.max_docs = '' as any;
formInternal.phases.hot!.actions.rollover!.max_primary_shard_size = '';
formInternal.phases.hot!.actions.rollover!.max_primary_shard_docs = '' as any;
const result = serializer(formInternal);
expect(result.phases.hot!.actions.rollover!.max_size).toBeUndefined();
expect(result.phases.hot!.actions.rollover!.max_age).toBeUndefined();
expect(result.phases.hot!.actions.rollover!.max_docs).toBeUndefined();
expect(result.phases.hot!.actions.rollover!.max_size).toBeUndefined();
expect(result.phases.hot!.actions.rollover!.max_primary_shard_size).toBeUndefined();
expect(result.phases.hot!.actions.rollover!.max_primary_shard_docs).toBeUndefined();
});
});

View file

@ -365,6 +365,22 @@ export const getSchema = (isCloudEnabled: boolean): FormSchema => ({
],
fieldsToValidateOnChange: rolloverFormPaths,
},
max_primary_shard_docs: {
label: i18nTexts.editPolicy.maxPrimaryShardDocsLabel,
validations: [
{
validator: rolloverThresholdsValidator,
},
{
validator: ifExistsNumberGreaterThanZero,
},
{
validator: integerValidator,
},
],
serializer: serializers.stringToNumber,
fieldsToValidateOnChange: rolloverFormPaths,
},
max_size: {
label: i18n.translate('xpack.indexLifecycleMgmt.hotPhase.maximumIndexSizeLabel', {
defaultMessage: 'Maximum index size',

View file

@ -76,6 +76,13 @@ export const createSerializer =
delete hotPhaseActions.rollover.max_primary_shard_size;
}
if (
typeof updatedPolicy.phases.hot!.actions.rollover?.max_primary_shard_docs !==
'number'
) {
delete hotPhaseActions.rollover.max_primary_shard_docs;
}
if (updatedPolicy.phases.hot!.actions.rollover?.max_size) {
hotPhaseActions.rollover.max_size = `${hotPhaseActions.rollover.max_size}${_meta.hot?.customRollover.maxStorageSizeUnit}`;
} else {

View file

@ -86,6 +86,9 @@ export const rolloverThresholdsValidator: ValidationFunc = ({ form, path }) => {
case ROLLOVER_FORM_PATHS.maxPrimaryShardSize:
errorToReturn.message = i18nTexts.editPolicy.errors.maximumPrimaryShardSizeRequiredMessage;
break;
case ROLLOVER_FORM_PATHS.maxPrimaryShardDocs:
errorToReturn.message = i18nTexts.editPolicy.errors.maximumPrimaryShardDocsRequiredMessage;
break;
default:
errorToReturn.message = i18nTexts.editPolicy.errors.maximumSizeRequiredMessage;
}

View file

@ -107,6 +107,12 @@ export const i18nTexts = {
defaultMessage: 'Maximum primary shard size',
}
),
maxPrimaryShardDocsLabel: i18n.translate(
'xpack.indexLifecycleMgmt.hotPhase.maximumPrimaryShardDocsLabel',
{
defaultMessage: 'Maximum docs in the primary shard',
}
),
maxPrimaryShardSizeUnitsLabel: i18n.translate(
'xpack.indexLifecycleMgmt.editPolicy.maximumPrimaryShardSizeAriaLabel',
{
@ -156,6 +162,12 @@ export const i18nTexts = {
defaultMessage: 'A maximum primary shard size is required',
}
),
maximumPrimaryShardDocsRequiredMessage: i18n.translate(
'xpack.indexLifecycleMgmt.editPolicy.errors.maximumPrimaryShardDocsMissingError',
{
defaultMessage: 'Maximum documents in the primary shard is required',
}
),
rollOverConfigurationCallout: {
title: i18n.translate(
'xpack.indexLifecycleMgmt.editPolicy.errors.rolloverConfigurationError.title',