[Snapshot + Restore] Add callout when restoring snapshot (#95104)
This commit is contained in:
parent
fad3b74f2f
commit
43e3d558fd
|
@ -284,6 +284,7 @@ export class DocLinksService {
|
||||||
registerSourceOnly: `${ELASTICSEARCH_DOCS}snapshots-register-repository.html#snapshots-source-only-repository`,
|
registerSourceOnly: `${ELASTICSEARCH_DOCS}snapshots-register-repository.html#snapshots-source-only-repository`,
|
||||||
registerUrl: `${ELASTICSEARCH_DOCS}snapshots-register-repository.html#snapshots-read-only-repository`,
|
registerUrl: `${ELASTICSEARCH_DOCS}snapshots-register-repository.html#snapshots-read-only-repository`,
|
||||||
restoreSnapshot: `${ELASTICSEARCH_DOCS}snapshots-restore-snapshot.html`,
|
restoreSnapshot: `${ELASTICSEARCH_DOCS}snapshots-restore-snapshot.html`,
|
||||||
|
restoreSnapshotApi: `${ELASTICSEARCH_DOCS}restore-snapshot-api.html#restore-snapshot-api-request-body`,
|
||||||
},
|
},
|
||||||
ingest: {
|
ingest: {
|
||||||
pipelines: `${ELASTICSEARCH_DOCS}ingest.html`,
|
pipelines: `${ELASTICSEARCH_DOCS}ingest.html`,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
|
||||||
import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest';
|
import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest';
|
||||||
import { RestoreSnapshot } from '../../../public/application/sections/restore_snapshot';
|
import { RestoreSnapshot } from '../../../public/application/sections/restore_snapshot';
|
||||||
|
@ -23,11 +24,19 @@ const initTestBed = registerTestBed<RestoreSnapshotFormTestSubject>(
|
||||||
);
|
);
|
||||||
|
|
||||||
const setupActions = (testBed: TestBed<RestoreSnapshotFormTestSubject>) => {
|
const setupActions = (testBed: TestBed<RestoreSnapshotFormTestSubject>) => {
|
||||||
const { find } = testBed;
|
const { find, component, form } = testBed;
|
||||||
return {
|
return {
|
||||||
findDataStreamCallout() {
|
findDataStreamCallout() {
|
||||||
return find('dataStreamWarningCallOut');
|
return find('dataStreamWarningCallOut');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleGlobalState() {
|
||||||
|
act(() => {
|
||||||
|
form.toggleEuiSwitch('includeGlobalStateSwitch');
|
||||||
|
});
|
||||||
|
|
||||||
|
component.update();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,4 +57,6 @@ export const setup = async (): Promise<RestoreSnapshotTestBed> => {
|
||||||
|
|
||||||
export type RestoreSnapshotFormTestSubject =
|
export type RestoreSnapshotFormTestSubject =
|
||||||
| 'snapshotRestoreStepLogistics'
|
| 'snapshotRestoreStepLogistics'
|
||||||
|
| 'includeGlobalStateSwitch'
|
||||||
|
| 'systemIndicesInfoCallOut'
|
||||||
| 'dataStreamWarningCallOut';
|
| 'dataStreamWarningCallOut';
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
|
||||||
import { nextTick, pageHelpers, setupEnvironment } from './helpers';
|
import { pageHelpers, setupEnvironment } from './helpers';
|
||||||
import { RestoreSnapshotTestBed } from './helpers/restore_snapshot.helpers';
|
import { RestoreSnapshotTestBed } from './helpers/restore_snapshot.helpers';
|
||||||
import * as fixtures from '../../test/fixtures';
|
import * as fixtures from '../../test/fixtures';
|
||||||
|
|
||||||
|
@ -20,11 +21,15 @@ describe('<RestoreSnapshot />', () => {
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
server.restore();
|
server.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with data streams', () => {
|
describe('with data streams', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setGetSnapshotResponse(fixtures.getSnapshot());
|
httpRequestsMockHelpers.setGetSnapshotResponse(fixtures.getSnapshot());
|
||||||
testBed = await setup();
|
|
||||||
await nextTick();
|
await act(async () => {
|
||||||
|
testBed = await setup();
|
||||||
|
});
|
||||||
|
|
||||||
testBed.component.update();
|
testBed.component.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,8 +42,10 @@ describe('<RestoreSnapshot />', () => {
|
||||||
describe('without data streams', () => {
|
describe('without data streams', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
httpRequestsMockHelpers.setGetSnapshotResponse(fixtures.getSnapshot({ totalDataStreams: 0 }));
|
httpRequestsMockHelpers.setGetSnapshotResponse(fixtures.getSnapshot({ totalDataStreams: 0 }));
|
||||||
testBed = await setup();
|
await act(async () => {
|
||||||
await nextTick();
|
testBed = await setup();
|
||||||
|
});
|
||||||
|
|
||||||
testBed.component.update();
|
testBed.component.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,4 +54,25 @@ describe('<RestoreSnapshot />', () => {
|
||||||
expect(exists('dataStreamWarningCallOut')).toBe(false);
|
expect(exists('dataStreamWarningCallOut')).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('global state', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
httpRequestsMockHelpers.setGetSnapshotResponse(fixtures.getSnapshot());
|
||||||
|
await act(async () => {
|
||||||
|
testBed = await setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
testBed.component.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows an info callout when include_global_state is enabled', () => {
|
||||||
|
const { exists, actions } = testBed;
|
||||||
|
|
||||||
|
expect(exists('systemIndicesInfoCallOut')).toBe(false);
|
||||||
|
|
||||||
|
actions.toggleGlobalState();
|
||||||
|
|
||||||
|
expect(exists('systemIndicesInfoCallOut')).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -142,7 +142,7 @@ export const PolicyStepSettings: React.FunctionComponent<StepProps> = ({
|
||||||
description={
|
description={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription"
|
id="xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription"
|
||||||
defaultMessage="Stores the global cluster state as part of the snapshot."
|
defaultMessage="Stores the global cluster state and system indices as part of the snapshot."
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
|
@ -112,7 +112,8 @@ export const RestoreSnapshotForm: React.FunctionComponent<Props> = ({
|
||||||
errors={validation.errors}
|
errors={validation.errors}
|
||||||
updateCurrentStep={updateCurrentStep}
|
updateCurrentStep={updateCurrentStep}
|
||||||
/>
|
/>
|
||||||
<EuiSpacer size="l" />
|
|
||||||
|
<EuiSpacer size="xl" />
|
||||||
|
|
||||||
{saveError ? (
|
{saveError ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import React, { Fragment, useState } from 'react';
|
import React, { Fragment, useState } from 'react';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
import semverGt from 'semver/functions/gt';
|
||||||
import {
|
import {
|
||||||
EuiButtonEmpty,
|
EuiButtonEmpty,
|
||||||
EuiDescribedFormGroup,
|
EuiDescribedFormGroup,
|
||||||
|
@ -38,6 +39,8 @@ import { DataStreamsGlobalStateCallOut } from './data_streams_global_state_call_
|
||||||
|
|
||||||
import { DataStreamsAndIndicesListHelpText } from './data_streams_and_indices_list_help_text';
|
import { DataStreamsAndIndicesListHelpText } from './data_streams_and_indices_list_help_text';
|
||||||
|
|
||||||
|
import { SystemIndicesOverwrittenCallOut } from './system_indices_overwritten_callout';
|
||||||
|
|
||||||
export const RestoreSnapshotStepLogistics: React.FunctionComponent<StepProps> = ({
|
export const RestoreSnapshotStepLogistics: React.FunctionComponent<StepProps> = ({
|
||||||
snapshotDetails,
|
snapshotDetails,
|
||||||
restoreSettings,
|
restoreSettings,
|
||||||
|
@ -50,6 +53,7 @@ export const RestoreSnapshotStepLogistics: React.FunctionComponent<StepProps> =
|
||||||
indices: unfilteredSnapshotIndices,
|
indices: unfilteredSnapshotIndices,
|
||||||
dataStreams: snapshotDataStreams = [],
|
dataStreams: snapshotDataStreams = [],
|
||||||
includeGlobalState: snapshotIncludeGlobalState,
|
includeGlobalState: snapshotIncludeGlobalState,
|
||||||
|
version,
|
||||||
} = snapshotDetails;
|
} = snapshotDetails;
|
||||||
|
|
||||||
const snapshotIndices = unfilteredSnapshotIndices.filter(
|
const snapshotIndices = unfilteredSnapshotIndices.filter(
|
||||||
|
@ -564,11 +568,34 @@ export const RestoreSnapshotStepLogistics: React.FunctionComponent<StepProps> =
|
||||||
</EuiTitle>
|
</EuiTitle>
|
||||||
}
|
}
|
||||||
description={
|
description={
|
||||||
<FormattedMessage
|
<>
|
||||||
id="xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription"
|
<FormattedMessage
|
||||||
defaultMessage="Restores templates that don’t currently exist in the cluster and overrides
|
id="xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription"
|
||||||
templates with the same name. Also restores persistent settings."
|
defaultMessage="Restores templates that don’t currently exist in the cluster and overrides
|
||||||
/>
|
templates with the same name. Also restores persistent settings and all system indices. {learnMoreLink}"
|
||||||
|
values={{
|
||||||
|
learnMoreLink: (
|
||||||
|
<EuiLink target="_blank" href={docLinks.links.snapshotRestore.restoreSnapshotApi}>
|
||||||
|
{i18n.translate(
|
||||||
|
'xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDocLink',
|
||||||
|
{ defaultMessage: 'Learn more.' }
|
||||||
|
)}
|
||||||
|
</EuiLink>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Only display callout if include_global_state is enabled and the snapshot was created by ES 7.12+
|
||||||
|
* Note: Once we support features states in the UI, we will also need to add a check here for that
|
||||||
|
* See https://github.com/elastic/kibana/issues/95128 more details
|
||||||
|
*/}
|
||||||
|
{includeGlobalState && semverGt(version, '7.12.0') && (
|
||||||
|
<>
|
||||||
|
<EuiSpacer size="s" />
|
||||||
|
<SystemIndicesOverwrittenCallOut />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
|
@ -594,6 +621,7 @@ export const RestoreSnapshotStepLogistics: React.FunctionComponent<StepProps> =
|
||||||
checked={includeGlobalState === undefined ? false : includeGlobalState}
|
checked={includeGlobalState === undefined ? false : includeGlobalState}
|
||||||
onChange={(e) => updateRestoreSettings({ includeGlobalState: e.target.checked })}
|
onChange={(e) => updateRestoreSettings({ includeGlobalState: e.target.checked })}
|
||||||
disabled={!snapshotIncludeGlobalState}
|
disabled={!snapshotIncludeGlobalState}
|
||||||
|
data-test-subj="includeGlobalStateSwitch"
|
||||||
/>
|
/>
|
||||||
</EuiFormRow>
|
</EuiFormRow>
|
||||||
</EuiDescribedFormGroup>
|
</EuiDescribedFormGroup>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 { i18n } from '@kbn/i18n';
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import { EuiCallOut } from '@elastic/eui';
|
||||||
|
|
||||||
|
export const SystemIndicesOverwrittenCallOut: FunctionComponent = () => {
|
||||||
|
return (
|
||||||
|
<EuiCallOut
|
||||||
|
data-test-subj="systemIndicesInfoCallOut"
|
||||||
|
title={i18n.translate(
|
||||||
|
'xpack.snapshotRestore.restoreForm.stepLogistics.systemIndicesCallOut.title',
|
||||||
|
{
|
||||||
|
defaultMessage:
|
||||||
|
'When this snapshot is restored, system indices will be overwritten with data from the snapshot.',
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
iconType="pin"
|
||||||
|
size="s"
|
||||||
|
aria-live="polite"
|
||||||
|
aria-atomic="true"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -21323,7 +21323,6 @@
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "データストリームとインデックスを選択",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "データストリームとインデックスを選択",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "すべて選択解除",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "すべて選択解除",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "スナップショットと復元ドキュメント",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "スナップショットと復元ドキュメント",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription": "現在クラスターに存在しないテンプレートを復元し、テンプレートを同じ名前で上書きします。永続的な設定も復元します。",
|
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDisabledDescription": "このスナップショットでは使用できません。",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDisabledDescription": "このスナップショットでは使用できません。",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateLabel": "グローバル状態の復元",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateLabel": "グローバル状態の復元",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateTitle": "グローバル状態の復元",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateTitle": "グローバル状態の復元",
|
||||||
|
|
|
@ -21661,7 +21661,6 @@
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "选择数据流和索引",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "选择数据流和索引",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "取消全选",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "取消全选",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "快照和还原文档",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "快照和还原文档",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription": "还原当前在集群中不存在的模板并覆盖同名模板。同时还原永久性设置。",
|
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDisabledDescription": "不适用于此快照。",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDisabledDescription": "不适用于此快照。",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateLabel": "还原全局状态",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateLabel": "还原全局状态",
|
||||||
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateTitle": "还原全局状态",
|
"xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateTitle": "还原全局状态",
|
||||||
|
|
Loading…
Reference in a new issue