Skip to content

Commit

Permalink
[UA] Special handling of ES transforms (#211418)
Browse files Browse the repository at this point in the history
  • Loading branch information
jloleysens authored Feb 17, 2025
1 parent e86ca4b commit c6e0eeb
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ export interface ReindexAction {
* In future this could be an array of blockers.
*/
blockerForReindexing?: 'index-closed'; // 'index-closed' can be handled automatically, but requires more resources, user should be warned

/**
* The transform IDs that are currently targeting this index
*/
transformIds?: string[];
}

export interface UnfreezeAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export const IndexFlyout: React.FunctionComponent<IndexFlyoutProps> = ({
startReadonly={() => {
setFlyoutStep('confirmReadonly');
}}
deprecation={deprecation}
updateIndexState={updateIndexState}
reindexState={reindexState}
/>
Expand Down Expand Up @@ -214,6 +215,7 @@ export const IndexFlyout: React.FunctionComponent<IndexFlyoutProps> = ({
}, [
flyoutStep,
correctiveAction?.type,
deprecation,
closeFlyout,
updateIndexState,
reindexState,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 { EuiCallOut, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import type { EnrichedDeprecationInfo } from '../../../../../../../../../common/types';
import { useAppContext } from '../../../../../../../app_context';

interface Props {
deprecation: EnrichedDeprecationInfo;
}

/**
* We get copy directly from ES. This contains information that applies to indices
* that are read-only or not.
*/
export const ESTransformsTargetGuidance = ({ deprecation }: Props) => {
const {
services: {
core: { http },
},
} = useAppContext();
return (
<>
<EuiCallOut
title={i18n.translate(
'xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.esTransform.calloutTitle',
{ defaultMessage: 'Transforms detected' }
)}
data-test-subj="esTransformsGuidance"
color="warning"
>
{deprecation.details}
</EuiCallOut>
<EuiSpacer size="s" />
<EuiText size="m">
<p>
<FormattedMessage
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.esTransform.description1"
defaultMessage="The reindex operation will copy all of the existing documents into a new index and remove the old one. During the reindex operation your data will be in a read-only state and transforms writing to this index will be paused."
/>
</p>
<p>
<FormattedMessage
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.esTransform.description2"
defaultMessage="Depending on size and resources, reindexing may take an extended time. For indices with more than 10GB of data or to avoid transform downtime refer to the {migrationGuideLink} or {transformsLink} to manage transforms writing to this index."
values={{
migrationGuideLink: (
<EuiLink target="_blank" href={deprecation.url}>
{i18n.translate(
'xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.esTransform.migrationGuideLink',
{ defaultMessage: 'migration guide' }
)}
</EuiLink>
),
transformsLink: (
<EuiLink
target="_blank"
href={`${http.basePath.prepend('/app/management/data/transform')}`}
>
<FormattedMessage
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.esTransform.transfromsLink"
defaultMessage="go to transforms"
/>
</EuiLink>
),
}}
/>
</p>
</EuiText>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { ReindexState } from '../../../use_reindex';
import type { UpdateIndexState } from '../../../use_update_index';
import { LoadingState } from '../../../../../../types';
import { cloneDeep } from 'lodash';
import { EnrichedDeprecationInfo } from '../../../../../../../../../common/types';

jest.mock('../../../../../../../app_context', () => {
const { docLinksServiceMock } = jest.requireActual('@kbn/core-doc-links-browser-mocks');
Expand All @@ -38,6 +39,13 @@ jest.mock('../../../../../../../app_context', () => {
});

describe('ReindexDetailsFlyoutStep', () => {
const deprecation: EnrichedDeprecationInfo = {
isCritical: true,
message: 'foo',
resolveDuringUpgrade: false,
type: 'index_settings',
url: 'https://te.st',
};
const defaultReindexState: ReindexState = {
loadingState: LoadingState.Success,
meta: {
Expand Down Expand Up @@ -65,6 +73,7 @@ describe('ReindexDetailsFlyoutStep', () => {
startReadonly={jest.fn()}
reindexState={defaultReindexState}
updateIndexState={defaultUpdateIndexState}
deprecation={deprecation}
/>
);

Expand Down Expand Up @@ -206,6 +215,94 @@ describe('ReindexDetailsFlyoutStep', () => {
`);
});

it('renders correct guidance for indices with transforms', () => {
const wrapper = shallow(
<ReindexDetailsFlyoutStep
closeFlyout={jest.fn()}
startReindex={jest.fn()}
startReadonly={jest.fn()}
reindexState={defaultReindexState}
updateIndexState={defaultUpdateIndexState}
deprecation={{
...deprecation,
correctiveAction: { type: 'reindex', transformIds: ['abc', 'def'] },
}}
/>
);
expect(wrapper).toMatchInlineSnapshot(`
<Fragment>
<EuiFlyoutBody>
<EuiText>
<ESTransformsTargetGuidance
deprecation={
Object {
"correctiveAction": Object {
"transformIds": Array [
"abc",
"def",
],
"type": "reindex",
},
"isCritical": true,
"message": "foo",
"resolveDuringUpgrade": false,
"type": "index_settings",
"url": "https://te.st",
}
}
/>
</EuiText>
<EuiSpacer />
</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiFlexGroup
justifyContent="spaceBetween"
>
<EuiFlexItem
grow={false}
>
<EuiButtonEmpty
flush="left"
iconType="cross"
onClick={[MockFunction]}
>
<MemoizedFormattedMessage
defaultMessage="Close"
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.closeButtonLabel"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem
grow={false}
>
<EuiFlexGroup
gutterSize="s"
>
<EuiFlexItem
grow={false}
>
<EuiButton
color="primary"
data-test-subj="startReindexingButton"
disabled={false}
fill={true}
isLoading={false}
onClick={[MockFunction]}
>
<MemoizedFormattedMessage
defaultMessage="Start reindexing"
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.reindexButton.runReindexLabel"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
</Fragment>
`);
});

it('renders for readonly indices (warning deprecation)', () => {
const props = cloneDeep(defaultReindexState);
props.meta.isReadonly = true;
Expand All @@ -217,6 +314,7 @@ describe('ReindexDetailsFlyoutStep', () => {
startReadonly={jest.fn()}
reindexState={props}
updateIndexState={defaultUpdateIndexState}
deprecation={deprecation}
/>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import {
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';

import { ReindexStatus } from '../../../../../../../../../common/types';
import {
EnrichedDeprecationInfo,
ReindexAction,
ReindexStatus,
} from '../../../../../../../../../common/types';
import { LoadingState } from '../../../../../../types';
import type { ReindexState } from '../../../use_reindex';
import { useAppContext } from '../../../../../../../app_context';
Expand All @@ -32,17 +36,26 @@ import { FrozenCallOut } from '../frozen_callout';
import type { UpdateIndexState } from '../../../use_update_index';
import { FetchFailedCallOut } from '../fetch_failed_callout';
import { ReindexingFailedCallOut } from '../reindexing_failed_callout';
import { ESTransformsTargetGuidance } from './es_transform_target_guidance';

/**
* Displays a flyout that shows the details / corrective action for a "reindex" deprecation for a given index.
*/
export const ReindexDetailsFlyoutStep: React.FunctionComponent<{
reindexState: ReindexState;
updateIndexState: UpdateIndexState;
deprecation: EnrichedDeprecationInfo;
startReindex: () => void;
startReadonly: () => void;
closeFlyout: () => void;
}> = ({ reindexState, updateIndexState, startReindex, startReadonly, closeFlyout }) => {
}> = ({
reindexState,
updateIndexState,
deprecation,
startReindex,
startReadonly,
closeFlyout,
}) => {
const {
services: {
api,
Expand All @@ -57,6 +70,8 @@ export const ReindexDetailsFlyoutStep: React.FunctionComponent<{
const isCompleted = reindexStatus === ReindexStatus.completed || updateIndexStatus === 'complete';
const hasFetchFailed = reindexStatus === ReindexStatus.fetchFailed;
const hasReindexingFailed = reindexStatus === ReindexStatus.failed;
const correctiveAction = deprecation.correctiveAction as ReindexAction | undefined;
const isESTransformTarget = !!correctiveAction?.transformIds?.length;

const { data: nodes } = api.useLoadNodeDiskSpace();

Expand Down Expand Up @@ -145,7 +160,8 @@ export const ReindexDetailsFlyoutStep: React.FunctionComponent<{
</p>
</Fragment>
)}
{!meta.isReadonly && (
{isESTransformTarget && <ESTransformsTargetGuidance deprecation={deprecation} />}
{!meta.isReadonly && !isESTransformTarget && (
<Fragment>
<p>
<FormattedMessage
Expand Down Expand Up @@ -252,20 +268,24 @@ export const ReindexDetailsFlyoutStep: React.FunctionComponent<{
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="s">
{!meta.isReadonly && !hasFetchFailed && !isCompleted && hasRequiredPrivileges && (
<EuiFlexItem grow={false}>
<EuiButton
onClick={startReadonly}
disabled={loading}
data-test-subj="startIndexReadonlyButton"
>
<FormattedMessage
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.startIndexReadonlyButton"
defaultMessage="Mark as read-only"
/>
</EuiButton>
</EuiFlexItem>
)}
{!meta.isReadonly &&
!hasFetchFailed &&
!isCompleted &&
hasRequiredPrivileges &&
!isESTransformTarget && (
<EuiFlexItem grow={false}>
<EuiButton
onClick={startReadonly}
disabled={loading}
data-test-subj="startIndexReadonlyButton"
>
<FormattedMessage
id="xpack.upgradeAssistant.esDeprecations.indices.indexFlyout.detailsStep.startIndexReadonlyButton"
defaultMessage="Mark as read-only"
/>
</EuiButton>
</EuiFlexItem>
)}
{!hasFetchFailed && !isCompleted && hasRequiredPrivileges && (
<EuiFlexItem grow={false}>
<EuiButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@
"resolve_during_rolling_upgrade": false
}
],
"transforms_index": [
{
"level": "critical",
"message": "Old index with a compatibility version < 8.0",
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"details": "This index has version: 7.17.25",
"resolve_during_rolling_upgrade": false,
"_meta": {
"reindex_required": true,
"transform_ids": ["abc"]
}
}
],
"myindex": [
{
"level": "critical",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c6e0eeb

Please sign in to comment.