-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Index lifecycle #25553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Index lifecycle #25553
Changes from 70 commits
25cfc88
d71d35c
7118608
a1055f8
9869f83
05f0da7
9fffdcb
a9565b7
7c7c220
3d16e96
bbf797d
72e414c
c227d13
ec97734
c327036
1861141
f1cec95
f6c7801
2c80733
fa44132
889a618
cac732a
e6ed714
d71f8a0
4a63330
6e081b1
1971280
e73966f
18a0a1d
cadea13
7f5196c
6d0f208
ef390e7
a4ee97d
89aa0e1
80902c8
8c4029d
eaa941f
717106e
11c8c59
7ca4507
e92aef1
664ae58
2f0e6f7
fe047a1
b04de6d
a652e9b
fdc0034
f89af82
5e5ebfe
b855b18
bd9df3a
a26015e
e197ba1
3200cc4
627e782
b63ff0a
4a3077d
48ca9be
7c3c9d7
e1afabb
1a95ec4
753e13e
a2b396d
198fd26
955c395
2e89680
0d171ee
cb7fbfb
bb0d3f2
445804c
960ef2c
80443bd
3f41730
aa8ce1d
b61d2f2
bd22a00
4d1f3dc
4cb443b
525a7ac
90cce7f
94e1d5a
ce1d8b2
e50924d
fb72e67
4d7af88
6af1d0c
9eb7b1c
73e13e0
2606b4b
a777230
1e1bfce
8855a3b
bb6d539
4caff44
67a7e47
9520690
6a0a286
b85d2d9
c7fda8e
f748192
0b9108c
79c7a01
8543150
a9bca53
a0434e6
cdec345
b765b82
84acff7
11aa4e1
df39f2b
361e8ad
4f45d68
c9a2c31
7e7e34d
acceb13
e72ac43
a602c60
e325412
f644847
fc800c2
e04ea81
621f76c
7bf0f1e
f2396fd
2091c82
e8e8d7e
449f8cf
8708783
ba2bdde
c316924
e219e27
b1c218e
5b41501
ae4f7ef
fb319d4
cee9893
7a84207
f056efb
50c9edb
26d6838
23b0db4
5a02830
05a7f91
adbc6cd
9ee24db
00f3aa8
92972ef
7d91d6a
eae092a
5990be0
345ddf8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| /* | ||
| * 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 const BASE_PATH = '/management/elasticsearch/index_lifecycle_management/'; | ||
| export const PLUGIN_ID = 'index_lifecycle_management'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /* | ||
| * 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 { resolve } from 'path'; | ||
| import { registerTemplatesRoutes } from './server/routes/api/templates'; | ||
| import { registerNodesRoutes } from './server/routes/api/nodes'; | ||
| import { registerPoliciesRoutes } from './server/routes/api/policies'; | ||
| import { registerLifecycleRoutes } from './server/routes/api/lifecycle'; | ||
| import { registerIndexRoutes } from './server/routes/api/index'; | ||
| import { registerLicenseChecker } from './server/lib/register_license_checker'; | ||
| import { PLUGIN_ID } from './common/constants'; | ||
| import { indexLifecycleDataEnricher } from './index_lifecycle_data'; | ||
| export function indexLifecycleManagement(kibana) { | ||
| return new kibana.Plugin({ | ||
| id: PLUGIN_ID, | ||
| publicDir: resolve(__dirname, 'public'), | ||
| configPrefix: 'xpack.index_lifecycle_management', | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you feel about renaming "Index Lifecycle Management" to just "Index Lifecycles"? This way we won't end up with a dozen "Foo Management" apps. We renamed "Remote Cluster Management" to "Remote Clusters" for the same reason.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for display names I think that is ok. I would prefer to keep the code level name index_lifecycle_management as that makes it clear where the code fits in Kibana. |
||
| require: ['kibana', 'elasticsearch', 'xpack_main', 'index_management'], | ||
| uiExports: { | ||
| managementSections: ['plugins/index_lifecycle_management'], | ||
| }, | ||
| isEnabled(config) { | ||
| return ( | ||
| config.get('xpack.index_lifecycle_management.enabled') && | ||
| config.has('index_management.enabled') && | ||
| config.get('index_management.enabled') | ||
| ); | ||
| }, | ||
| init: function (server) { | ||
| registerLicenseChecker(server); | ||
| registerTemplatesRoutes(server); | ||
| registerNodesRoutes(server); | ||
| registerPoliciesRoutes(server); | ||
| registerLifecycleRoutes(server); | ||
| registerIndexRoutes(server); | ||
| if ( | ||
| server.plugins.index_management && | ||
| server.plugins.index_management.addIndexManagementDataEnricher | ||
| ) { | ||
| server.plugins.index_management.addIndexManagementDataEnricher(indexLifecycleDataEnricher); | ||
| } | ||
| }, | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| /* | ||
| * 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 const indexLifecycleDataEnricher = async (indicesList, callWithRequest) => { | ||
| if (!indicesList || !indicesList.length) { | ||
| return; | ||
| } | ||
| const params = { | ||
| path: '/*/_ilm/explain', | ||
| method: 'GET', | ||
| }; | ||
| const { indices: ilmIndicesData } = await callWithRequest('transport.request', params); | ||
| return indicesList.map(index => { | ||
| return { | ||
| ...index, | ||
| ilm: { ...(ilmIndicesData[index.name] || {}) }, | ||
| }; | ||
| }); | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||||
| /* | ||||||||
| * 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 React from 'react'; | ||||||||
| import { HashRouter, Switch, Route } from 'react-router-dom'; | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| import { EditPolicy } from './sections/edit_policy'; | ||||||||
| import { PolicyTable } from './sections/policy_table'; | ||||||||
| import { BASE_PATH } from '../common/constants'; | ||||||||
|
|
||||||||
| export const App = () => ( | ||||||||
| <HashRouter> | ||||||||
| <Switch> | ||||||||
| <Route exact path={`${BASE_PATH}policies`} component={PolicyTable}/> | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clicking
Suggested change
|
||||||||
| <Route path={`${BASE_PATH}policies/edit/:policyName?`} component={EditPolicy}/> | ||||||||
| </Switch> | ||||||||
| </HashRouter> | ||||||||
| ); | ||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,282 @@ | ||||||
| /* | ||||||
| * 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 React, { Component } from 'react'; | ||||||
| import { get } from 'lodash'; | ||||||
| import { i18n } from '@kbn/i18n'; | ||||||
| import { | ||||||
| EuiLink, | ||||||
| EuiSelect, | ||||||
| EuiForm, | ||||||
| EuiFormRow, | ||||||
| EuiOverlayMask, | ||||||
| EuiConfirmModal, | ||||||
| EuiModal, | ||||||
| EuiModalBody, | ||||||
| EuiModalHeader, | ||||||
| EuiCallOut, | ||||||
| EuiModalHeaderTitle, | ||||||
| } from '@elastic/eui'; | ||||||
| import { BASE_PATH } from '../../../common/constants'; | ||||||
| import { FormattedMessage } from '@kbn/i18n/react'; | ||||||
| import { toastNotifications } from 'ui/notify'; | ||||||
| import { loadPolicies, addLifecyclePolicyToIndex } from '../../services/api'; | ||||||
| import { showApiError } from '../../services/api_errors'; | ||||||
| export class AddLifecyclePolicyConfirmModal extends Component { | ||||||
| constructor(props) { | ||||||
| super(props); | ||||||
| this.state = { | ||||||
| policies: [], | ||||||
| selectedPolicyName: null, | ||||||
| selectedAlias: null, | ||||||
| }; | ||||||
| } | ||||||
| addPolicy = async () => { | ||||||
| const { indexName, httpClient, closeModal, reloadIndices } = this.props; | ||||||
| const { selectedPolicyName, selectedAlias } = this.state; | ||||||
| if (!selectedPolicyName) { | ||||||
| return; | ||||||
| } | ||||||
| try { | ||||||
| const body = { | ||||||
| indexName, | ||||||
| policyName: selectedPolicyName, | ||||||
| alias: selectedAlias, | ||||||
| }; | ||||||
| await addLifecyclePolicyToIndex(body, httpClient); | ||||||
| closeModal(); | ||||||
| toastNotifications.addSuccess( | ||||||
| i18n.translate( | ||||||
| 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.addPolicyToIndexSuccess', | ||||||
| { | ||||||
| defaultMessage: 'Added policy {policyName} to index {indexName}', | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| values: { | ||||||
| policyName: selectedPolicyName, | ||||||
| indexName, | ||||||
| }, | ||||||
| } | ||||||
| ) | ||||||
| ); | ||||||
| reloadIndices(); | ||||||
| } catch (err) { | ||||||
| showApiError( | ||||||
| err, | ||||||
| i18n.translate( | ||||||
| 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.addPolicyToIndexError', | ||||||
| { | ||||||
| defaultMessage: 'Error adding policy to index', | ||||||
| } | ||||||
| ) | ||||||
| ); | ||||||
| } | ||||||
| }; | ||||||
| renderAliasFormElement = selectedPolicy => { | ||||||
| const { selectedAlias } = this.state; | ||||||
| const { index } = this.props; | ||||||
| const showAliasSelect = | ||||||
| selectedPolicy && get(selectedPolicy, 'policy.phases.hot.actions.rollover'); | ||||||
| if (!showAliasSelect) { | ||||||
| return null; | ||||||
| } | ||||||
| const { aliases } = index; | ||||||
| if (aliases === 'none') { | ||||||
| return ( | ||||||
| <EuiCallOut | ||||||
| style={{ maxWidth: 400 }} | ||||||
| title={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.indexHasNoAliasesWarningTitle" | ||||||
| defaultMessage="Index has no aliases" | ||||||
| /> | ||||||
| } | ||||||
| color="warning" | ||||||
| > | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.indexHasNoAliasesWarningMessage" | ||||||
| defaultMessage="Policy {policyName} is configured for rollover, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| but index {indexName} does not have an alias, which is required for rollover." | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| values={{ | ||||||
| policyName: selectedPolicy.name, | ||||||
| indexName: index.name, | ||||||
| }} | ||||||
| /> | ||||||
| </EuiCallOut> | ||||||
| ); | ||||||
| } | ||||||
| const aliasOptions = aliases.map(alias => { | ||||||
| return { | ||||||
| text: alias, | ||||||
| value: alias, | ||||||
| }; | ||||||
| }); | ||||||
| aliasOptions.unshift({ | ||||||
| text: i18n.translate( | ||||||
| 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.chooseAliasMessage', | ||||||
| { | ||||||
| defaultMessage: 'Choose an alias', | ||||||
| } | ||||||
| ), | ||||||
| value: '', | ||||||
| }); | ||||||
| return ( | ||||||
| <EuiFormRow | ||||||
| label={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.chooseAliasLabel" | ||||||
| defaultMessage="Index alias" | ||||||
| /> | ||||||
| } | ||||||
| > | ||||||
| <EuiSelect | ||||||
| options={aliasOptions} | ||||||
| value={selectedAlias} | ||||||
| onChange={e => { | ||||||
| this.setState({ selectedAlias: e.target.value }); | ||||||
| }} | ||||||
| aria-label="Use aria labels when no actual label is in use" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs to be fixed |
||||||
| /> | ||||||
| </EuiFormRow> | ||||||
| ); | ||||||
| }; | ||||||
| renderForm() { | ||||||
| const { policies, selectedPolicyName } = this.state; | ||||||
| const selectedPolicy = selectedPolicyName | ||||||
| ? policies.find(policy => policy.name === selectedPolicyName) | ||||||
| : null; | ||||||
|
|
||||||
| const options = policies.map(({ name }) => { | ||||||
| return { | ||||||
| value: name, | ||||||
| text: name, | ||||||
| }; | ||||||
| }); | ||||||
| options.unshift({ | ||||||
| value: '', | ||||||
| text: i18n.translate( | ||||||
| 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.choosePolicyMessage', | ||||||
| { | ||||||
| defaultMessage: 'Choose a lifecycle policy', | ||||||
| } | ||||||
| ), | ||||||
| }); | ||||||
| return ( | ||||||
| <EuiForm> | ||||||
| <EuiFormRow | ||||||
| label={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.choosePolicyLabel" | ||||||
| defaultMessage="Lifecycle policy" | ||||||
| /> | ||||||
| } | ||||||
| > | ||||||
| <EuiSelect | ||||||
| options={options} | ||||||
| value={selectedPolicyName} | ||||||
|
bmcconaghy marked this conversation as resolved.
|
||||||
| onChange={e => { | ||||||
| this.setState({ selectedPolicyName: e.target.value }); | ||||||
| }} | ||||||
| aria-label="Use aria labels when no actual label is in use" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs to be fixed |
||||||
| /> | ||||||
| </EuiFormRow> | ||||||
| {this.renderAliasFormElement(selectedPolicy)} | ||||||
| </EuiForm> | ||||||
| ); | ||||||
| } | ||||||
| async componentDidMount() { | ||||||
| try { | ||||||
| const policies = await loadPolicies(false, this.props.httpClient); | ||||||
| this.setState({ policies }); | ||||||
| } catch (err) { | ||||||
| showApiError( | ||||||
| err, | ||||||
| i18n.translate( | ||||||
| 'xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.loadPolicyError', | ||||||
| { | ||||||
| defaultMessage: 'Error loading policy list', | ||||||
| } | ||||||
| ) | ||||||
| ); | ||||||
| this.props.closeModal(); | ||||||
| } | ||||||
| } | ||||||
| render() { | ||||||
| const { policies } = this.state; | ||||||
| const { indexName, closeModal } = this.props; | ||||||
| const title = ( | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.modalTitle" | ||||||
| defaultMessage="Add lifecycle policy to {indexName}" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| values={{ | ||||||
| indexName, | ||||||
| }} | ||||||
| /> | ||||||
| ); | ||||||
| if (!policies.length) { | ||||||
| return ( | ||||||
| <EuiOverlayMask> | ||||||
| <EuiModal | ||||||
| onClose={closeModal} | ||||||
| > | ||||||
| <EuiModalHeader> | ||||||
| <EuiModalHeaderTitle > | ||||||
| {title} | ||||||
| </EuiModalHeaderTitle > | ||||||
|
|
||||||
| </EuiModalHeader> | ||||||
| <EuiModalBody> | ||||||
| <EuiCallOut | ||||||
| style={{ maxWidth: 400 }} | ||||||
| title={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.noPoliciesWarningTitle" | ||||||
| defaultMessage="No index lifecycle policies defined" | ||||||
| /> | ||||||
| } | ||||||
| color="warning" | ||||||
| > | ||||||
| <FormattedMessage | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.noPoliciesWarningMessage" | ||||||
| defaultMessage="No index lifecycle policies are defined." | ||||||
| /> | ||||||
| <p> | ||||||
| <EuiLink href={`#${BASE_PATH}policies/edit`}> | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.defineLifecyclePolicyLinkText" | ||||||
| defaultMessage="Define lifecycle policy" | ||||||
| /> | ||||||
| </EuiLink> | ||||||
| </p> | ||||||
| </EuiCallOut> | ||||||
| </EuiModalBody> | ||||||
| </EuiModal> | ||||||
| </EuiOverlayMask> | ||||||
| ); | ||||||
| } | ||||||
| return ( | ||||||
| <EuiOverlayMask> | ||||||
| <EuiConfirmModal | ||||||
| title={title} | ||||||
| onCancel={closeModal} | ||||||
| onConfirm={this.addPolicy} | ||||||
| cancelButtonText={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.cancelButtonText" | ||||||
| defaultMessage="Cancel" | ||||||
| /> | ||||||
| } | ||||||
| confirmButtonText={ | ||||||
| <FormattedMessage | ||||||
| id="xpack.indexLifecycleMgmt.indexManagementTable.addLifecyclePolicyConfirmModal.addPolicyButtonText" | ||||||
| defaultMessage="Add policy" | ||||||
| /> | ||||||
| } | ||||||
| > | ||||||
| {this.renderForm()} | ||||||
| </EuiConfirmModal> | ||||||
| </EuiOverlayMask> | ||||||
| ); | ||||||
| } | ||||||
| } | ||||||

Uh oh!
There was an error while loading. Please reload this page.