[ILM] TS conversion of Index Management plugin extension (#76517)

* [ILM] TS conversion of Index Management plugin extension

* [ILM] Implement review suggestions

* [ILM] Fix jest test

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Yulia Čech 2020-09-04 13:47:16 +02:00 committed by GitHub
parent 6e339d319d
commit 70b4b89270
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 331 additions and 129 deletions

View file

@ -134,6 +134,7 @@ exports[`extend index management ilm summary extension should return extension w
},
"step_time_millis": 1544187776208,
},
"isFrozen": false,
"name": "testy3",
"primary": "1",
"primary_size": "6.5kb",
@ -326,6 +327,82 @@ exports[`extend index management ilm summary extension should return extension w
className="euiSpacer euiSpacer--s"
/>
</EuiSpacer>
<EuiPopover
anchorPosition="downCenter"
button={
<EuiButtonEmpty
onClick={[Function]}
>
<FormattedMessage
defaultMessage="Stack trace"
id="xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.stackTraceButton"
values={Object {}}
/>
</EuiButtonEmpty>
}
closePopover={[Function]}
display="inlineBlock"
hasArrow={true}
id="stackPopover"
isOpen={false}
ownFocus={false}
panelPaddingSize="m"
>
<EuiOutsideClickDetector
isDisabled={true}
onOutsideClick={[Function]}
>
<div
className="euiPopover euiPopover--anchorDownCenter"
id="stackPopover"
onKeyDown={[Function]}
onMouseDown={[Function]}
onMouseUp={[Function]}
onTouchEnd={[Function]}
onTouchStart={[Function]}
>
<div
className="euiPopover__anchor"
>
<EuiButtonEmpty
onClick={[Function]}
>
<button
className="euiButtonEmpty euiButtonEmpty--primary"
onClick={[Function]}
type="button"
>
<EuiButtonContent
className="euiButtonEmpty__content"
iconSide="left"
textProps={
Object {
"className": "euiButtonEmpty__text",
}
}
>
<span
className="euiButtonContent euiButtonEmpty__content"
>
<span
className="euiButtonEmpty__text"
>
<FormattedMessage
defaultMessage="Stack trace"
id="xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.stackTraceButton"
values={Object {}}
>
Stack trace
</FormattedMessage>
</span>
</span>
</EuiButtonContent>
</button>
</EuiButtonEmpty>
</div>
</div>
</EuiOutsideClickDetector>
</EuiPopover>
</div>
</EuiText>
</div>
@ -588,6 +665,7 @@ exports[`extend index management ilm summary extension should return extension w
"step": "complete",
"step_time_millis": 1544187775867,
},
"isFrozen": false,
"name": "testy3",
"primary": "1",
"primary_size": "6.5kb",

View file

@ -8,7 +8,8 @@ import moment from 'moment-timezone';
import axios from 'axios';
import axiosXhrAdapter from 'axios/lib/adapters/xhr';
import { mountWithIntl } from '../../../test_utils/enzyme_helpers';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { usageCollectionPluginMock } from '../../../../src/plugins/usage_collection/public/mocks';
import {
retryLifecycleActionExtension,
removeLifecyclePolicyActionExtension,
@ -19,19 +20,22 @@ import {
} from '../public/extend_index_management';
import { init as initHttp } from '../public/application/services/http';
import { init as initUiMetric } from '../public/application/services/ui_metric';
import { Index } from '../public/application/services/policies/types';
// We need to init the http with a mock for any tests that depend upon the http service.
// For example, add_lifecycle_confirm_modal makes an API request in its componentDidMount
// lifecycle method. If we don't mock this, CI will fail with "Call retries were exceeded".
initHttp(axios.create({ adapter: axiosXhrAdapter }), (path) => path);
initUiMetric({ reportUiStats: () => {} });
// This expects HttpSetup but we're giving it AxiosInstance.
// @ts-ignore
initHttp(axios.create({ adapter: axiosXhrAdapter }));
initUiMetric(usageCollectionPluginMock.createSetupContract());
jest.mock('../../../plugins/index_management/public', async () => {
const { indexManagementMock } = await import('../../../plugins/index_management/public/mocks.ts');
const { indexManagementMock } = await import('../../../plugins/index_management/public/mocks');
return indexManagementMock.createSetup();
});
const indexWithoutLifecyclePolicy = {
const indexWithoutLifecyclePolicy: Index = {
health: 'yellow',
status: 'open',
name: 'noPolicy',
@ -43,13 +47,14 @@ const indexWithoutLifecyclePolicy = {
size: '3.4kb',
primary_size: '3.4kb',
aliases: 'none',
isFrozen: false,
ilm: {
index: 'testy1',
managed: false,
},
};
const indexWithLifecyclePolicy = {
const indexWithLifecyclePolicy: Index = {
health: 'yellow',
status: 'open',
name: 'testy3',
@ -61,6 +66,7 @@ const indexWithLifecyclePolicy = {
size: '6.5kb',
primary_size: '6.5kb',
aliases: 'none',
isFrozen: false,
ilm: {
index: 'testy3',
managed: true,
@ -87,6 +93,7 @@ const indexWithLifecycleError = {
size: '6.5kb',
primary_size: '6.5kb',
aliases: 'none',
isFrozen: false,
ilm: {
index: 'testy3',
managed: true,
@ -115,10 +122,12 @@ const indexWithLifecycleError = {
moment.tz.setDefault('utc');
const getUrlForApp = (appId, options) => {
const getUrlForApp = (appId: string, options: any) => {
return appId + '/' + (options ? options.path : '');
};
const reloadIndices = () => {};
describe('extend index management', () => {
describe('retry lifecycle action extension', () => {
test('should return null when no indices have index lifecycle policy', () => {
@ -153,6 +162,7 @@ describe('extend index management', () => {
test('should return null when no indices have index lifecycle policy', () => {
const extension = removeLifecyclePolicyActionExtension({
indices: [indexWithoutLifecyclePolicy],
reloadIndices,
});
expect(extension).toBeNull();
});
@ -160,6 +170,7 @@ describe('extend index management', () => {
test('should return null when some indices have index lifecycle policy', () => {
const extension = removeLifecyclePolicyActionExtension({
indices: [indexWithoutLifecyclePolicy, indexWithLifecyclePolicy],
reloadIndices,
});
expect(extension).toBeNull();
});
@ -167,6 +178,7 @@ describe('extend index management', () => {
test('should return extension when all indices have lifecycle policy', () => {
const extension = removeLifecyclePolicyActionExtension({
indices: [indexWithLifecycleError, indexWithLifecycleError],
reloadIndices,
});
expect(extension).toBeDefined();
expect(extension).toMatchSnapshot();
@ -175,16 +187,18 @@ describe('extend index management', () => {
describe('add lifecycle policy action extension', () => {
test('should return null when index has index lifecycle policy', () => {
const extension = addLifecyclePolicyActionExtension(
{ indices: [indexWithLifecyclePolicy] },
getUrlForApp
);
const extension = addLifecyclePolicyActionExtension({
indices: [indexWithLifecyclePolicy],
reloadIndices,
getUrlForApp,
});
expect(extension).toBeNull();
});
test('should return null when more than one index is passed', () => {
const extension = addLifecyclePolicyActionExtension({
indices: [indexWithoutLifecyclePolicy, indexWithoutLifecyclePolicy],
reloadIndices,
getUrlForApp,
});
expect(extension).toBeNull();
@ -193,10 +207,11 @@ describe('extend index management', () => {
test('should return extension when one index is passed and it does not have lifecycle policy', () => {
const extension = addLifecyclePolicyActionExtension({
indices: [indexWithoutLifecyclePolicy],
reloadIndices,
getUrlForApp,
});
expect(extension.renderConfirmModal).toBeDefined;
const component = extension.renderConfirmModal(jest.fn());
expect(extension?.renderConfirmModal).toBeDefined();
const component = extension!.renderConfirmModal(jest.fn());
const rendered = mountWithIntl(component);
expect(rendered.exists('.euiModal--confirmation'));
});

View file

@ -12,7 +12,7 @@ import {
UIM_POLICY_ATTACH_INDEX_TEMPLATE,
UIM_POLICY_DETACH_INDEX,
UIM_INDEX_RETRY_STEP,
} from '../constants/ui_metric';
} from '../constants';
import { trackUiMetric } from './ui_metric';
import { sendGet, sendPost, sendDelete, useRequest } from './http';
@ -78,7 +78,11 @@ export const removeLifecycleForIndex = async (indexNames: string[]) => {
return response;
};
export const addLifecyclePolicyToIndex = async (body: GenericObject) => {
export const addLifecyclePolicyToIndex = async (body: {
indexName: string;
policyName: string;
alias: string;
}) => {
const response = await sendPost(`index/add`, body);
// Only track successful actions.
trackUiMetric(METRIC_TYPE.COUNT, UIM_POLICY_ATTACH_INDEX);

View file

@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Index as IndexInterface } from '../../../../../index_management/public';
export interface SerializedPolicy {
name: string;
phases: Phases;
@ -169,3 +171,36 @@ export interface FrozenPhase
export interface DeletePhase extends CommonPhaseSettings, PhaseWithMinAge {
waitForSnapshotPolicy: string;
}
export interface IndexLifecyclePolicy {
index: string;
managed: boolean;
action?: string;
action_time_millis?: number;
age?: string;
failed_step?: string;
failed_step_retry_count?: number;
is_auto_retryable_error?: boolean;
lifecycle_date_millis?: number;
phase?: string;
phase_execution?: {
policy: string;
modified_date_in_millis: number;
version: number;
phase_definition: SerializedPhase;
};
phase_time_millis?: number;
policy?: string;
step?: string;
step_info?: {
reason?: string;
stack_trace?: string;
type?: string;
message?: string;
};
step_time_millis?: number;
}
export interface Index extends IndexInterface {
ilm: IndexLifecyclePolicy;
}

View file

@ -8,6 +8,8 @@ import React, { Component, Fragment } from 'react';
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { ApplicationStart } from 'kibana/public';
import {
EuiLink,
EuiSelect,
@ -26,9 +28,25 @@ import {
import { loadPolicies, addLifecyclePolicyToIndex } from '../../application/services/api';
import { showApiError } from '../../application/services/api_errors';
import { toasts } from '../../application/services/notification';
import { Index, PolicyFromES } from '../../application/services/policies/types';
export class AddLifecyclePolicyConfirmModal extends Component {
constructor(props) {
interface Props {
indexName: string;
closeModal: () => void;
index: Index;
reloadIndices: () => void;
getUrlForApp: ApplicationStart['getUrlForApp'];
}
interface State {
selectedPolicyName: string;
selectedAlias: string;
policies: PolicyFromES[];
policyErrorMessage?: string;
}
export class AddLifecyclePolicyConfirmModal extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
policies: [],
@ -41,7 +59,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
const { selectedPolicyName, selectedAlias } = this.state;
if (!selectedPolicyName) {
this.setState({
policyError: i18n.translate(
policyErrorMessage: i18n.translate(
'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.noPolicySelectedErrorMessage',
{ defaultMessage: 'You must select a policy.' }
),
@ -81,7 +99,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
);
}
};
renderAliasFormElement = (selectedPolicy) => {
renderAliasFormElement = (selectedPolicy?: PolicyFromES) => {
const { selectedAlias } = this.state;
const { index } = this.props;
const showAliasSelect =
@ -109,7 +127,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
defaultMessage="Policy {policyName} is configured for rollover,
but index {indexName} does not have an alias, which is required for rollover."
values={{
policyName: selectedPolicy.name,
policyName: selectedPolicy?.name,
indexName: index.name,
}}
/>
@ -117,7 +135,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
</Fragment>
);
}
const aliasOptions = aliases.map((alias) => {
const aliasOptions = (aliases as string[]).map((alias: string) => {
return {
text: alias,
value: alias,
@ -152,10 +170,10 @@ export class AddLifecyclePolicyConfirmModal extends Component {
);
};
renderForm() {
const { policies, selectedPolicyName, policyError } = this.state;
const { policies, selectedPolicyName, policyErrorMessage } = this.state;
const selectedPolicy = selectedPolicyName
? policies.find((policy) => policy.name === selectedPolicyName)
: null;
: undefined;
const options = policies.map(({ name }) => {
return {
@ -175,8 +193,8 @@ export class AddLifecyclePolicyConfirmModal extends Component {
return (
<EuiForm>
<EuiFormRow
isInvalid={!!policyError}
error={policyError}
isInvalid={!!policyErrorMessage}
error={policyErrorMessage}
label={
<FormattedMessage
id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.choosePolicyLabel"
@ -188,7 +206,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
options={options}
value={selectedPolicyName}
onChange={(e) => {
this.setState({ policyError: null, selectedPolicyName: e.target.value });
this.setState({ policyErrorMessage: undefined, selectedPolicyName: e.target.value });
}}
/>
</EuiFormRow>
@ -198,7 +216,7 @@ export class AddLifecyclePolicyConfirmModal extends Component {
}
async componentDidMount() {
try {
const policies = await loadPolicies(false, this.props.httpClient);
const policies = await loadPolicies(false);
this.setState({ policies });
} catch (err) {
showApiError(

View file

@ -24,44 +24,71 @@ import {
EuiPopoverTitle,
} from '@elastic/eui';
import { ApplicationStart } from 'kibana/public';
import { getPolicyPath } from '../../application/services/navigation';
import { Index, IndexLifecyclePolicy } from '../../application/services/policies/types';
const getHeaders = () => {
return {
policy: i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader',
{
defaultMessage: 'Lifecycle policy',
}
),
phase: i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentPhaseHeader',
{
defaultMessage: 'Current phase',
}
),
action: i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionHeader',
{
defaultMessage: 'Current action',
}
),
action_time_millis: i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionTimeHeader',
{
defaultMessage: 'Current action time',
}
),
failed_step: i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.failedStepHeader',
{
defaultMessage: 'Failed step',
}
),
};
const getHeaders = (): Array<[keyof IndexLifecyclePolicy, string]> => {
return [
[
'policy',
i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.lifecyclePolicyHeader',
{
defaultMessage: 'Lifecycle policy',
}
),
],
[
'phase',
i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentPhaseHeader',
{
defaultMessage: 'Current phase',
}
),
],
[
'action',
i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionHeader',
{
defaultMessage: 'Current action',
}
),
],
[
'action_time_millis',
i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.currentActionTimeHeader',
{
defaultMessage: 'Current action time',
}
),
],
[
'failed_step',
i18n.translate(
'xpack.indexLifecycleMgmt.indexLifecycleMgmtSummary.headers.failedStepHeader',
{
defaultMessage: 'Failed step',
}
),
],
];
};
export class IndexLifecycleSummary extends Component {
constructor(props) {
interface Props {
index: Index;
getUrlForApp: ApplicationStart['getUrlForApp'];
}
interface State {
showStackPopover: boolean;
showPhaseExecutionPopover: boolean;
}
export class IndexLifecycleSummary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
showStackPopover: false,
@ -80,8 +107,8 @@ export class IndexLifecycleSummary extends Component {
closePhaseExecutionPopover = () => {
this.setState({ showPhaseExecutionPopover: false });
};
renderStackPopoverButton(ilm) {
if (!ilm.stack_trace) {
renderStackPopoverButton(ilm: IndexLifecyclePolicy) {
if (!ilm.step_info!.stack_trace) {
return null;
}
const button = (
@ -100,15 +127,12 @@ export class IndexLifecycleSummary extends Component {
closePopover={this.closeStackPopover}
>
<div style={{ maxHeight: '400px', width: '900px', overflowY: 'scroll' }}>
<pre>{ilm.step_info.stack_trace}</pre>
<pre>{ilm.step_info!.stack_trace}</pre>
</div>
</EuiPopover>
);
}
renderPhaseExecutionPopoverButton(ilm) {
if (!ilm.phase_execution) {
return null;
}
renderPhaseExecutionPopoverButton(ilm: IndexLifecyclePolicy) {
const button = (
<EuiLink onClick={this.togglePhaseExecutionPopover}>
<FormattedMessage
@ -150,15 +174,18 @@ export class IndexLifecycleSummary extends Component {
}
buildRows() {
const {
index: { ilm = {} },
index: { ilm },
} = this.props;
const headers = getHeaders();
const rows = {
const rows: {
left: JSX.Element[];
right: JSX.Element[];
} = {
left: [],
right: [],
};
Object.keys(headers).forEach((fieldName, arrayIndex) => {
const value = ilm[fieldName];
headers.forEach(([fieldName, label], arrayIndex) => {
const value: any = ilm[fieldName];
let content;
if (fieldName === 'action_time_millis') {
content = moment(value).format('YYYY-MM-DD HH:mm:ss');
@ -176,34 +203,38 @@ export class IndexLifecycleSummary extends Component {
content = value;
}
content = content || '-';
const cell = [
<EuiDescriptionListTitle key={fieldName}>
<strong>{headers[fieldName]}</strong>
</EuiDescriptionListTitle>,
<EuiDescriptionListDescription key={fieldName + '_desc'}>
{content}
</EuiDescriptionListDescription>,
];
const cell = (
<>
<EuiDescriptionListTitle key={fieldName}>
<strong>{label}</strong>
</EuiDescriptionListTitle>
<EuiDescriptionListDescription key={fieldName + '_desc'}>
{content}
</EuiDescriptionListDescription>
</>
);
if (arrayIndex % 2 === 0) {
rows.left.push(cell);
} else {
rows.right.push(cell);
}
});
rows.right.push(this.renderPhaseExecutionPopoverButton(ilm));
if (ilm.phase_execution) {
rows.right.push(this.renderPhaseExecutionPopoverButton(ilm));
}
return rows;
}
render() {
const {
index: { ilm = {} },
index: { ilm },
} = this.props;
if (!ilm.managed) {
return null;
}
const { left, right } = this.buildRows();
return (
<Fragment>
<>
<EuiTitle size="s">
<h3>
<FormattedMessage
@ -213,7 +244,7 @@ export class IndexLifecycleSummary extends Component {
</h3>
</EuiTitle>
{ilm.step_info && ilm.step_info.type ? (
<Fragment>
<>
<EuiSpacer size="s" />
<EuiCallOut
color="danger"
@ -229,10 +260,10 @@ export class IndexLifecycleSummary extends Component {
<EuiSpacer size="s" />
{this.renderStackPopoverButton(ilm)}
</EuiCallOut>
</Fragment>
</>
) : null}
{ilm.step_info && ilm.step_info.message && !ilm.step_info.stack_trace ? (
<Fragment>
{ilm.step_info && ilm.step_info!.message && !ilm.step_info!.stack_trace ? (
<>
<EuiSpacer size="s" />
<EuiCallOut
color="primary"
@ -243,9 +274,9 @@ export class IndexLifecycleSummary extends Component {
/>
}
>
{ilm.step_info.message}
{ilm.step_info!.message}
</EuiCallOut>
</Fragment>
</>
) : null}
<EuiSpacer size="m" />
<EuiFlexGroup>
@ -256,7 +287,7 @@ export class IndexLifecycleSummary extends Component {
<EuiDescriptionList type="column">{right}</EuiDescriptionList>
</EuiFlexItem>
</EuiFlexGroup>
</Fragment>
</>
);
}
}

View file

@ -1,7 +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.
*/
export declare const addAllExtensions: any;

View file

@ -8,22 +8,27 @@ import React from 'react';
import { get, every, some } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiSearchBar } from '@elastic/eui';
import { ApplicationStart } from 'kibana/public';
import { IndexManagementPluginSetup } from '../../../index_management/public';
import { retryLifecycleForIndex } from '../application/services/api';
import { IndexLifecycleSummary } from './components/index_lifecycle_summary';
import { AddLifecyclePolicyConfirmModal } from './components/add_lifecycle_confirm_modal';
import { RemoveLifecyclePolicyConfirmModal } from './components/remove_lifecycle_confirm_modal';
import { Index } from '../application/services/policies/types';
const stepPath = 'ilm.step';
export const retryLifecycleActionExtension = ({ indices }) => {
export const retryLifecycleActionExtension = ({ indices }: { indices: Index[] }) => {
const allHaveErrors = every(indices, (index) => {
return index.ilm && index.ilm.failed_step;
});
if (!allHaveErrors) {
return null;
}
const indexNames = indices.map(({ name }) => name);
const indexNames = indices.map(({ name }: Index) => name);
return {
requestMethod: retryLifecycleForIndex,
icon: 'play',
@ -35,22 +40,28 @@ export const retryLifecycleActionExtension = ({ indices }) => {
'xpack.indexLifecycleMgmt.retryIndexLifecycleAction.retriedLifecycleMessage',
{
defaultMessage: 'Called retry lifecycle step for: {indexNames}',
values: { indexNames: indexNames.map((indexName) => `"${indexName}"`).join(', ') },
values: { indexNames: indexNames.map((indexName: string) => `"${indexName}"`).join(', ') },
}
),
};
};
export const removeLifecyclePolicyActionExtension = ({ indices, reloadIndices }) => {
export const removeLifecyclePolicyActionExtension = ({
indices,
reloadIndices,
}: {
indices: Index[];
reloadIndices: () => void;
}) => {
const allHaveIlm = every(indices, (index) => {
return index.ilm && index.ilm.managed;
});
if (!allHaveIlm) {
return null;
}
const indexNames = indices.map(({ name }) => name);
const indexNames = indices.map(({ name }: Index) => name);
return {
renderConfirmModal: (closeModal) => {
renderConfirmModal: (closeModal: () => void) => {
return (
<RemoveLifecyclePolicyConfirmModal
indexNames={indexNames}
@ -67,7 +78,15 @@ export const removeLifecyclePolicyActionExtension = ({ indices, reloadIndices })
};
};
export const addLifecyclePolicyActionExtension = ({ indices, reloadIndices, getUrlForApp }) => {
export const addLifecyclePolicyActionExtension = ({
indices,
reloadIndices,
getUrlForApp,
}: {
indices: Index[];
reloadIndices: () => void;
getUrlForApp: ApplicationStart['getUrlForApp'];
}) => {
if (indices.length !== 1) {
return null;
}
@ -79,7 +98,7 @@ export const addLifecyclePolicyActionExtension = ({ indices, reloadIndices, getU
}
const indexName = index.name;
return {
renderConfirmModal: (closeModal) => {
renderConfirmModal: (closeModal: () => void) => {
return (
<AddLifecyclePolicyConfirmModal
indexName={indexName}
@ -97,12 +116,12 @@ export const addLifecyclePolicyActionExtension = ({ indices, reloadIndices, getU
};
};
export const ilmBannerExtension = (indices) => {
export const ilmBannerExtension = (indices: Index[]) => {
const { Query } = EuiSearchBar;
if (!indices.length) {
return null;
}
const indicesWithLifecycleErrors = indices.filter((index) => {
const indicesWithLifecycleErrors = indices.filter((index: Index) => {
return get(index, stepPath) === 'ERROR';
});
const numIndicesWithLifecycleErrors = indicesWithLifecycleErrors.length;
@ -124,11 +143,14 @@ export const ilmBannerExtension = (indices) => {
};
};
export const ilmSummaryExtension = (index, getUrlForApp) => {
export const ilmSummaryExtension = (
index: Index,
getUrlForApp: ApplicationStart['getUrlForApp']
) => {
return <IndexLifecycleSummary index={index} getUrlForApp={getUrlForApp} />;
};
export const ilmFilterExtension = (indices) => {
export const ilmFilterExtension = (indices: Index[]) => {
const hasIlm = some(indices, (index) => index.ilm && index.ilm.managed);
if (!hasIlm) {
return [];
@ -200,7 +222,9 @@ export const ilmFilterExtension = (indices) => {
}
};
export const addAllExtensions = (extensionsService) => {
export const addAllExtensions = (
extensionsService: IndexManagementPluginSetup['extensionsService']
) => {
extensionsService.addAction(retryLifecycleActionExtension);
extensionsService.addAction(removeLifecyclePolicyActionExtension);
extensionsService.addAction(addLifecyclePolicyActionExtension);

View file

@ -41,3 +41,18 @@ export interface IndexSettings {
analysis?: AnalysisModule;
[key: string]: any;
}
export interface Index {
health: string;
status: string;
name: string;
uuid: string;
primary: string;
replica: string;
documents: any;
size: any;
isFrozen: boolean;
aliases: string | string[];
data_stream?: string;
[key: string]: any;
}

View file

@ -14,3 +14,5 @@ export const plugin = () => {
export { IndexManagementPluginSetup };
export { getIndexListUri } from './application/services/routing';
export { Index } from '../common';

View file

@ -18,5 +18,5 @@ export const config = {
/** @public */
export { Dependencies } from './types';
export { IndexManagementPluginSetup } from './plugin';
export { Index } from './types';
export { Index } from '../common';
export { IndexManagementConfig } from './config';

View file

@ -5,7 +5,8 @@
*/
import { CatIndicesParams } from 'elasticsearch';
import { IndexDataEnricher } from '../services';
import { Index, CallAsCurrentUser } from '../types';
import { CallAsCurrentUser } from '../types';
import { Index } from '../index';
interface Hit {
health: string;

View file

@ -4,7 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Index, CallAsCurrentUser } from '../types';
import { CallAsCurrentUser } from '../types';
import { Index } from '../index';
export type Enricher = (indices: Index[], callAsCurrentUser: CallAsCurrentUser) => Promise<Index[]>;

View file

@ -26,19 +26,4 @@ export interface RouteDependencies {
};
}
export interface Index {
health: string;
status: string;
name: string;
uuid: string;
primary: string;
replica: string;
documents: any;
size: any;
isFrozen: boolean;
aliases: string | string[];
data_stream?: string;
[key: string]: any;
}
export type CallAsCurrentUser = LegacyScopedClusterClient['callAsCurrentUser'];