mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Upgrade assistant - Phase 1 (#25168)
* Get basic scaffolding working * Wire up cluster checkup data * Add types for elasticsearch plugin * Implement basics of checkup tab * Update style of deprecations * Add copy and reload button to checkup * Add filtering by warning level * Add deprecation logging tab * Copy updates and cleanup * Type cleanup * Move deprecation logging to overview tab * Make filters togglable * Move sections into tabs and add support for grouping * Cleanup and add clearer labels * Use tables for message grouping * Cleanup and small fixes * Allow console to load relative URLs * Add reindex in console button to reindex tasks * Merge documentation UI and uiButtons * Fix tests * Filter bar tweaks * Filter out index settings that can't be set * Fix types * Add tests for deprecation_logging * Add tests for reindex templates * Make KibanaConfig generic * Simplify integration test * Finish backend unit tests * Fixup types * Fix uiButton updating for reindex items * Fixed background color stretching * Pulling tabs out and re-ordering filter buttons * Making accordions more item-list like * Turned Healths into Badges - Couldn’t do the conversion within the cell because it only passed color * Fix overflow issue * Optional filter and expand/collapse controls * Reorganizing - Added placeholder for moving action button up into accordion header - Removed repetitive message name outputs - Slightly better listing of each message when sorting by index - Only showing number of severity when sorting by index - Still need to allow showing all severity levels - Added indice count when sorting by issue * Putting `Deprecation logging` in a `EuiDescribedFormGroup` * Added some stats, empty prompts, and all clear prompt * Added docs link * Cleaned up sass files * Revert changes to fake_deprecations * Update blacklisted settings * wip * Move data fetching and tab control * Wire up overview summary * Cleanup docs/uiButtons + move actions to index table * Add expand/collapse all functionality * Wire up search box * Wire up severity indicators * Fix types * Round out functional tests * Fix fake data * Remove info deprecation level * Fix extra space on cluster tab control bar * Cleanup code and localize majority of UI controls * Change overview tab to steps layout * Update copy * Localize overview tab * Complete localization of checkup tabs * Make ES version dynamic based on branch * Add pagination to checkup tabs * Rename checkup -> assistant * Cleanup filter and group by bars * WIP UI unit tests * Copy tweaks * Fix i18n formatting issues * Update tests for copy * Add tests for remaining UI * Fix pagination w/ filter changes + table button color * Small cleanup * Add reindex button to old index deprecations * Add shrunken indices setting to copy settings blacklist for #18469 * Add next steps to overview tab + update copy * Remove usage of migration assistance API * Use all/critical toggle for filter buttons * Cloud upgrade copy * Translate reindex button * Remove hacked EUI type * Show incomplete banner on all tabs * Update copy for waiting for next version * Review comments * Update deprecation level type * Update checkup tab snapshots * Remove dependencies on types from #25168 * Use types from new global type defs * Remove 'Reindex in Console' button * Remove unused variable
This commit is contained in:
parent
fcb0a6d1ab
commit
4d295c7923
64 changed files with 4916 additions and 3 deletions
|
@ -31,6 +31,7 @@
|
|||
"xpack.searchProfiler": "x-pack/plugins/searchprofiler",
|
||||
"xpack.security": "x-pack/plugins/security",
|
||||
"xpack.spaces": "x-pack/plugins/spaces",
|
||||
"xpack.upgradeAssistant": "x-pack/plugins/upgrade_assistant",
|
||||
"xpack.watcher": "x-pack/plugins/watcher"
|
||||
},
|
||||
"exclude": [
|
||||
|
|
|
@ -371,7 +371,7 @@ export interface CallClusterWithRequest {
|
|||
<T = any>(
|
||||
request: Request,
|
||||
endpoint: string,
|
||||
clientParams: GenericParams,
|
||||
clientParams: any,
|
||||
options?: CallClusterOptions
|
||||
): Promise<T>;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import { kueryAutocomplete } from './plugins/kuery_autocomplete';
|
|||
import { canvas } from './plugins/canvas';
|
||||
import { infra } from './plugins/infra';
|
||||
import { rollup } from './plugins/rollup';
|
||||
import { upgradeAssistant } from './plugins/upgrade_assistant';
|
||||
|
||||
module.exports = function (kibana) {
|
||||
return [
|
||||
|
@ -57,5 +58,6 @@ module.exports = function (kibana) {
|
|||
kueryAutocomplete(kibana),
|
||||
infra(kibana),
|
||||
rollup(kibana),
|
||||
upgradeAssistant(kibana),
|
||||
];
|
||||
};
|
||||
|
|
|
@ -29,6 +29,8 @@ function getInjected(key) {
|
|||
return 'apm*';
|
||||
case 'mlEnabled':
|
||||
return true;
|
||||
case 'isCloudEnabled':
|
||||
return false;
|
||||
default:
|
||||
throw new Error(`Unexpected config key: ${key}`);
|
||||
}
|
||||
|
|
2
x-pack/plugins/infra/types/eui.d.ts
vendored
2
x-pack/plugins/infra/types/eui.d.ts
vendored
|
@ -95,6 +95,8 @@ declare module '@elastic/eui' {
|
|||
rel?: string;
|
||||
target?: string;
|
||||
type?: string;
|
||||
hasActiveFilters?: boolean;
|
||||
numFilters?: number;
|
||||
};
|
||||
export const EuiFilterButton: React.SFC<EuiFilterButtonProps>;
|
||||
|
||||
|
|
14
x-pack/plugins/upgrade_assistant/common/version.ts
Normal file
14
x-pack/plugins/upgrade_assistant/common/version.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 pkg from '../../../package.json';
|
||||
|
||||
// Extract version information
|
||||
const currentVersionNum = pkg.version as string;
|
||||
const matches = currentVersionNum.match(/^([1-9]+)\.([0-9]+)\.([0-9]+)$/)!;
|
||||
|
||||
export const CURRENT_MAJOR_VERSION = matches[1];
|
||||
export const NEXT_MAJOR_VERSION = (parseInt(CURRENT_MAJOR_VERSION, 10) + 1).toString();
|
32
x-pack/plugins/upgrade_assistant/index.ts
Normal file
32
x-pack/plugins/upgrade_assistant/index.ts
Normal 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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { Server } from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { resolve } from 'path';
|
||||
import { initServer } from './server';
|
||||
|
||||
export function upgradeAssistant(kibana: any) {
|
||||
return new kibana.Plugin({
|
||||
id: 'upgrade_assistant',
|
||||
require: ['elasticsearch'],
|
||||
uiExports: {
|
||||
managementSections: ['plugins/upgrade_assistant'],
|
||||
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
|
||||
},
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
|
||||
config() {
|
||||
return Joi.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
}).default();
|
||||
},
|
||||
|
||||
init(server: Server) {
|
||||
// Add server routes and initialize the plugin here
|
||||
initServer(server);
|
||||
},
|
||||
});
|
||||
}
|
4
x-pack/plugins/upgrade_assistant/public/_app.scss
Normal file
4
x-pack/plugins/upgrade_assistant/public/_app.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
upgrade-assistant {
|
||||
flex-grow: 1;
|
||||
background-color: $euiColorLightestShade;
|
||||
}
|
36
x-pack/plugins/upgrade_assistant/public/app.tsx
Normal file
36
x-pack/plugins/upgrade_assistant/public/app.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 { EuiPage, EuiPageBody, EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui';
|
||||
import { FormattedMessage, injectI18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
import { NEXT_MAJOR_VERSION } from '../common/version';
|
||||
import { UpgradeAssistantTabs } from './components/tabs';
|
||||
|
||||
export const RootComponentUI: React.StatelessComponent = () => (
|
||||
<EuiPage restrictWidth data-test-subj="upgradeAssistantRoot">
|
||||
<EuiPageBody>
|
||||
<EuiPageHeader>
|
||||
<EuiPageHeaderSection>
|
||||
<EuiTitle size="l">
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.appTitle"
|
||||
defaultMessage="{version} Upgrade Assistant"
|
||||
values={{ version: `${NEXT_MAJOR_VERSION}.0` }}
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageHeaderSection>
|
||||
</EuiPageHeader>
|
||||
<UpgradeAssistantTabs />
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
);
|
||||
|
||||
export const RootComponent = injectI18nProvider(RootComponentUI);
|
|
@ -0,0 +1,2 @@
|
|||
@import './tabs/checkup/index';
|
||||
@import './tabs/overview/index';
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 { EuiCallOut, EuiLink } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../common/version';
|
||||
|
||||
export const LatestMinorBanner: React.StatelessComponent = () => (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.tabs.incompleteCallout.calloutTitle"
|
||||
defaultMessage="Issues list might be incomplete"
|
||||
/>
|
||||
}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.calloutDetail"
|
||||
defaultMessage="The complete list of {breakingChangesDocButton} in Elasticsearch {nextEsVersion}
|
||||
will be available in the final {currentEsVersion} minor release. When the list
|
||||
is complete, this warning will go away."
|
||||
values={{
|
||||
breakingChangesDocButton: (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes.html"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.breackingChangesDocButtonLabel"
|
||||
defaultMessage="deprecations and breaking changes"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
nextEsVersion: `${NEXT_MAJOR_VERSION}.x`,
|
||||
currentEsVersion: `${CURRENT_MAJOR_VERSION}.x`,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
);
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
jest.mock('axios', () => ({
|
||||
get: jest.fn(),
|
||||
}));
|
||||
|
||||
import { UpgradeAssistantTabs } from './tabs';
|
||||
import { LoadingState } from './types';
|
||||
|
||||
import axios from 'axios';
|
||||
import { OverviewTab } from './tabs/overview';
|
||||
|
||||
// Used to wait for promises to resolve and renders to finish before reading updates
|
||||
const promisesToResolve = () => new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
describe('UpgradeAssistantTabs', () => {
|
||||
test('renders loading state', async () => {
|
||||
// @ts-ignore
|
||||
axios.get.mockReturnValue(
|
||||
new Promise(resolve => {
|
||||
/* never resolve */
|
||||
})
|
||||
);
|
||||
const wrapper = mountWithIntl(<UpgradeAssistantTabs />);
|
||||
// Should pass down loading status to child component
|
||||
expect(wrapper.find(OverviewTab).prop('loadingState')).toEqual(LoadingState.Loading);
|
||||
});
|
||||
|
||||
test('successful data fetch', async () => {
|
||||
// @ts-ignore
|
||||
axios.get.mockResolvedValue({
|
||||
data: {
|
||||
cluster: [],
|
||||
indices: [],
|
||||
},
|
||||
});
|
||||
const wrapper = mountWithIntl(<UpgradeAssistantTabs />);
|
||||
expect(axios.get).toHaveBeenCalled();
|
||||
await promisesToResolve();
|
||||
wrapper.update();
|
||||
// Should pass down success status to child component
|
||||
expect(wrapper.find(OverviewTab).prop('loadingState')).toEqual(LoadingState.Success);
|
||||
});
|
||||
|
||||
test('network failure', async () => {
|
||||
// @ts-ignore
|
||||
axios.get.mockRejectedValue(new Error(`oh no!`));
|
||||
const wrapper = mountWithIntl(<UpgradeAssistantTabs />);
|
||||
await promisesToResolve();
|
||||
wrapper.update();
|
||||
// Should pass down error status to child component
|
||||
expect(wrapper.find(OverviewTab).prop('loadingState')).toEqual(LoadingState.Error);
|
||||
});
|
||||
});
|
145
x-pack/plugins/upgrade_assistant/public/components/tabs.tsx
Normal file
145
x-pack/plugins/upgrade_assistant/public/components/tabs.tsx
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* 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 axios from 'axios';
|
||||
import { findIndex } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiTabbedContent, EuiTabbedContentTab } from '@elastic/eui';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
import { UpgradeAssistantStatus } from '../../server/lib/es_migration_apis';
|
||||
import { LatestMinorBanner } from './latest_minor_banner';
|
||||
import { CheckupTab } from './tabs/checkup';
|
||||
import { OverviewTab } from './tabs/overview';
|
||||
import { LoadingState, UpgradeAssistantTabProps } from './types';
|
||||
|
||||
interface TabsState {
|
||||
loadingState: LoadingState;
|
||||
checkupData?: UpgradeAssistantStatus;
|
||||
selectedTabIndex: number;
|
||||
}
|
||||
|
||||
export class UpgradeAssistantTabsUI extends React.Component<
|
||||
ReactIntl.InjectedIntlProps,
|
||||
TabsState
|
||||
> {
|
||||
constructor(props: ReactIntl.InjectedIntlProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loadingState: LoadingState.Loading,
|
||||
selectedTabIndex: 0,
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { selectedTabIndex } = this.state;
|
||||
const tabs = this.tabs;
|
||||
|
||||
return (
|
||||
<EuiTabbedContent
|
||||
tabs={tabs}
|
||||
onTabClick={this.onTabClick}
|
||||
selectedTab={tabs[selectedTabIndex]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private onTabClick = (selectedTab: EuiTabbedContentTab) => {
|
||||
const selectedTabIndex = findIndex(this.tabs, { id: selectedTab.id });
|
||||
if (selectedTabIndex === -1) {
|
||||
throw new Error(`Clicked tab did not exist in tabs array`);
|
||||
}
|
||||
|
||||
this.setSelectedTabIndex(selectedTabIndex);
|
||||
};
|
||||
|
||||
private setSelectedTabIndex = (selectedTabIndex: number) => {
|
||||
this.setState({ selectedTabIndex });
|
||||
};
|
||||
|
||||
private loadData = async () => {
|
||||
try {
|
||||
this.setState({ loadingState: LoadingState.Loading });
|
||||
const resp = await axios.get(chrome.addBasePath('/api/upgrade_assistant/status'));
|
||||
this.setState({
|
||||
loadingState: LoadingState.Success,
|
||||
checkupData: resp.data,
|
||||
});
|
||||
} catch (e) {
|
||||
this.setState({ loadingState: LoadingState.Error });
|
||||
}
|
||||
};
|
||||
|
||||
private get tabs() {
|
||||
const { intl } = this.props;
|
||||
const { loadingState, checkupData } = this.state;
|
||||
const commonProps: UpgradeAssistantTabProps = {
|
||||
loadingState,
|
||||
refreshCheckupData: this.loadData,
|
||||
setSelectedTabIndex: this.setSelectedTabIndex,
|
||||
// Remove this in last minor of the current major (eg. 6.7)
|
||||
alertBanner: <LatestMinorBanner />,
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'overview',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.overviewTab.overviewTabTitle',
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
content: <OverviewTab checkupData={checkupData} {...commonProps} />,
|
||||
},
|
||||
{
|
||||
id: 'cluster',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.clusterTabLabel',
|
||||
defaultMessage: 'Cluster',
|
||||
}),
|
||||
content: (
|
||||
<CheckupTab
|
||||
key="cluster"
|
||||
deprecations={checkupData ? checkupData.cluster : undefined}
|
||||
checkupLabel={intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.tabs.checkupTab.clusterLabel',
|
||||
defaultMessage: 'cluster',
|
||||
})}
|
||||
{...commonProps}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'indices',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.indicesTabLabel',
|
||||
defaultMessage: 'Indices',
|
||||
}),
|
||||
content: (
|
||||
<CheckupTab
|
||||
key="indices"
|
||||
deprecations={checkupData ? checkupData.indices : undefined}
|
||||
checkupLabel={intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.indexLabel',
|
||||
defaultMessage: 'index',
|
||||
})}
|
||||
showBackupWarning
|
||||
{...commonProps}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export const UpgradeAssistantTabs = injectI18n(UpgradeAssistantTabsUI);
|
|
@ -0,0 +1,870 @@
|
|||
{
|
||||
"cluster": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 3",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 3 4",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 3 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 1 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 1 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead 0 1 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings 0 1 2 3 4 5",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
}
|
||||
],
|
||||
"nodes": [],
|
||||
"indices": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]",
|
||||
"index": ".monitoring-es-6-2018.11.07"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]",
|
||||
"index": ".kibana"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]",
|
||||
"index": ".watcher-history-6-2018.11.07"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: snapshot]]",
|
||||
"index": ".monitoring-kibana-6-2018.11.07"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter2"
|
||||
},
|
||||
{
|
||||
"index": "twitter",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"actions": [
|
||||
{
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter.json"
|
||||
}
|
||||
],
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html"
|
||||
},
|
||||
{
|
||||
"index": ".triggered_watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html"
|
||||
},
|
||||
{
|
||||
"index": ".reindex-status",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"actions": [
|
||||
{
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2F.reindex-status.json"
|
||||
}
|
||||
],
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html"
|
||||
},
|
||||
{
|
||||
"index": "twitter2",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"actions": [
|
||||
{
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter2.json"
|
||||
}
|
||||
],
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html"
|
||||
},
|
||||
{
|
||||
"index": ".watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,518 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CheckupTab render with deprecations 1`] = `
|
||||
<React.Fragment>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<EuiText
|
||||
grow={false}
|
||||
size="m"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="These {strongCheckupLabel} issues need your attention. Resolve them before upgrading to Elasticsearch {nextEsVersion}."
|
||||
id="xpack.upgradeAssistant.checkupTab.tabDetail"
|
||||
values={
|
||||
Object {
|
||||
"nextEsVersion": "8.x",
|
||||
"strongCheckupLabel": <strong>
|
||||
index
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<React.Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your indices now"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your data using the {snapshotRestoreDocsButton}."
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail"
|
||||
values={
|
||||
Object {
|
||||
"snapshotRestoreDocsButton": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="snapshot and restore APIs"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<EuiPageContent
|
||||
panelPaddingSize="l"
|
||||
>
|
||||
<EuiPageContentBody>
|
||||
<React.Fragment>
|
||||
<InjectIntl(Component)
|
||||
allDeprecations={
|
||||
Array [
|
||||
Object {
|
||||
"details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]",
|
||||
"index": ".monitoring-es-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]",
|
||||
"index": ".kibana",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]",
|
||||
"index": ".watcher-history-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: snapshot]]",
|
||||
"index": ".monitoring-kibana-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter2",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": "twitter",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".triggered_watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2F.reindex-status.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".reindex-status",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter2.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": "twitter2",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html",
|
||||
},
|
||||
]
|
||||
}
|
||||
availableGroupByOptions={
|
||||
Array [
|
||||
"message",
|
||||
"index",
|
||||
]
|
||||
}
|
||||
currentFilter="all"
|
||||
currentGroupBy="message"
|
||||
loadData={[MockFunction]}
|
||||
loadingState={1}
|
||||
onFilterChange={[Function]}
|
||||
onGroupByChange={[Function]}
|
||||
onSearchChange={[Function]}
|
||||
search=""
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<GroupedDeprecations
|
||||
allDeprecations={
|
||||
Array [
|
||||
Object {
|
||||
"details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]",
|
||||
"index": ".monitoring-es-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]",
|
||||
"index": ".kibana",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]",
|
||||
"index": ".watcher-history-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: snapshot]]",
|
||||
"index": ".monitoring-kibana-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter2",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": "twitter",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".triggered_watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2F.reindex-status.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".reindex-status",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Reindex in Console",
|
||||
"url": "/app/kibana#/dev_tools/console?load_from=%2Fapi%2Fupgrade_assistant%2Freindex%2Fconsole_template%2Ftwitter2.json",
|
||||
},
|
||||
],
|
||||
"details": "Reindexing is irreversible, so always back up your index before proceeding.",
|
||||
"index": "twitter2",
|
||||
"level": "critical",
|
||||
"message": "This index must be reindexed in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade.html",
|
||||
},
|
||||
Object {
|
||||
"details": "Upgrading is irreversible, so always back up your index before proceeding.",
|
||||
"index": ".watches",
|
||||
"level": "critical",
|
||||
"message": "This index must be upgraded in order to upgrade the Elastic Stack.",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html",
|
||||
},
|
||||
]
|
||||
}
|
||||
currentFilter="all"
|
||||
currentGroupBy="message"
|
||||
search=""
|
||||
/>
|
||||
</React.Fragment>
|
||||
</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CheckupTab render with error 1`] = `
|
||||
<React.Fragment>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<EuiText
|
||||
grow={false}
|
||||
size="m"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="These {strongCheckupLabel} issues need your attention. Resolve them before upgrading to Elasticsearch {nextEsVersion}."
|
||||
id="xpack.upgradeAssistant.checkupTab.tabDetail"
|
||||
values={
|
||||
Object {
|
||||
"nextEsVersion": "8.x",
|
||||
"strongCheckupLabel": <strong>
|
||||
index
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<React.Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your indices now"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your data using the {snapshotRestoreDocsButton}."
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail"
|
||||
values={
|
||||
Object {
|
||||
"snapshotRestoreDocsButton": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="snapshot and restore APIs"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<EuiPageContent
|
||||
panelPaddingSize="l"
|
||||
>
|
||||
<EuiPageContentBody>
|
||||
<EuiCallOut
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="A network error occurred while retrieving the checkup results."
|
||||
id="xpack.upgradeAssistant.checkupTab.errorCallout.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
</React.Fragment>
|
||||
`;
|
||||
|
||||
exports[`CheckupTab render without deprecations 1`] = `
|
||||
<React.Fragment>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<EuiText
|
||||
grow={false}
|
||||
size="m"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="These {strongCheckupLabel} issues need your attention. Resolve them before upgrading to Elasticsearch {nextEsVersion}."
|
||||
id="xpack.upgradeAssistant.checkupTab.tabDetail"
|
||||
values={
|
||||
Object {
|
||||
"nextEsVersion": "8.x",
|
||||
"strongCheckupLabel": <strong>
|
||||
index
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
<React.Fragment>
|
||||
<EuiCallOut
|
||||
color="warning"
|
||||
iconType="help"
|
||||
size="m"
|
||||
title={
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your indices now"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Back up your data using the {snapshotRestoreDocsButton}."
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail"
|
||||
values={
|
||||
Object {
|
||||
"snapshotRestoreDocsButton": <EuiLink
|
||||
color="primary"
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"
|
||||
target="_blank"
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="snapshot and restore APIs"
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer
|
||||
size="l"
|
||||
/>
|
||||
</React.Fragment>
|
||||
<EuiPageContent
|
||||
panelPaddingSize="l"
|
||||
>
|
||||
<EuiPageContentBody>
|
||||
<EuiEmptyPrompt
|
||||
body={
|
||||
<React.Fragment>
|
||||
<p
|
||||
data-test-subj="upgradeAssistantIssueSummary"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="You have no {strongCheckupLabel} issues."
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.noIssuesLabel"
|
||||
values={
|
||||
Object {
|
||||
"strongCheckupLabel": <strong>
|
||||
index
|
||||
</strong>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
defaultMessage="Check the {overviewTabButton} for next steps."
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.nextStepsDetail"
|
||||
values={
|
||||
Object {
|
||||
"overviewTabButton": <EuiLink
|
||||
color="primary"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Overview tab"
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.nextStepsDetail.overviewTabButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
iconColor="subdued"
|
||||
iconType="faceHappy"
|
||||
title={
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
defaultMessage="All clear!"
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.noIssuesTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
}
|
||||
/>
|
||||
</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
</React.Fragment>
|
||||
`;
|
|
@ -0,0 +1,35 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FilterBar renders 1`] = `
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFilterGroup>
|
||||
<EuiFilterButton
|
||||
color="text"
|
||||
grow={false}
|
||||
hasActiveFilters={false}
|
||||
iconSide="right"
|
||||
key="all"
|
||||
numFilters={2}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
all
|
||||
</EuiFilterButton>
|
||||
<EuiFilterButton
|
||||
color="text"
|
||||
grow={false}
|
||||
hasActiveFilters={true}
|
||||
iconSide="right"
|
||||
key="critical"
|
||||
numFilters={2}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
critical
|
||||
</EuiFilterButton>
|
||||
</EuiFilterGroup>
|
||||
</EuiFlexItem>
|
||||
`;
|
|
@ -0,0 +1,33 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`GroupByBar renders 1`] = `
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFilterGroup>
|
||||
<EuiFilterButton
|
||||
color="text"
|
||||
grow={false}
|
||||
hasActiveFilters={true}
|
||||
iconSide="right"
|
||||
key="message"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
by issue
|
||||
</EuiFilterButton>
|
||||
<EuiFilterButton
|
||||
color="text"
|
||||
grow={false}
|
||||
hasActiveFilters={false}
|
||||
iconSide="right"
|
||||
key="index"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
by index
|
||||
</EuiFilterButton>
|
||||
</EuiFilterGroup>
|
||||
</EuiFlexItem>
|
||||
`;
|
|
@ -0,0 +1 @@
|
|||
@import './deprecations/index';
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { LoadingState } from '../../types';
|
||||
import AssistanceData from '../__fixtures__/checkup_api_response.json';
|
||||
import { CheckupTab } from './checkup_tab';
|
||||
|
||||
const defaultProps = {
|
||||
checkupLabel: 'index',
|
||||
deprecations: AssistanceData.indices,
|
||||
showBackupWarning: true,
|
||||
refreshCheckupData: jest.fn(),
|
||||
loadingState: LoadingState.Success,
|
||||
setSelectedTabIndex: jest.fn(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Mostly a dumb container with copy, test the three main states.
|
||||
*/
|
||||
describe('CheckupTab', () => {
|
||||
test('render with deprecations', () => {
|
||||
expect(shallow(<CheckupTab {...defaultProps} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render without deprecations', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<CheckupTab
|
||||
{...{ ...defaultProps, deprecations: undefined, loadingState: LoadingState.Loading }}
|
||||
/>
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('render with error', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<CheckupTab
|
||||
{...{ ...defaultProps, deprecations: undefined, loadingState: LoadingState.Error }}
|
||||
/>
|
||||
)
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* 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 { find } from 'lodash';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import {
|
||||
// @ts-ignore
|
||||
EuiAccordion,
|
||||
EuiCallOut,
|
||||
EuiEmptyPrompt,
|
||||
EuiLink,
|
||||
EuiPageContent,
|
||||
EuiPageContentBody,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { NEXT_MAJOR_VERSION } from '../../../../common/version';
|
||||
import {
|
||||
GroupByOption,
|
||||
LevelFilterOption,
|
||||
LoadingState,
|
||||
UpgradeAssistantTabComponent,
|
||||
UpgradeAssistantTabProps,
|
||||
} from '../../types';
|
||||
import { CheckupControls } from './controls';
|
||||
import { GroupedDeprecations } from './deprecations/grouped';
|
||||
|
||||
interface CheckupTabProps extends UpgradeAssistantTabProps {
|
||||
checkupLabel: string;
|
||||
showBackupWarning?: boolean;
|
||||
}
|
||||
|
||||
interface CheckupTabState {
|
||||
currentFilter: LevelFilterOption;
|
||||
search: string;
|
||||
currentGroupBy: GroupByOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a list of deprecations that filterable and groupable. Can be used for cluster,
|
||||
* nodes, or indices checkups.
|
||||
*/
|
||||
export class CheckupTab extends UpgradeAssistantTabComponent<CheckupTabProps, CheckupTabState> {
|
||||
constructor(props: CheckupTabProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
// initialize to all filters
|
||||
currentFilter: LevelFilterOption.all,
|
||||
search: '',
|
||||
currentGroupBy: GroupByOption.message,
|
||||
};
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {
|
||||
alertBanner,
|
||||
checkupLabel,
|
||||
deprecations,
|
||||
loadingState,
|
||||
refreshCheckupData,
|
||||
setSelectedTabIndex,
|
||||
showBackupWarning = false,
|
||||
} = this.props;
|
||||
const { currentFilter, search, currentGroupBy } = this.state;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiSpacer />
|
||||
<EuiText grow={false}>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.tabDetail"
|
||||
defaultMessage="These {strongCheckupLabel} issues need your attention. Resolve them before upgrading to Elasticsearch {nextEsVersion}."
|
||||
values={{
|
||||
strongCheckupLabel: <strong>{checkupLabel}</strong>,
|
||||
nextEsVersion: `${NEXT_MAJOR_VERSION}.x`,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
{alertBanner && (
|
||||
<Fragment>
|
||||
{alertBanner}
|
||||
<EuiSpacer />
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
{showBackupWarning && (
|
||||
<Fragment>
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutTitle"
|
||||
defaultMessage="Back up your indices now"
|
||||
/>
|
||||
}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail"
|
||||
defaultMessage="Back up your data using the {snapshotRestoreDocsButton}."
|
||||
values={{
|
||||
snapshotRestoreDocsButton: (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel"
|
||||
defaultMessage="snapshot and restore APIs"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer />
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
<EuiPageContent>
|
||||
<EuiPageContentBody>
|
||||
{loadingState === LoadingState.Error ? (
|
||||
<EuiCallOut
|
||||
title={
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.errorCallout.calloutTitle"
|
||||
defaultMessage="A network error occurred while retrieving the checkup results."
|
||||
/>
|
||||
}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
/>
|
||||
) : deprecations && deprecations.length > 0 ? (
|
||||
<Fragment>
|
||||
<CheckupControls
|
||||
allDeprecations={deprecations}
|
||||
loadingState={loadingState}
|
||||
loadData={refreshCheckupData}
|
||||
currentFilter={currentFilter}
|
||||
onFilterChange={this.changeFilter}
|
||||
search={search}
|
||||
onSearchChange={this.changeSearch}
|
||||
availableGroupByOptions={this.availableGroupByOptions()}
|
||||
currentGroupBy={currentGroupBy}
|
||||
onGroupByChange={this.changeGroupBy}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
{this.renderCheckupData()}
|
||||
</Fragment>
|
||||
) : (
|
||||
<EuiEmptyPrompt
|
||||
iconType="faceHappy"
|
||||
title={
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.noIssuesTitle"
|
||||
defaultMessage="All clear!"
|
||||
/>
|
||||
</h2>
|
||||
}
|
||||
body={
|
||||
<Fragment>
|
||||
<p data-test-subj="upgradeAssistantIssueSummary">
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.noIssuesLabel"
|
||||
defaultMessage="You have no {strongCheckupLabel} issues."
|
||||
values={{
|
||||
strongCheckupLabel: <strong>{checkupLabel}</strong>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.nextStepsDetail"
|
||||
defaultMessage="Check the {overviewTabButton} for next steps."
|
||||
values={{
|
||||
overviewTabButton: (
|
||||
<EuiLink onClick={() => setSelectedTabIndex(0)}>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.noIssues.nextStepsDetail.overviewTabButtonLabel"
|
||||
defaultMessage="Overview tab"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
private changeFilter = (filter: LevelFilterOption) => {
|
||||
this.setState({ currentFilter: filter });
|
||||
};
|
||||
|
||||
private changeSearch = (search: string) => {
|
||||
this.setState({ search });
|
||||
};
|
||||
|
||||
private changeGroupBy = (groupBy: GroupByOption) => {
|
||||
this.setState({ currentGroupBy: groupBy });
|
||||
};
|
||||
|
||||
private availableGroupByOptions() {
|
||||
const { deprecations } = this.props;
|
||||
|
||||
if (!deprecations) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object.keys(GroupByOption).filter(opt => find(deprecations, opt)) as GroupByOption[];
|
||||
}
|
||||
|
||||
private renderCheckupData() {
|
||||
const { deprecations } = this.props;
|
||||
const { currentFilter, currentGroupBy, search } = this.state;
|
||||
|
||||
return (
|
||||
<GroupedDeprecations
|
||||
currentGroupBy={currentGroupBy}
|
||||
currentFilter={currentFilter}
|
||||
search={search}
|
||||
allDeprecations={deprecations}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
||||
import { IconColor } from '@elastic/eui';
|
||||
import { invert } from 'lodash';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
|
||||
export const LEVEL_MAP: { [level: string]: number } = {
|
||||
warning: 0,
|
||||
critical: 1,
|
||||
};
|
||||
|
||||
export const REVERSE_LEVEL_MAP: { [idx: number]: DeprecationInfo['level'] } = invert(LEVEL_MAP);
|
||||
|
||||
export const COLOR_MAP: { [level: string]: IconColor } = {
|
||||
warning: 'default',
|
||||
critical: 'danger',
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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, { StatelessComponent } from 'react';
|
||||
|
||||
import { EuiButton, EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { GroupByOption, LevelFilterOption, LoadingState } from '../../types';
|
||||
import { FilterBar } from './filter_bar';
|
||||
import { GroupByBar } from './group_by_bar';
|
||||
|
||||
interface CheckupControlsProps extends ReactIntl.InjectedIntlProps {
|
||||
allDeprecations?: DeprecationInfo[];
|
||||
loadingState: LoadingState;
|
||||
loadData: () => void;
|
||||
currentFilter: LevelFilterOption;
|
||||
onFilterChange: (filter: LevelFilterOption) => void;
|
||||
search: string;
|
||||
onSearchChange: (filter: string) => void;
|
||||
availableGroupByOptions: GroupByOption[];
|
||||
currentGroupBy: GroupByOption;
|
||||
onGroupByChange: (groupBy: GroupByOption) => void;
|
||||
}
|
||||
|
||||
export const CheckupControlsUI: StatelessComponent<CheckupControlsProps> = ({
|
||||
allDeprecations,
|
||||
loadingState,
|
||||
loadData,
|
||||
currentFilter,
|
||||
onFilterChange,
|
||||
search,
|
||||
onSearchChange,
|
||||
availableGroupByOptions,
|
||||
currentGroupBy,
|
||||
onGroupByChange,
|
||||
intl,
|
||||
}) => (
|
||||
<EuiFlexGroup alignItems="center" wrap={true} responsive={false}>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiFieldSearch
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.controls.searchBarPlaceholder',
|
||||
defaultMessage: 'Filter',
|
||||
})}
|
||||
value={search}
|
||||
onChange={e => onSearchChange(e.target.value)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
|
||||
{/* These two components provide their own EuiFlexItem wrappers */}
|
||||
<FilterBar {...{ allDeprecations, currentFilter, onFilterChange }} />
|
||||
<GroupByBar {...{ availableGroupByOptions, currentGroupBy, onGroupByChange }} />
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
onClick={loadData}
|
||||
iconType="refresh"
|
||||
isLoading={loadingState === LoadingState.Loading}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.controls.refreshButtonLabel"
|
||||
defaultMessage="Refresh"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
export const CheckupControls = injectI18n(CheckupControlsUI);
|
|
@ -0,0 +1,4 @@
|
|||
.upgDeprecationCell {
|
||||
overflow: hidden;
|
||||
padding: $euiSize 0 0 $euiSizeL;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
@import './cell';
|
||||
|
||||
.upgDeprecations {
|
||||
// Pull the container through the padding of EuiPageContent
|
||||
margin-left: -$euiSizeL;
|
||||
margin-right: -$euiSizeL;
|
||||
}
|
||||
|
||||
.upgDeprecations__item {
|
||||
padding: $euiSize $euiSizeL;
|
||||
border-top: $euiBorderThin;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: -$euiSizeL;
|
||||
}
|
||||
}
|
||||
|
||||
.upgDeprecations__itemName {
|
||||
font-weight: $euiFontWeightMedium;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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, { ReactNode, StatelessComponent } from 'react';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIcon,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
interface DeprecationCellProps {
|
||||
items?: Array<{ title?: string; body: string }>;
|
||||
docUrl?: string;
|
||||
headline?: string;
|
||||
healthColor?: string;
|
||||
actions?: Array<{
|
||||
label: string;
|
||||
url: string;
|
||||
}>;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to display a deprecation with links to docs, a health indicator, and other descriptive information.
|
||||
*/
|
||||
export const DeprecationCell: StatelessComponent<DeprecationCellProps> = ({
|
||||
headline,
|
||||
healthColor,
|
||||
actions,
|
||||
docUrl,
|
||||
items = [],
|
||||
children,
|
||||
}) => (
|
||||
<div className="upgDeprecationCell">
|
||||
<EuiFlexGroup responsive={false} wrap alignItems="baseline">
|
||||
{healthColor && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="dot" color={healthColor} />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
|
||||
<EuiFlexItem grow>
|
||||
{headline && (
|
||||
<EuiTitle size="xxs">
|
||||
<h2>{headline}</h2>
|
||||
</EuiTitle>
|
||||
)}
|
||||
|
||||
{docUrl && (
|
||||
<div>
|
||||
<EuiLink href={docUrl} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.deprecations.documentationButtonLabel"
|
||||
defaultMessage="Documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
<EuiSpacer size="s" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{items.map(item => (
|
||||
<div key={item.title || item.body}>
|
||||
<EuiText>
|
||||
{item.title && <h6>{item.title}</h6>}
|
||||
<p>{item.body}</p>
|
||||
</EuiText>
|
||||
</div>
|
||||
))}
|
||||
</EuiFlexItem>
|
||||
|
||||
{actions &&
|
||||
actions.map(button => (
|
||||
<EuiFlexItem key={button.url} grow={false}>
|
||||
<EuiButton size="s" href={button.url} target="_blank">
|
||||
{button.label}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
{children}
|
||||
</div>
|
||||
);
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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, { Fragment, StatelessComponent } from 'react';
|
||||
|
||||
import { EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { EnrichedDeprecationInfo } from '../../../../../server/lib/es_migration_apis';
|
||||
|
||||
export const DeprecationCountSummary: StatelessComponent<{
|
||||
deprecations: EnrichedDeprecationInfo[];
|
||||
allDeprecations: EnrichedDeprecationInfo[];
|
||||
}> = ({ deprecations, allDeprecations }) => (
|
||||
<EuiText size="s">
|
||||
{allDeprecations.length ? (
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.numDeprecationsShownLabel"
|
||||
defaultMessage="Showing {numShown} of {total}"
|
||||
values={{ numShown: deprecations.length, total: allDeprecations.length }}
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.noDeprecationsLabel"
|
||||
defaultMessage="No deprecations"
|
||||
/>
|
||||
)}
|
||||
{deprecations.length !== allDeprecations.length && (
|
||||
<Fragment>
|
||||
{'. '}
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.changeFiltersShowMoreLabel"
|
||||
description="Explains how to show all deprecations if there are more available."
|
||||
defaultMessage="Change filter to show more."
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
</EuiText>
|
||||
);
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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 { range } from 'lodash';
|
||||
import React from 'react';
|
||||
import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import { EuiBadge, EuiPagination } from '@elastic/eui';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { EnrichedDeprecationInfo } from '../../../../../server/lib/es_migration_apis';
|
||||
import { GroupByOption, LevelFilterOption } from '../../../types';
|
||||
import { DeprecationAccordion, filterDeps, GroupedDeprecations } from './grouped';
|
||||
|
||||
describe('filterDeps', () => {
|
||||
test('filters on levels', () => {
|
||||
const fd = filterDeps(LevelFilterOption.critical);
|
||||
expect(fd({ level: 'critical' } as DeprecationInfo)).toBe(true);
|
||||
expect(fd({ level: 'warning' } as DeprecationInfo)).toBe(false);
|
||||
});
|
||||
|
||||
test('filters on search', () => {
|
||||
const fd = filterDeps(LevelFilterOption.critical, 'wow');
|
||||
expect(fd({ level: 'critical', message: 'the wow error' } as DeprecationInfo)).toBe(true);
|
||||
expect(fd({ level: 'critical', message: 'other error' } as DeprecationInfo)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GroupedDeprecations', () => {
|
||||
const defaultProps = {
|
||||
currentFilter: LevelFilterOption.all,
|
||||
search: '',
|
||||
currentGroupBy: GroupByOption.message,
|
||||
allDeprecations: [
|
||||
{ message: 'Cluster error 1', url: '', level: 'warning' },
|
||||
{ message: 'Cluster error 2', url: '', level: 'critical' },
|
||||
] as EnrichedDeprecationInfo[],
|
||||
};
|
||||
|
||||
describe('expand + collapse all', () => {
|
||||
const expectNumOpen = (wrapper: any, numExpected: number) =>
|
||||
expect(wrapper.find('div.euiAccordion-isOpen')).toHaveLength(numExpected);
|
||||
|
||||
test('clicking opens and closes panels', () => {
|
||||
const wrapper = mountWithIntl(<GroupedDeprecations {...defaultProps} />);
|
||||
expectNumOpen(wrapper, 0);
|
||||
|
||||
// Test expand all
|
||||
wrapper.find('button[data-test-subj="expandAll"]').simulate('click');
|
||||
expectNumOpen(wrapper, 2);
|
||||
|
||||
// Test collapse all
|
||||
wrapper.find('button[data-test-subj="collapseAll"]').simulate('click');
|
||||
expectNumOpen(wrapper, 0);
|
||||
});
|
||||
|
||||
test('clicking overrides current state when some are open', () => {
|
||||
const wrapper = mountWithIntl(<GroupedDeprecations {...defaultProps} />);
|
||||
|
||||
// Open a single deprecation
|
||||
wrapper
|
||||
.find('button.euiAccordion__button')
|
||||
.first()
|
||||
.simulate('click');
|
||||
expectNumOpen(wrapper, 1);
|
||||
|
||||
// Test expand all
|
||||
wrapper.find('button[data-test-subj="expandAll"]').simulate('click');
|
||||
expectNumOpen(wrapper, 2);
|
||||
|
||||
// Close a single deprecation
|
||||
wrapper
|
||||
.find('button.euiAccordion__button')
|
||||
.first()
|
||||
.simulate('click');
|
||||
expectNumOpen(wrapper, 1);
|
||||
|
||||
// Test collapse all
|
||||
wrapper.find('button[data-test-subj="collapseAll"]').simulate('click');
|
||||
expectNumOpen(wrapper, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pagination', () => {
|
||||
const paginationProps = {
|
||||
...defaultProps,
|
||||
allDeprecations: range(0, 40).map(i => ({
|
||||
message: `Message ${i}`,
|
||||
level: 'warning',
|
||||
})) as DeprecationInfo[],
|
||||
};
|
||||
|
||||
test('it only displays 25 items', () => {
|
||||
const wrapper = shallowWithIntl(<GroupedDeprecations {...paginationProps} />);
|
||||
expect(wrapper.find(DeprecationAccordion)).toHaveLength(25);
|
||||
});
|
||||
|
||||
test('it displays pagination', () => {
|
||||
const wrapper = shallowWithIntl(<GroupedDeprecations {...paginationProps} />);
|
||||
expect(wrapper.find(EuiPagination).exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('shows next page on click', () => {
|
||||
const wrapper = mountWithIntl(<GroupedDeprecations {...paginationProps} />);
|
||||
wrapper.find('button[data-test-subj="pagination-button-next"]').simulate('click');
|
||||
expect(wrapper.find(DeprecationAccordion)).toHaveLength(15); // 40 total - 25 first page = 15 second page
|
||||
});
|
||||
});
|
||||
|
||||
describe('grouping', () => {
|
||||
test('group by message', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<GroupedDeprecations
|
||||
{...defaultProps}
|
||||
currentGroupBy={GroupByOption.message}
|
||||
allDeprecations={[
|
||||
{ message: 'Cluster error 1', url: '', level: 'warning' },
|
||||
{ message: 'Cluster error 2', url: '', level: 'warning' },
|
||||
{ message: 'Cluster error 2', url: '', level: 'warning' },
|
||||
{ message: 'Cluster error 2', url: '', level: 'warning' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
// Only 2 groups should exist b/c there are only 2 unique messages
|
||||
expect(wrapper.find(DeprecationAccordion)).toHaveLength(2);
|
||||
});
|
||||
|
||||
test('group by index', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<GroupedDeprecations
|
||||
{...defaultProps}
|
||||
currentGroupBy={GroupByOption.index}
|
||||
allDeprecations={[
|
||||
{
|
||||
message: 'Cluster error 1',
|
||||
url: '',
|
||||
level: 'warning',
|
||||
index: 'index1',
|
||||
},
|
||||
{
|
||||
message: 'Cluster error 2',
|
||||
url: '',
|
||||
level: 'warning',
|
||||
index: 'index1',
|
||||
},
|
||||
{
|
||||
message: 'Cluster error 2',
|
||||
url: '',
|
||||
level: 'warning',
|
||||
index: 'index2',
|
||||
},
|
||||
{
|
||||
message: 'Cluster error 2',
|
||||
url: '',
|
||||
level: 'warning',
|
||||
index: 'index3',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
// Only 3 groups should exist b/c there are only 3 unique indexes
|
||||
expect(wrapper.find(DeprecationAccordion)).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('DeprecationAccordion', () => {
|
||||
const defaultProps = {
|
||||
id: 'x',
|
||||
title: 'Issue 1',
|
||||
currentGroupBy: GroupByOption.message,
|
||||
forceExpand: false,
|
||||
deprecations: [{ index: 'index1' }, { index: 'index2' }] as EnrichedDeprecationInfo[],
|
||||
};
|
||||
|
||||
test('shows indices count badge', () => {
|
||||
const wrapper = mountWithIntl(<DeprecationAccordion {...defaultProps} />);
|
||||
expect(
|
||||
wrapper
|
||||
.find(EuiBadge)
|
||||
.find('[data-test-subj="indexCount"]')
|
||||
.text()
|
||||
).toEqual('2');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* 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 { groupBy } from 'lodash';
|
||||
import React, { Fragment, StatelessComponent } from 'react';
|
||||
|
||||
import {
|
||||
EuiAccordion,
|
||||
EuiBadge,
|
||||
EuiButtonEmpty,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPagination,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { EnrichedDeprecationInfo } from '../../../../../server/lib/es_migration_apis';
|
||||
import { GroupByOption, LevelFilterOption } from '../../../types';
|
||||
|
||||
import { DeprecationCountSummary } from './count_summary';
|
||||
import { DeprecationHealth } from './health';
|
||||
import { DeprecationList } from './list';
|
||||
|
||||
// exported only for testing
|
||||
export const filterDeps = (level: LevelFilterOption, search: string = '') => {
|
||||
const conditions: Array<(dep: DeprecationInfo) => boolean> = [];
|
||||
|
||||
if (level !== LevelFilterOption.all) {
|
||||
conditions.push((dep: DeprecationInfo) => dep.level === level);
|
||||
}
|
||||
|
||||
if (search.length > 0) {
|
||||
// Change everything to lower case for a case-insensitive comparison
|
||||
conditions.push(dep => {
|
||||
try {
|
||||
const searchReg = new RegExp(search.toLowerCase());
|
||||
return Boolean(
|
||||
dep.message.toLowerCase().match(searchReg) ||
|
||||
(dep.details && dep.details.match(searchReg))
|
||||
);
|
||||
} catch (e) {
|
||||
// ignore any regexp errors.
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Return true if every condition function returns true (boolean AND)
|
||||
return (dep: DeprecationInfo) => conditions.map(c => c(dep)).every(t => t);
|
||||
};
|
||||
|
||||
/**
|
||||
* A single accordion item for a grouped deprecation item.
|
||||
*/
|
||||
export const DeprecationAccordion: StatelessComponent<{
|
||||
id: string;
|
||||
deprecations: EnrichedDeprecationInfo[];
|
||||
title: string;
|
||||
currentGroupBy: GroupByOption;
|
||||
forceExpand: boolean;
|
||||
}> = ({ id, deprecations, title, currentGroupBy, forceExpand }) => {
|
||||
const hasIndices = Boolean(
|
||||
currentGroupBy === GroupByOption.message && deprecations.filter(d => d.index).length
|
||||
);
|
||||
const numIndices = hasIndices ? deprecations.length : null;
|
||||
|
||||
return (
|
||||
<EuiAccordion
|
||||
id={id}
|
||||
className="upgDeprecations__item"
|
||||
initialIsOpen={forceExpand}
|
||||
buttonContent={<span className="upgDeprecations__itemName">{title}</span>}
|
||||
extraAction={
|
||||
<div>
|
||||
{hasIndices && (
|
||||
<Fragment>
|
||||
<EuiBadge color="hollow">
|
||||
<span data-test-subj="indexCount">{numIndices}</span>{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.indicesBadgeLabel"
|
||||
defaultMessage="{numIndices, plural, one {index} other {indices}}"
|
||||
values={{ numIndices }}
|
||||
/>
|
||||
</EuiBadge>
|
||||
 
|
||||
</Fragment>
|
||||
)}
|
||||
<DeprecationHealth
|
||||
single={currentGroupBy === GroupByOption.message}
|
||||
deprecations={deprecations}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<DeprecationList deprecations={deprecations} currentGroupBy={currentGroupBy} />
|
||||
</EuiAccordion>
|
||||
);
|
||||
};
|
||||
|
||||
interface GroupedDeprecationsProps {
|
||||
currentFilter: LevelFilterOption;
|
||||
search: string;
|
||||
currentGroupBy: GroupByOption;
|
||||
allDeprecations?: EnrichedDeprecationInfo[];
|
||||
}
|
||||
|
||||
interface GroupedDeprecationsState {
|
||||
forceExpand: true | false | null;
|
||||
expandNumber: number;
|
||||
currentPage: number;
|
||||
}
|
||||
|
||||
const PER_PAGE = 25;
|
||||
|
||||
/**
|
||||
* Collection of calculated fields based on props, extracted for reuse in
|
||||
* `render` and `getDerivedStateFromProps`.
|
||||
*/
|
||||
const CalcFields = {
|
||||
filteredDeprecations(props: GroupedDeprecationsProps) {
|
||||
const { allDeprecations = [], currentFilter, search } = props;
|
||||
return allDeprecations.filter(filterDeps(currentFilter, search));
|
||||
},
|
||||
|
||||
groups(props: GroupedDeprecationsProps) {
|
||||
const { currentGroupBy } = props;
|
||||
return groupBy(CalcFields.filteredDeprecations(props), currentGroupBy);
|
||||
},
|
||||
|
||||
numPages(props: GroupedDeprecationsProps) {
|
||||
return Math.ceil(Object.keys(CalcFields.groups(props)).length / PER_PAGE);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays groups of deprecation messages in an accordion.
|
||||
*/
|
||||
export class GroupedDeprecations extends React.Component<
|
||||
GroupedDeprecationsProps,
|
||||
GroupedDeprecationsState
|
||||
> {
|
||||
public static getDerivedStateFromProps(
|
||||
nextProps: GroupedDeprecationsProps,
|
||||
{ currentPage }: GroupedDeprecationsState
|
||||
) {
|
||||
// If filters change and the currentPage is now bigger than the num of pages we're going to show,
|
||||
// reset the current page to 0.
|
||||
if (currentPage >= CalcFields.numPages(nextProps)) {
|
||||
return { currentPage: 0 };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public state = {
|
||||
forceExpand: false,
|
||||
// `expandNumber` is used as workaround to force EuiAccordion to re-render by
|
||||
// incrementing this number (used as a key) when expand all or collapse all is clicked.
|
||||
expandNumber: 0,
|
||||
currentPage: 0,
|
||||
};
|
||||
|
||||
public render() {
|
||||
const { currentGroupBy, allDeprecations = [] } = this.props;
|
||||
const { forceExpand, expandNumber, currentPage } = this.state;
|
||||
|
||||
const filteredDeprecations = CalcFields.filteredDeprecations(this.props);
|
||||
const groups = CalcFields.groups(this.props);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiFlexGroup responsive={false} alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
flush="left"
|
||||
size="s"
|
||||
onClick={() => this.setExpand(true)}
|
||||
data-test-subj="expandAll"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.controls.expandAllButtonLabel"
|
||||
defaultMessage="Expand all"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
flush="left"
|
||||
size="s"
|
||||
onClick={() => this.setExpand(false)}
|
||||
data-test-subj="collapseAll"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.checkupTab.controls.collapseAllButtonLabel"
|
||||
defaultMessage="Collapse all"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem />
|
||||
<EuiFlexItem grow={false}>
|
||||
<DeprecationCountSummary
|
||||
allDeprecations={allDeprecations}
|
||||
deprecations={filteredDeprecations}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<div className="upgDeprecations">
|
||||
{Object.keys(groups)
|
||||
.sort()
|
||||
// Apply pagination
|
||||
.slice(currentPage * PER_PAGE, (currentPage + 1) * PER_PAGE)
|
||||
.map(groupName => [
|
||||
<DeprecationAccordion
|
||||
key={expandNumber}
|
||||
id={`depgroup-${groupName}`}
|
||||
title={groupName}
|
||||
deprecations={groups[groupName]}
|
||||
{...{ currentGroupBy, forceExpand }}
|
||||
/>,
|
||||
])}
|
||||
|
||||
{/* Only show pagination if we have more than PER_PAGE. */}
|
||||
{Object.keys(groups).length > PER_PAGE && (
|
||||
<Fragment>
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiFlexGroup justifyContent="spaceAround">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiPagination
|
||||
pageCount={CalcFields.numPages(this.props)}
|
||||
activePage={currentPage}
|
||||
onPageClick={this.setPage}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
private setExpand = (forceExpand: boolean) => {
|
||||
this.setState({ forceExpand, expandNumber: this.state.expandNumber + 1 });
|
||||
};
|
||||
|
||||
private setPage = (currentPage: number) => this.setState({ currentPage });
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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 { countBy } from 'lodash';
|
||||
import React, { StatelessComponent } from 'react';
|
||||
|
||||
import { EuiBadge, EuiToolTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { COLOR_MAP, LEVEL_MAP, REVERSE_LEVEL_MAP } from '../constants';
|
||||
|
||||
const LocalizedLevels: { [level: string]: string } = {
|
||||
warning: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.warningLabel', {
|
||||
defaultMessage: 'warning',
|
||||
}),
|
||||
critical: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.criticalLabel', {
|
||||
defaultMessage: 'critical',
|
||||
}),
|
||||
};
|
||||
|
||||
export const LocalizedActions: { [level: string]: string } = {
|
||||
warning: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.warningActionTooltip', {
|
||||
defaultMessage: 'Resolving this issue before upgrading is advised, but not required.',
|
||||
}),
|
||||
critical: i18n.translate('xpack.upgradeAssistant.checkupTab.deprecations.criticalActionTooltip', {
|
||||
defaultMessage: 'Resolve this issue before upgrading.',
|
||||
}),
|
||||
};
|
||||
|
||||
interface DeprecationHealthProps {
|
||||
deprecations: DeprecationInfo[];
|
||||
single?: boolean;
|
||||
}
|
||||
|
||||
const SingleHealth: StatelessComponent<{ level: DeprecationInfo['level']; label: string }> = ({
|
||||
level,
|
||||
label,
|
||||
}) => (
|
||||
<React.Fragment>
|
||||
<EuiToolTip content={LocalizedActions[level]}>
|
||||
<EuiBadge color={COLOR_MAP[level]}>{label}</EuiBadge>
|
||||
</EuiToolTip>
|
||||
 
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
/**
|
||||
* Displays a summary health for a list of deprecations that shows the number and level of severity
|
||||
* deprecations in the list.
|
||||
*/
|
||||
export const DeprecationHealth: StatelessComponent<DeprecationHealthProps> = ({
|
||||
deprecations,
|
||||
single = false,
|
||||
}) => {
|
||||
if (deprecations.length === 0) {
|
||||
return <span />;
|
||||
}
|
||||
|
||||
const levels = deprecations.map(d => LEVEL_MAP[d.level]);
|
||||
|
||||
if (single) {
|
||||
const highest = Math.max(...levels);
|
||||
const highestLevel = REVERSE_LEVEL_MAP[highest];
|
||||
|
||||
return <SingleHealth level={highestLevel} label={LocalizedLevels[highestLevel]} />;
|
||||
}
|
||||
|
||||
const countByLevel = countBy(levels);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{Object.keys(countByLevel)
|
||||
.map(k => parseInt(k, 10))
|
||||
.sort()
|
||||
.map(level => [level, REVERSE_LEVEL_MAP[level]])
|
||||
.map(([numLevel, stringLevel]) => (
|
||||
<SingleHealth
|
||||
key={stringLevel}
|
||||
level={stringLevel as DeprecationInfo['level']}
|
||||
label={`${countByLevel[numLevel]} ${LocalizedLevels[stringLevel]}`}
|
||||
/>
|
||||
))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* 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 { GroupedDeprecations } from './grouped';
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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 { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import { IndexDeprecationTableProps, IndexDeprecationTableUI } from './index_table';
|
||||
|
||||
describe('IndexDeprecationTable', () => {
|
||||
const actions = [{ label: 'Do it', url: 'http://justdoit.com' }];
|
||||
const defaultProps = {
|
||||
indices: [
|
||||
{ index: 'index1', details: 'Index 1 deets', actions },
|
||||
{ index: 'index2', details: 'Index 2 deets', actions },
|
||||
{ index: 'index3', details: 'Index 3 deets', actions },
|
||||
],
|
||||
} as IndexDeprecationTableProps;
|
||||
|
||||
// Relying pretty heavily on EUI to implement the table functionality correctly.
|
||||
// This test simply verifies that the props passed to EuiBaseTable are the ones
|
||||
// expected.
|
||||
test('render', () => {
|
||||
expect(shallowWithIntl(<IndexDeprecationTableUI {...defaultProps} />)).toMatchInlineSnapshot(`
|
||||
<EuiBasicTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"field": "index",
|
||||
"name": "Index",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"field": "details",
|
||||
"name": "Details",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"render": [Function],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
hasActions={false}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Do it",
|
||||
"url": "http://justdoit.com",
|
||||
},
|
||||
],
|
||||
"details": "Index 1 deets",
|
||||
"index": "index1",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Do it",
|
||||
"url": "http://justdoit.com",
|
||||
},
|
||||
],
|
||||
"details": "Index 2 deets",
|
||||
"index": "index2",
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"label": "Do it",
|
||||
"url": "http://justdoit.com",
|
||||
},
|
||||
],
|
||||
"details": "Index 3 deets",
|
||||
"index": "index3",
|
||||
},
|
||||
]
|
||||
}
|
||||
noItemsMessage="No items found"
|
||||
onChange={[Function]}
|
||||
pagination={
|
||||
Object {
|
||||
"hidePerPageOptions": true,
|
||||
"pageIndex": 0,
|
||||
"pageSize": 10,
|
||||
"pageSizeOptions": Array [],
|
||||
"totalItemCount": 3,
|
||||
}
|
||||
}
|
||||
responsive={true}
|
||||
sorting={
|
||||
Object {
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "index",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
`);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* 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 { sortBy } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiBasicTable, EuiButton } from '@elastic/eui';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
const PAGE_SIZES = [10, 25, 50, 100, 250, 500, 1000];
|
||||
|
||||
export interface IndexDeprecationDetails {
|
||||
index: string;
|
||||
details?: string;
|
||||
actions?: Array<{
|
||||
label: string;
|
||||
url: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface IndexDeprecationTableProps extends ReactIntl.InjectedIntlProps {
|
||||
indices: IndexDeprecationDetails[];
|
||||
}
|
||||
|
||||
interface IndexDeprecationTableState {
|
||||
sortField: string;
|
||||
sortDirection: 'asc' | 'desc';
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export class IndexDeprecationTableUI extends React.Component<
|
||||
IndexDeprecationTableProps,
|
||||
IndexDeprecationTableState
|
||||
> {
|
||||
constructor(props: IndexDeprecationTableProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
sortField: 'index',
|
||||
sortDirection: 'asc',
|
||||
pageIndex: 0,
|
||||
pageSize: 10,
|
||||
};
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { intl } = this.props;
|
||||
const { pageIndex, pageSize, sortField, sortDirection } = this.state;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'index',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.deprecations.indexTable.indexColumnLabel',
|
||||
defaultMessage: 'Index',
|
||||
}),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'details',
|
||||
name: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.checkupTab.deprecations.indexTable.detailsColumnLabel',
|
||||
defaultMessage: 'Details',
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
if (this.actionsColumn) {
|
||||
// @ts-ignore
|
||||
columns.push(this.actionsColumn);
|
||||
}
|
||||
|
||||
const sorting = { sort: { field: sortField, direction: sortDirection } };
|
||||
const pagination = {
|
||||
pageIndex,
|
||||
pageSize,
|
||||
...this.pageSizeOptions(),
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiBasicTable
|
||||
items={this.getRows()}
|
||||
columns={columns}
|
||||
sorting={sorting}
|
||||
pagination={pagination}
|
||||
onChange={this.onTableChange}
|
||||
hasActions={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private getRows() {
|
||||
const { sortField, sortDirection, pageIndex, pageSize } = this.state;
|
||||
const { indices } = this.props;
|
||||
|
||||
let sorted = sortBy(indices, sortField);
|
||||
if (sortDirection === 'desc') {
|
||||
sorted = sorted.reverse();
|
||||
}
|
||||
|
||||
const start = pageIndex * pageSize;
|
||||
return sorted.slice(start, start + pageSize);
|
||||
}
|
||||
|
||||
private onTableChange = (tableProps: any) => {
|
||||
this.setState({
|
||||
sortField: tableProps.sort.field,
|
||||
sortDirection: tableProps.sort.direction,
|
||||
pageIndex: tableProps.page.index,
|
||||
pageSize: tableProps.page.size,
|
||||
});
|
||||
};
|
||||
|
||||
private pageSizeOptions() {
|
||||
const { indices } = this.props;
|
||||
const totalItemCount = indices.length;
|
||||
|
||||
// If we only have that smallest page size, don't show any page size options.
|
||||
if (totalItemCount <= PAGE_SIZES[0]) {
|
||||
return { totalItemCount, pageSizeOptions: [], hidePerPageOptions: true };
|
||||
}
|
||||
|
||||
// Keep a size option if the # of items is larger than the previous option.
|
||||
// This avoids having a long list of useless page sizes.
|
||||
const pageSizeOptions = PAGE_SIZES.filter((perPage, idx) => {
|
||||
return idx === 0 || totalItemCount > PAGE_SIZES[idx - 1];
|
||||
});
|
||||
|
||||
return { totalItemCount, pageSizeOptions, hidePerPageOptions: false };
|
||||
}
|
||||
|
||||
private get actionsColumn() {
|
||||
// NOTE: this naive implementation assumes all indices in the table have
|
||||
// the same actions (can still have different URLs). This should work for known usecases.
|
||||
const { indices } = this.props;
|
||||
if (!indices.find(i => i.actions !== undefined)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const actions = indices[0].actions!;
|
||||
|
||||
return {
|
||||
actions: actions.map((action, idx) => ({
|
||||
render(index: IndexDeprecationDetails) {
|
||||
const { url, label } = index.actions![idx];
|
||||
return (
|
||||
<EuiButton size="s" href={url} target="_blank">
|
||||
{label}
|
||||
</EuiButton>
|
||||
);
|
||||
},
|
||||
})),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const IndexDeprecationTable = injectI18n(IndexDeprecationTableUI);
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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 { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { EnrichedDeprecationInfo } from 'x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis';
|
||||
import { GroupByOption } from '../../../types';
|
||||
import { DeprecationList } from './list';
|
||||
|
||||
describe('DeprecationList', () => {
|
||||
describe('group by message', () => {
|
||||
const defaultProps = {
|
||||
deprecations: [
|
||||
{ message: 'Issue 1', url: '', level: 'warning' },
|
||||
{ message: 'Issue 1', url: '', level: 'warning' },
|
||||
] as EnrichedDeprecationInfo[],
|
||||
currentGroupBy: GroupByOption.message,
|
||||
};
|
||||
|
||||
test('shows simple messages when index field is not present', () => {
|
||||
expect(shallow(<DeprecationList {...defaultProps} />)).toMatchInlineSnapshot(`
|
||||
<div>
|
||||
<SimpleMessageDeprecation
|
||||
deprecation={
|
||||
Object {
|
||||
"level": "warning",
|
||||
"message": "Issue 1",
|
||||
"url": "",
|
||||
}
|
||||
}
|
||||
key="Issue 1"
|
||||
/>
|
||||
<SimpleMessageDeprecation
|
||||
deprecation={
|
||||
Object {
|
||||
"level": "warning",
|
||||
"message": "Issue 1",
|
||||
"url": "",
|
||||
}
|
||||
}
|
||||
key="Issue 1"
|
||||
/>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
|
||||
test('shows index deprecation when index field is present', () => {
|
||||
// Add index fields to deprecation items
|
||||
const props = {
|
||||
...defaultProps,
|
||||
deprecations: defaultProps.deprecations.map((d, index) => ({
|
||||
...d,
|
||||
index: index.toString(),
|
||||
})),
|
||||
};
|
||||
const wrapper = shallow(<DeprecationList {...props} />);
|
||||
expect(wrapper).toMatchInlineSnapshot(`
|
||||
<IndexDeprecation
|
||||
deprecation={
|
||||
Object {
|
||||
"index": "0",
|
||||
"level": "warning",
|
||||
"message": "Issue 1",
|
||||
"url": "",
|
||||
}
|
||||
}
|
||||
indices={
|
||||
Array [
|
||||
Object {
|
||||
"actions": undefined,
|
||||
"details": undefined,
|
||||
"index": "0",
|
||||
},
|
||||
Object {
|
||||
"actions": undefined,
|
||||
"details": undefined,
|
||||
"index": "1",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('group by index', () => {
|
||||
const defaultProps = {
|
||||
deprecations: [
|
||||
{ message: 'Issue 1', index: 'index1', url: '', level: 'warning' },
|
||||
{ message: 'Issue 2', index: 'index1', url: '', level: 'warning' },
|
||||
] as EnrichedDeprecationInfo[],
|
||||
currentGroupBy: GroupByOption.index,
|
||||
};
|
||||
|
||||
test('shows detailed messages', () => {
|
||||
expect(shallow(<DeprecationList {...defaultProps} />)).toMatchInlineSnapshot(`
|
||||
<div>
|
||||
<MessageDeprecation
|
||||
deprecation={
|
||||
Object {
|
||||
"index": "index1",
|
||||
"level": "warning",
|
||||
"message": "Issue 1",
|
||||
"url": "",
|
||||
}
|
||||
}
|
||||
key="Issue 1"
|
||||
/>
|
||||
<MessageDeprecation
|
||||
deprecation={
|
||||
Object {
|
||||
"index": "index1",
|
||||
"level": "warning",
|
||||
"message": "Issue 2",
|
||||
"url": "",
|
||||
}
|
||||
}
|
||||
key="Issue 2"
|
||||
/>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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, { StatelessComponent } from 'react';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { EnrichedDeprecationInfo } from '../../../../../server/lib/es_migration_apis';
|
||||
import { GroupByOption } from '../../../types';
|
||||
|
||||
import { COLOR_MAP, LEVEL_MAP } from '../constants';
|
||||
import { DeprecationCell } from './cell';
|
||||
import { IndexDeprecationDetails, IndexDeprecationTable } from './index_table';
|
||||
|
||||
const sortByLevelDesc = (a: DeprecationInfo, b: DeprecationInfo) => {
|
||||
return -1 * (LEVEL_MAP[a.level] - LEVEL_MAP[b.level]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to show a single deprecation message with any detailed information.
|
||||
*/
|
||||
const MessageDeprecation: StatelessComponent<{ deprecation: EnrichedDeprecationInfo }> = ({
|
||||
deprecation,
|
||||
}) => {
|
||||
const items = [];
|
||||
|
||||
if (deprecation.details) {
|
||||
items.push({ body: deprecation.details });
|
||||
}
|
||||
|
||||
return (
|
||||
<DeprecationCell
|
||||
headline={deprecation.message}
|
||||
healthColor={COLOR_MAP[deprecation.level]}
|
||||
actions={deprecation.actions}
|
||||
docUrl={deprecation.url}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to show a single (simple) deprecation message with any detailed information.
|
||||
*/
|
||||
const SimpleMessageDeprecation: StatelessComponent<{ deprecation: EnrichedDeprecationInfo }> = ({
|
||||
deprecation,
|
||||
}) => {
|
||||
const items = [];
|
||||
|
||||
if (deprecation.details) {
|
||||
items.push({ body: deprecation.details });
|
||||
}
|
||||
|
||||
return <DeprecationCell items={items} docUrl={deprecation.url} />;
|
||||
};
|
||||
|
||||
interface IndexDeprecationProps {
|
||||
deprecation: DeprecationInfo;
|
||||
indices: IndexDeprecationDetails[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a single deprecation and table of affected indices with details for each index.
|
||||
*/
|
||||
const IndexDeprecation: StatelessComponent<IndexDeprecationProps> = ({ deprecation, indices }) => {
|
||||
return (
|
||||
<DeprecationCell docUrl={deprecation.url}>
|
||||
<IndexDeprecationTable indices={indices} />
|
||||
</DeprecationCell>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* A list of deprecations that is either shown as individual deprecation cells or as a
|
||||
* deprecation summary for a list of indices.
|
||||
*/
|
||||
export const DeprecationList: StatelessComponent<{
|
||||
deprecations: EnrichedDeprecationInfo[];
|
||||
currentGroupBy: GroupByOption;
|
||||
}> = ({ deprecations, currentGroupBy }) => {
|
||||
// If we're grouping by message and the first deprecation has an index field, show an index
|
||||
// group deprecation. Otherwise, show each message.
|
||||
if (currentGroupBy === GroupByOption.message && deprecations[0].index !== undefined) {
|
||||
// If we're grouping by index we assume that every deprecation message is the same
|
||||
// issue and that each deprecation will have an index associated with it.
|
||||
const indices = deprecations.map(dep => ({
|
||||
index: dep.index!,
|
||||
details: dep.details,
|
||||
actions: dep.actions,
|
||||
}));
|
||||
|
||||
return <IndexDeprecation indices={indices} deprecation={deprecations[0]} />;
|
||||
} else if (currentGroupBy === GroupByOption.index) {
|
||||
// If we're grouping by index show all info for each message
|
||||
return (
|
||||
<div>
|
||||
{deprecations.sort(sortByLevelDesc).map(dep => (
|
||||
<MessageDeprecation deprecation={dep} key={dep.message} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
{deprecations.sort(sortByLevelDesc).map(dep => (
|
||||
<SimpleMessageDeprecation deprecation={dep} key={dep.message} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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 { mount, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { LevelFilterOption } from '../../types';
|
||||
import { FilterBar } from './filter_bar';
|
||||
|
||||
const defaultProps = {
|
||||
allDeprecations: [
|
||||
{ level: LevelFilterOption.critical },
|
||||
{ level: LevelFilterOption.critical },
|
||||
] as DeprecationInfo[],
|
||||
currentFilter: LevelFilterOption.critical,
|
||||
onFilterChange: jest.fn(),
|
||||
};
|
||||
|
||||
describe('FilterBar', () => {
|
||||
test('renders', () => {
|
||||
expect(shallow(<FilterBar {...defaultProps} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('clicking button calls onFilterChange', () => {
|
||||
const wrapper = mount(<FilterBar {...defaultProps} />);
|
||||
wrapper.find('button.euiFilterButton-hasActiveFilters').simulate('click');
|
||||
expect(defaultProps.onFilterChange).toHaveBeenCalledTimes(1);
|
||||
expect(defaultProps.onFilterChange.mock.calls[0][0]).toEqual(LevelFilterOption.critical);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 { groupBy } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiFilterButton, EuiFilterGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { LevelFilterOption } from '../../types';
|
||||
|
||||
const LocalizedOptions: { [option: string]: string } = {
|
||||
all: i18n.translate('xpack.upgradeAssistant.checkupTab.controls.filterBar.allButtonLabel', {
|
||||
defaultMessage: 'all',
|
||||
}),
|
||||
critical: i18n.translate(
|
||||
'xpack.upgradeAssistant.checkupTab.controls.filterBar.criticalButtonLabel',
|
||||
{ defaultMessage: 'critical' }
|
||||
),
|
||||
};
|
||||
|
||||
const allFilterOptions = Object.keys(LevelFilterOption) as LevelFilterOption[];
|
||||
|
||||
interface FilterBarProps {
|
||||
allDeprecations?: DeprecationInfo[];
|
||||
currentFilter: LevelFilterOption;
|
||||
onFilterChange(level: LevelFilterOption): void;
|
||||
}
|
||||
|
||||
export const FilterBar: React.StatelessComponent<FilterBarProps> = ({
|
||||
allDeprecations = [],
|
||||
currentFilter,
|
||||
onFilterChange,
|
||||
}) => {
|
||||
const levelGroups = groupBy(allDeprecations, 'level');
|
||||
const levelCounts = Object.keys(levelGroups).reduce(
|
||||
(counts, level) => {
|
||||
counts[level] = levelGroups[level].length;
|
||||
return counts;
|
||||
},
|
||||
{} as { [level: string]: number }
|
||||
);
|
||||
|
||||
const allCount = allDeprecations.length;
|
||||
|
||||
return (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFilterGroup>
|
||||
{allFilterOptions.map(option => (
|
||||
<EuiFilterButton
|
||||
key={option}
|
||||
onClick={onFilterChange.bind(null, option)}
|
||||
hasActiveFilters={currentFilter === option}
|
||||
numFilters={
|
||||
option === LevelFilterOption.all ? allCount : levelCounts[option] || undefined
|
||||
}
|
||||
>
|
||||
{LocalizedOptions[option]}
|
||||
</EuiFilterButton>
|
||||
))}
|
||||
</EuiFilterGroup>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { mount, shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { GroupByOption } from '../../types';
|
||||
import { GroupByBar } from './group_by_bar';
|
||||
|
||||
const defaultProps = {
|
||||
availableGroupByOptions: [GroupByOption.message, GroupByOption.index],
|
||||
currentGroupBy: GroupByOption.message,
|
||||
onGroupByChange: jest.fn(),
|
||||
};
|
||||
|
||||
describe('GroupByBar', () => {
|
||||
test('renders', () => {
|
||||
expect(shallow(<GroupByBar {...defaultProps} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('clicking button calls onGroupByChange', () => {
|
||||
const wrapper = mount(<GroupByBar {...defaultProps} />);
|
||||
wrapper.find('button.euiFilterButton-hasActiveFilters').simulate('click');
|
||||
expect(defaultProps.onGroupByChange).toHaveBeenCalledTimes(1);
|
||||
expect(defaultProps.onGroupByChange.mock.calls[0][0]).toEqual(GroupByOption.message);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 { EuiFilterButton, EuiFilterGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { GroupByOption } from '../../types';
|
||||
|
||||
const LocalizedOptions: { [option: string]: string } = {
|
||||
message: i18n.translate('xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIssueLabel', {
|
||||
defaultMessage: 'by issue',
|
||||
}),
|
||||
index: i18n.translate('xpack.upgradeAssistant.checkupTab.controls.groupByBar.byIndexLabel', {
|
||||
defaultMessage: 'by index',
|
||||
}),
|
||||
};
|
||||
|
||||
interface GroupByBarProps {
|
||||
availableGroupByOptions: GroupByOption[];
|
||||
currentGroupBy: GroupByOption;
|
||||
onGroupByChange: (groupBy: GroupByOption) => void;
|
||||
}
|
||||
|
||||
export const GroupByBar: React.StatelessComponent<GroupByBarProps> = ({
|
||||
availableGroupByOptions,
|
||||
currentGroupBy,
|
||||
onGroupByChange,
|
||||
}) => {
|
||||
if (availableGroupByOptions.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFilterGroup>
|
||||
{availableGroupByOptions.map(option => (
|
||||
<EuiFilterButton
|
||||
key={option}
|
||||
onClick={onGroupByChange.bind(null, option)}
|
||||
hasActiveFilters={currentGroupBy === option}
|
||||
>
|
||||
{LocalizedOptions[option]}
|
||||
</EuiFilterButton>
|
||||
))}
|
||||
</EuiFilterGroup>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* 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 { CheckupTab } from './checkup_tab';
|
|
@ -0,0 +1 @@
|
|||
@import './steps';
|
|
@ -0,0 +1,6 @@
|
|||
.upgSteps {
|
||||
.euiStep:last-child .euiStep__content {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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 axios from 'axios';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiLoadingSpinner, EuiSwitch } from '@elastic/eui';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { LoadingState } from '../../types';
|
||||
|
||||
interface DeprecationLoggingTabState {
|
||||
loadingState: LoadingState;
|
||||
loggingEnabled?: boolean;
|
||||
}
|
||||
|
||||
export class DeprecationLoggingToggleUI extends React.Component<
|
||||
ReactIntl.InjectedIntlProps,
|
||||
DeprecationLoggingTabState
|
||||
> {
|
||||
constructor(props: ReactIntl.InjectedIntlProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loadingState: LoadingState.Loading,
|
||||
};
|
||||
}
|
||||
|
||||
public componentWillMount() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { loggingEnabled, loadingState } = this.state;
|
||||
|
||||
// Show a spinner until we've done the initial load.
|
||||
if (loadingState === LoadingState.Loading && loggingEnabled === undefined) {
|
||||
return <EuiLoadingSpinner size="l" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiSwitch
|
||||
data-test-subj="upgradeAssistantDeprecationToggle"
|
||||
label={this.renderLoggingState()}
|
||||
checked={loggingEnabled}
|
||||
onChange={this.toggleLogging}
|
||||
disabled={loadingState === LoadingState.Loading || loadingState === LoadingState.Error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private renderLoggingState() {
|
||||
const { intl } = this.props;
|
||||
const { loggingEnabled, loadingState } = this.state;
|
||||
|
||||
if (loadingState === LoadingState.Error) {
|
||||
return intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.enableDeprecationLoggingToggleSwitch.errorLabel',
|
||||
defaultMessage: 'Could not load logging state',
|
||||
});
|
||||
} else if (loggingEnabled) {
|
||||
return intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.enableDeprecationLoggingToggleSwitch.enabledLabel',
|
||||
defaultMessage: 'On',
|
||||
});
|
||||
} else {
|
||||
return intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.enableDeprecationLoggingToggleSwitch.disabledLabel',
|
||||
defaultMessage: 'Off',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private loadData = async () => {
|
||||
try {
|
||||
this.setState({ loadingState: LoadingState.Loading });
|
||||
const resp = await axios.get(
|
||||
chrome.addBasePath('/api/upgrade_assistant/deprecation_logging')
|
||||
);
|
||||
this.setState({
|
||||
loadingState: LoadingState.Success,
|
||||
loggingEnabled: resp.data.isEnabled,
|
||||
});
|
||||
} catch (e) {
|
||||
this.setState({ loadingState: LoadingState.Error });
|
||||
}
|
||||
};
|
||||
|
||||
private toggleLogging = async () => {
|
||||
try {
|
||||
// Optimistically toggle the UI
|
||||
const newEnabled = !this.state.loggingEnabled;
|
||||
this.setState({ loadingState: LoadingState.Loading, loggingEnabled: newEnabled });
|
||||
|
||||
const resp = await axios.put(
|
||||
chrome.addBasePath('/api/upgrade_assistant/deprecation_logging'),
|
||||
{
|
||||
isEnabled: newEnabled,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'kbn-xsrf': chrome.getXsrfToken(),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
this.setState({
|
||||
loadingState: LoadingState.Success,
|
||||
loggingEnabled: resp.data.isEnabled,
|
||||
});
|
||||
} catch (e) {
|
||||
this.setState({ loadingState: LoadingState.Error });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const DeprecationLoggingToggle = injectI18n(DeprecationLoggingToggleUI);
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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, { Fragment, StatelessComponent } from 'react';
|
||||
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiLoadingSpinner,
|
||||
EuiPageContent,
|
||||
EuiPageContentBody,
|
||||
EuiSpacer,
|
||||
// @ts-ignore
|
||||
EuiStat,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { NEXT_MAJOR_VERSION } from '../../../../common/version';
|
||||
import { LoadingState, UpgradeAssistantTabProps } from '../../types';
|
||||
import { Steps } from './steps';
|
||||
|
||||
export const OverviewTab: StatelessComponent<UpgradeAssistantTabProps> = props => (
|
||||
<Fragment>
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiText grow={false}>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.tabDetail"
|
||||
defaultMessage="This assistant checks your cluster and indices and identifies the changes
|
||||
you need to make before upgrading to Elasticsearch {nextEsVersion}."
|
||||
values={{
|
||||
nextEsVersion: `${NEXT_MAJOR_VERSION}.x`,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
{props.alertBanner && (
|
||||
<Fragment>
|
||||
{props.alertBanner}
|
||||
|
||||
<EuiSpacer />
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
<EuiPageContent>
|
||||
<EuiPageContentBody>
|
||||
{props.loadingState === LoadingState.Success ? (
|
||||
<Steps {...props} />
|
||||
) : (
|
||||
<EuiFlexGroup justifyContent="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLoadingSpinner />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</EuiPageContentBody>
|
||||
</EuiPageContent>
|
||||
</Fragment>
|
||||
);
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* 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, { Fragment, StatelessComponent } from 'react';
|
||||
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiLink,
|
||||
EuiNotificationBadge,
|
||||
EuiSpacer,
|
||||
// @ts-ignore
|
||||
EuiStat,
|
||||
EuiSteps,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../../../common/version';
|
||||
import { UpgradeAssistantTabProps } from '../../types';
|
||||
import { DeprecationLoggingToggle } from './deprecation_logging_toggle';
|
||||
|
||||
// Leaving these here even if unused so they are picked up for i18n static analysis
|
||||
// Keep this until last minor release (when next major is also released).
|
||||
const WAIT_FOR_RELEASE_STEP = {
|
||||
title: i18n.translate('xpack.upgradeAssistant.overviewTab.steps.waitForReleaseStep.stepTitle', {
|
||||
defaultMessage: 'Wait for the Elasticsearch {nextEsVersion} release',
|
||||
values: {
|
||||
nextEsVersion: `${NEXT_MAJOR_VERSION}.0`,
|
||||
},
|
||||
}),
|
||||
children: (
|
||||
<Fragment>
|
||||
<EuiText grow={false}>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.waitForReleaseStep.stepDetail"
|
||||
defaultMessage="Once the release is out, upgrade to the latest {currentEsMajorVersion} version, and then
|
||||
return here to proceed with your {nextEsMajorVersion} upgrade."
|
||||
values={{
|
||||
currentEsMajorVersion: `${CURRENT_MAJOR_VERSION}.x`, // use "0.x" notation to imply the last minor
|
||||
nextEsMajorVersion: `${NEXT_MAJOR_VERSION}.0`,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
),
|
||||
};
|
||||
|
||||
// Swap in this step for the one above it on the last minor release.
|
||||
// @ts-ignore
|
||||
const START_UPGRADE_STEP = {
|
||||
title: i18n.translate('xpack.upgradeAssistant.overviewTab.steps.startUpgradeStep.stepTitle', {
|
||||
defaultMessage: 'Start your upgrade',
|
||||
}),
|
||||
children: (
|
||||
<Fragment>
|
||||
<EuiText grow={false}>
|
||||
<p>
|
||||
{chrome.getInjected('isCloudEnabled', false) ? (
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.startUpgradeStepCloud.stepDetail.goToCloudDashboardDetail"
|
||||
defaultMessage="Go to the Deployments section on the Elastic Cloud dashboard to start your upgrade."
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.startUpgradeStepOnPrem.stepDetail.followInstructionsDetail"
|
||||
defaultMessage="Follow {instructionButton} to start your upgrade."
|
||||
values={{
|
||||
instructionButton: (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-upgrade.html"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.startUpgradeStepOnPrem.stepDetail.instructionButtonLabel"
|
||||
defaultMessage="these instructions"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
</EuiText>
|
||||
</Fragment>
|
||||
),
|
||||
};
|
||||
|
||||
export const StepsUI: StatelessComponent<
|
||||
UpgradeAssistantTabProps & ReactIntl.InjectedIntlProps
|
||||
> = ({ checkupData, setSelectedTabIndex, intl }) => {
|
||||
const countByType = Object.keys(checkupData!).reduce(
|
||||
(counts, checkupType) => {
|
||||
counts[checkupType] = checkupData![checkupType].length;
|
||||
return counts;
|
||||
},
|
||||
{} as { [checkupType: string]: number }
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiSteps
|
||||
className="upgSteps"
|
||||
headingElement="h2"
|
||||
steps={[
|
||||
{
|
||||
title: countByType.cluster
|
||||
? intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.overviewTab.steps.clusterStep.issuesRemainingStepTitle',
|
||||
defaultMessage: 'Check for issues with your cluster',
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.clusterStep.noIssuesRemainingStepTitle',
|
||||
defaultMessage: 'Your cluster settings are ready',
|
||||
}),
|
||||
status: countByType.cluster ? 'warning' : 'complete',
|
||||
children: (
|
||||
<EuiText>
|
||||
{countByType.cluster ? (
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.clusterStep.todo.todoDetail"
|
||||
defaultMessage="Go to the {clusterTabButton} to update the deprecated settings."
|
||||
values={{
|
||||
clusterTabButton: (
|
||||
<EuiLink onClick={() => setSelectedTabIndex(1)}>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.clusterStep.todo.clusterTabButtonLabel"
|
||||
defaultMessage="Cluster tab"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.clusterStep.remainingIssuesDetail"
|
||||
defaultMessage="{numIssues} issues must be resolved."
|
||||
values={{
|
||||
numIssues: (
|
||||
<EuiNotificationBadge>{countByType.cluster}</EuiNotificationBadge>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
) : (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.clusterStep.noRemainingIssuesLabel"
|
||||
defaultMessage="No remaining deprecated settings."
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: countByType.indices
|
||||
? intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.overviewTab.steps.indicesStep.issuesRemainingStepTitle',
|
||||
defaultMessage: 'Check for issues with your indices',
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.indicesStep.noIssuesRemainingStepTitle',
|
||||
defaultMessage: 'Your index settings are ready',
|
||||
}),
|
||||
status: countByType.indices ? 'warning' : 'complete',
|
||||
children: (
|
||||
<EuiText>
|
||||
{countByType.indices ? (
|
||||
<Fragment>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.indicesStep.todo.todoDetail"
|
||||
defaultMessage="Go to the {indicesTabButton} to update the deprecated settings."
|
||||
values={{
|
||||
indicesTabButton: (
|
||||
<EuiLink onClick={() => setSelectedTabIndex(2)}>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.indicesStep.todo.indicesTabButtonLabel"
|
||||
defaultMessage="Indices tab"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.indicesStep.remainingIssuesDetail"
|
||||
defaultMessage="{numIssues} issues must be resolved."
|
||||
values={{
|
||||
numIssues: (
|
||||
<EuiNotificationBadge>{countByType.indices}</EuiNotificationBadge>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</Fragment>
|
||||
) : (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.indicesStep.noRemainingIssuesLabel"
|
||||
defaultMessage="No remaining deprecated settings."
|
||||
/>
|
||||
</p>
|
||||
)}
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: 'xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.stepTitle',
|
||||
defaultMessage: 'Review the Elasticsearch deprecation logs',
|
||||
}),
|
||||
children: (
|
||||
<Fragment>
|
||||
<EuiText grow={false}>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.deprecationLogs.logsDetail"
|
||||
defaultMessage="Read the {deprecationLogsDocButton} to see if your applications
|
||||
are using functionality that is not available in {nextEsVersion}. You may need to enable deprecation logging."
|
||||
values={{
|
||||
deprecationLogsDocButton: (
|
||||
<EuiLink
|
||||
href="https://www.elastic.co/guide/en/elasticsearch/reference/current/logging.html#deprecation-logging"
|
||||
target="_blank"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.deprecationLogs.deprecationLogsDocButtonLabel"
|
||||
defaultMessage="deprecation logs"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
nextEsVersion: `${NEXT_MAJOR_VERSION}.0`,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
|
||||
<EuiSpacer />
|
||||
|
||||
<EuiFormRow
|
||||
label={intl.formatMessage({
|
||||
id:
|
||||
'xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.enableDeprecationLoggingLabel',
|
||||
defaultMessage: 'Enable deprecation logging?',
|
||||
})}
|
||||
describedByIds={['deprecation-logging']}
|
||||
>
|
||||
<DeprecationLoggingToggle />
|
||||
</EuiFormRow>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
|
||||
// Swap in START_UPGRADE_STEP on the last minor release.
|
||||
WAIT_FOR_RELEASE_STEP,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const Steps = injectI18n(StepsUI);
|
42
x-pack/plugins/upgrade_assistant/public/components/types.ts
Normal file
42
x-pack/plugins/upgrade_assistant/public/components/types.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 {
|
||||
EnrichedDeprecationInfo,
|
||||
UpgradeAssistantStatus,
|
||||
} from '../../server/lib/es_migration_apis';
|
||||
|
||||
export interface UpgradeAssistantTabProps {
|
||||
alertBanner?: React.ReactNode;
|
||||
checkupData?: UpgradeAssistantStatus;
|
||||
deprecations?: EnrichedDeprecationInfo[];
|
||||
refreshCheckupData: () => Promise<void>;
|
||||
loadingState: LoadingState;
|
||||
setSelectedTabIndex: (tabIndex: number) => void;
|
||||
}
|
||||
|
||||
export class UpgradeAssistantTabComponent<
|
||||
T extends UpgradeAssistantTabProps = UpgradeAssistantTabProps,
|
||||
S = {}
|
||||
> extends React.Component<T, S> {}
|
||||
|
||||
export enum LoadingState {
|
||||
Loading,
|
||||
Success,
|
||||
Error,
|
||||
}
|
||||
|
||||
export enum LevelFilterOption {
|
||||
all = 'all',
|
||||
critical = 'critical',
|
||||
}
|
||||
|
||||
export enum GroupByOption {
|
||||
message = 'message',
|
||||
index = 'index',
|
||||
node = 'node',
|
||||
}
|
4
x-pack/plugins/upgrade_assistant/public/index.scss
Normal file
4
x-pack/plugins/upgrade_assistant/public/index.scss
Normal file
|
@ -0,0 +1,4 @@
|
|||
@import 'ui/public/styles/_styling_constants';
|
||||
|
||||
@import './app';
|
||||
@import './components/index';
|
39
x-pack/plugins/upgrade_assistant/public/index.tsx
Normal file
39
x-pack/plugins/upgrade_assistant/public/index.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { management } from 'ui/management';
|
||||
// @ts-ignore
|
||||
import { uiModules } from 'ui/modules';
|
||||
// @ts-ignore
|
||||
import routes from 'ui/routes';
|
||||
import { NEXT_MAJOR_VERSION } from '../common/version';
|
||||
import { RootComponent } from './app';
|
||||
|
||||
const BASE_PATH = `/management/elasticsearch/upgrade_assistant`;
|
||||
|
||||
function startApp() {
|
||||
management.getSection('elasticsearch').register('upgrade_assistant', {
|
||||
visible: true,
|
||||
display: i18n.translate('xpack.upgradeAssistant.appTitle', {
|
||||
defaultMessage: '{version} Upgrade Assistant',
|
||||
values: { version: `${NEXT_MAJOR_VERSION}.0` },
|
||||
}),
|
||||
order: 100,
|
||||
url: `#${BASE_PATH}`,
|
||||
});
|
||||
|
||||
uiModules.get('kibana').directive('upgradeAssistant', (reactDirective: any) => {
|
||||
return reactDirective(RootComponent);
|
||||
});
|
||||
|
||||
routes.when(`${BASE_PATH}/:view?`, {
|
||||
template: '<upgrade-assistant />',
|
||||
});
|
||||
}
|
||||
|
||||
startApp();
|
14
x-pack/plugins/upgrade_assistant/server/index.ts
Normal file
14
x-pack/plugins/upgrade_assistant/server/index.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { Legacy } from 'kibana';
|
||||
import { registerClusterCheckupRoutes } from './routes/cluster_checkup';
|
||||
import { registerDeprecationLoggingRoutes } from './routes/deprecation_logging';
|
||||
|
||||
export function initServer(server: Legacy.Server) {
|
||||
registerClusterCheckupRoutes(server);
|
||||
registerDeprecationLoggingRoutes(server);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"cluster_settings": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using `template` field, but `index_patterns` instead",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
"details": "templates using `template` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template"
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}"
|
||||
}
|
||||
],
|
||||
"node_settings": [],
|
||||
"index_settings": {
|
||||
".monitoring-es-6-2018.11.07": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]"
|
||||
}
|
||||
],
|
||||
"twitter": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: tweet, field: liked]]"
|
||||
}
|
||||
],
|
||||
".kibana": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]"
|
||||
}
|
||||
],
|
||||
".watcher-history-6-2018.11.07": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]"
|
||||
}
|
||||
],
|
||||
".monitoring-kibana-6-2018.11.07": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: doc, field: snapshot]]"
|
||||
}
|
||||
],
|
||||
"twitter2": [
|
||||
{
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
"details": "[[type: tweet, field: liked]]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ml_settings": []
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`getUpgradeAssistantStatus returns the correct shape of data 1`] = `
|
||||
Object {
|
||||
"cluster": Array [
|
||||
Object {
|
||||
"details": "templates using \`template\` field: security_audit_log,watches,.monitoring-alerts,triggered_watches,.ml-anomalies-,.ml-notifications,.ml-meta,.monitoring-kibana,.monitoring-es,.monitoring-logstash,.watch-history-6,.ml-state,security-index-template",
|
||||
"level": "warning",
|
||||
"message": "Template patterns are no longer using \`template\` field, but \`index_patterns\` instead",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html#_index_templates_use_literal_index_patterns_literal_instead_of_literal_template_literal",
|
||||
},
|
||||
Object {
|
||||
"details": "{.monitoring-logstash=[Coercion of boolean fields], .monitoring-es=[Coercion of boolean fields], .ml-anomalies-=[Coercion of boolean fields], .watch-history-6=[Coercion of boolean fields], .monitoring-kibana=[Coercion of boolean fields], security-index-template=[Coercion of boolean fields]}",
|
||||
"level": "warning",
|
||||
"message": "one or more templates use deprecated mapping settings",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_indices_changes.html",
|
||||
},
|
||||
],
|
||||
"indices": Array [
|
||||
Object {
|
||||
"details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]",
|
||||
"index": ".monitoring-es-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]",
|
||||
"index": ".kibana",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]",
|
||||
"index": ".watcher-history-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: doc, field: snapshot]]",
|
||||
"index": ".monitoring-kibana-6-2018.11.07",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
Object {
|
||||
"details": "[[type: tweet, field: liked]]",
|
||||
"index": "twitter2",
|
||||
"level": "warning",
|
||||
"message": "Coercion of boolean fields",
|
||||
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields",
|
||||
},
|
||||
],
|
||||
"nodes": Array [],
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 {
|
||||
getDeprecationLoggingStatus,
|
||||
isDeprecationLoggingEnabled,
|
||||
setDeprecationLogging,
|
||||
} from './es_deprecation_logging_apis';
|
||||
|
||||
describe('getDeprecationLoggingStatus', () => {
|
||||
it('calls cluster.getSettings', async () => {
|
||||
const callWithRequest = jest.fn();
|
||||
await getDeprecationLoggingStatus(callWithRequest, {} as any);
|
||||
expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.getSettings', {
|
||||
includeDefaults: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setDeprecationLogging', () => {
|
||||
describe('isEnabled = true', async () => {
|
||||
it('calls cluster.putSettings with logger.deprecation = WARN', async () => {
|
||||
const callWithRequest = jest.fn();
|
||||
await setDeprecationLogging(callWithRequest, {} as any, true);
|
||||
expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.putSettings', {
|
||||
body: { transient: { 'logger.deprecation': 'WARN' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEnabled = false', async () => {
|
||||
it('calls cluster.putSettings with logger.deprecation = ERROR', async () => {
|
||||
const callWithRequest = jest.fn();
|
||||
await setDeprecationLogging(callWithRequest, {} as any, false);
|
||||
expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.putSettings', {
|
||||
body: { transient: { 'logger.deprecation': 'ERROR' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isDeprecationLoggingEnabled', () => {
|
||||
['default', 'persistent', 'transient'].forEach(tier => {
|
||||
['ALL', 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ALL'].forEach(level => {
|
||||
it(`returns true when ${tier} is set to ${level}`, () => {
|
||||
expect(isDeprecationLoggingEnabled({ [tier]: { logger: { deprecation: level } } })).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
['default', 'persistent', 'transient'].forEach(tier => {
|
||||
['ERROR', 'FATAL'].forEach(level => {
|
||||
it(`returns false when ${tier} is set to ${level}`, () => {
|
||||
expect(isDeprecationLoggingEnabled({ [tier]: { logger: { deprecation: level } } })).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('allows transient to override persistent and default', () => {
|
||||
expect(
|
||||
isDeprecationLoggingEnabled({
|
||||
default: { logger: { deprecation: 'FATAL' } },
|
||||
persistent: { logger: { deprecation: 'FATAL' } },
|
||||
transient: { logger: { deprecation: 'WARN' } },
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('allows persistent to override default', () => {
|
||||
expect(
|
||||
isDeprecationLoggingEnabled({
|
||||
default: { logger: { deprecation: 'FATAL' } },
|
||||
persistent: { logger: { deprecation: 'WARN' } },
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { get } from 'lodash';
|
||||
|
||||
import { Legacy } from 'kibana';
|
||||
import { CallClusterWithRequest } from 'src/legacy/core_plugins/elasticsearch';
|
||||
|
||||
interface DeprecationLoggingStatus {
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
export async function getDeprecationLoggingStatus(
|
||||
callWithRequest: CallClusterWithRequest,
|
||||
req: Legacy.Request
|
||||
): Promise<DeprecationLoggingStatus> {
|
||||
const response = await callWithRequest(req, 'cluster.getSettings', {
|
||||
includeDefaults: true,
|
||||
});
|
||||
|
||||
return {
|
||||
isEnabled: isDeprecationLoggingEnabled(response),
|
||||
};
|
||||
}
|
||||
|
||||
export async function setDeprecationLogging(
|
||||
callWithRequest: CallClusterWithRequest,
|
||||
req: Legacy.Request,
|
||||
isEnabled: boolean
|
||||
): Promise<DeprecationLoggingStatus> {
|
||||
const response = await callWithRequest(req, 'cluster.putSettings', {
|
||||
body: {
|
||||
transient: {
|
||||
'logger.deprecation': isEnabled ? 'WARN' : 'ERROR',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
isEnabled: isDeprecationLoggingEnabled(response),
|
||||
};
|
||||
}
|
||||
|
||||
export function isDeprecationLoggingEnabled(settings: any) {
|
||||
const deprecationLogLevel = ['default', 'persistent', 'transient'].reduce(
|
||||
(currentLogLevel, settingsTier) =>
|
||||
get(settings, [settingsTier, 'logger', 'deprecation'], currentLogLevel),
|
||||
'WARN'
|
||||
);
|
||||
|
||||
return ['ALL', 'TRACE', 'DEBUG', 'INFO', 'WARN'].includes(deprecationLogLevel);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import { getUpgradeAssistantStatus } from './es_migration_apis';
|
||||
|
||||
import { DeprecationAPIResponse } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import fakeDeprecations from './__fixtures__/fake_deprecations.json';
|
||||
|
||||
describe('getUpgradeAssistantStatus', () => {
|
||||
let deprecationsResponse: DeprecationAPIResponse;
|
||||
|
||||
const callWithRequest = jest.fn().mockImplementation(async (req, api, { path }) => {
|
||||
if (path === '/_xpack/migration/deprecations') {
|
||||
return deprecationsResponse;
|
||||
} else {
|
||||
throw new Error(`Unexpected API call: ${path}`);
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
deprecationsResponse = _.cloneDeep(fakeDeprecations);
|
||||
});
|
||||
|
||||
it('calls /_xpack/migration/deprecations', async () => {
|
||||
await getUpgradeAssistantStatus(callWithRequest, {} as any, '/');
|
||||
expect(callWithRequest).toHaveBeenCalledWith({}, 'transport.request', {
|
||||
path: '/_xpack/migration/deprecations',
|
||||
method: 'GET',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the correct shape of data', async () => {
|
||||
const resp = await getUpgradeAssistantStatus(callWithRequest, {} as any, '/');
|
||||
expect(resp).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
|
||||
import { Request } from 'hapi';
|
||||
import { DeprecationAPIResponse, DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch';
|
||||
|
||||
export interface EnrichedDeprecationInfo extends DeprecationInfo {
|
||||
index?: string;
|
||||
node?: string;
|
||||
actions?: Array<{
|
||||
label: string;
|
||||
url: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface UpgradeAssistantStatus {
|
||||
cluster: EnrichedDeprecationInfo[];
|
||||
nodes: EnrichedDeprecationInfo[];
|
||||
indices: EnrichedDeprecationInfo[];
|
||||
|
||||
[checkupType: string]: EnrichedDeprecationInfo[];
|
||||
}
|
||||
|
||||
export async function getUpgradeAssistantStatus(
|
||||
callWithRequest: any,
|
||||
req: Request,
|
||||
basePath: string
|
||||
): Promise<UpgradeAssistantStatus> {
|
||||
const deprecations = (await callWithRequest(req, 'transport.request', {
|
||||
path: '/_xpack/migration/deprecations',
|
||||
method: 'GET',
|
||||
})) as DeprecationAPIResponse;
|
||||
|
||||
return {
|
||||
cluster: deprecations.cluster_settings,
|
||||
nodes: deprecations.node_settings,
|
||||
indices: getCombinedIndexInfos(deprecations, basePath),
|
||||
};
|
||||
}
|
||||
|
||||
// Combines the information from the migration assistance api and the deprecation api into a single array.
|
||||
// Enhances with information about which index the deprecation applies to and adds buttons for accessing the
|
||||
// reindex UI.
|
||||
const getCombinedIndexInfos = (deprecations: DeprecationAPIResponse, basePath: string) =>
|
||||
Object.keys(deprecations.index_settings).reduce(
|
||||
(indexDeprecations, indexName) => {
|
||||
return indexDeprecations.concat(
|
||||
deprecations.index_settings[indexName].map(
|
||||
d => ({ ...d, index: indexName } as EnrichedDeprecationInfo)
|
||||
)
|
||||
);
|
||||
},
|
||||
[] as EnrichedDeprecationInfo[]
|
||||
);
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 { Server } from 'hapi';
|
||||
import { registerClusterCheckupRoutes } from './cluster_checkup';
|
||||
|
||||
// Need to require to get mock on named export to work.
|
||||
// tslint:disable:no-var-requires
|
||||
const MigrationApis = require('../lib/es_migration_apis');
|
||||
MigrationApis.getUpgradeAssistantStatus = jest.fn();
|
||||
|
||||
/**
|
||||
* Since these route callbacks are so thin, these serve simply as integration tests
|
||||
* to ensure they're wired up to the lib functions correctly. Business logic is tested
|
||||
* more thoroughly in the es_migration_apis test.
|
||||
*/
|
||||
describe('reindex template API', () => {
|
||||
const server = new Server();
|
||||
server.plugins = {
|
||||
elasticsearch: {
|
||||
getCluster: () => ({ callWithRequest: jest.fn() } as any),
|
||||
} as any,
|
||||
} as any;
|
||||
server.config = () => ({ get: () => '' } as any);
|
||||
|
||||
registerClusterCheckupRoutes(server);
|
||||
|
||||
describe('GET /api/upgrade_assistant/reindex/{indexName}.json', () => {
|
||||
it('returns a template', async () => {
|
||||
MigrationApis.getUpgradeAssistantStatus.mockResolvedValue({
|
||||
cluster: [],
|
||||
indices: [],
|
||||
nodes: [],
|
||||
});
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/status',
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(200);
|
||||
expect(resp.payload).toMatchInlineSnapshot(
|
||||
`"{\\"cluster\\":[],\\"indices\\":[],\\"nodes\\":[]}"`
|
||||
);
|
||||
});
|
||||
|
||||
it('returns an 403 error if it throws forbidden', async () => {
|
||||
const e: any = new Error(`you can't go here!`);
|
||||
e.status = 403;
|
||||
|
||||
MigrationApis.getUpgradeAssistantStatus.mockRejectedValue(e);
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/status',
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(403);
|
||||
});
|
||||
|
||||
it('returns an 500 error if it throws', async () => {
|
||||
MigrationApis.getUpgradeAssistantStatus.mockRejectedValue(new Error(`scary error!`));
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/status',
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(500);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 Boom from 'boom';
|
||||
import { Legacy } from 'kibana';
|
||||
|
||||
import { getUpgradeAssistantStatus } from '../lib/es_migration_apis';
|
||||
|
||||
export function registerClusterCheckupRoutes(server: Legacy.Server) {
|
||||
const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin');
|
||||
const basePath = server.config().get<string>('server.basePath');
|
||||
|
||||
server.route({
|
||||
path: '/api/upgrade_assistant/status',
|
||||
method: 'GET',
|
||||
async handler(request) {
|
||||
try {
|
||||
return await getUpgradeAssistantStatus(callWithRequest, request, basePath);
|
||||
} catch (e) {
|
||||
if (e.status === 403) {
|
||||
return Boom.forbidden(e.message);
|
||||
}
|
||||
|
||||
return Boom.boomify(e, {
|
||||
statusCode: 500,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 { Server } from 'hapi';
|
||||
import { registerDeprecationLoggingRoutes } from './deprecation_logging';
|
||||
|
||||
/**
|
||||
* Since these route callbacks are so thin, these serve simply as integration tests
|
||||
* to ensure they're wired up to the lib functions correctly. Business logic is tested
|
||||
* more thoroughly in the es_deprecation_logging_apis test.
|
||||
*/
|
||||
describe('deprecation logging API', () => {
|
||||
const callWithRequest = jest.fn();
|
||||
const server = new Server();
|
||||
server.plugins = {
|
||||
elasticsearch: {
|
||||
getCluster: () => ({ callWithRequest } as any),
|
||||
} as any,
|
||||
} as any;
|
||||
|
||||
registerDeprecationLoggingRoutes(server);
|
||||
|
||||
describe('GET /api/upgrade_assistant/deprecation_logging', () => {
|
||||
it('returns isEnabled', async () => {
|
||||
callWithRequest.mockResolvedValue({ default: { logger: { deprecation: 'WARN' } } });
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/deprecation_logging',
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(200);
|
||||
expect(JSON.parse(resp.payload)).toEqual({ isEnabled: true });
|
||||
});
|
||||
|
||||
it('returns an error if it throws', async () => {
|
||||
callWithRequest.mockRejectedValue(new Error(`scary error!`));
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/deprecation_logging',
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /api/upgrade_assistant/deprecation_logging', () => {
|
||||
it('returns isEnabled', async () => {
|
||||
callWithRequest.mockResolvedValue({ default: { logger: { deprecation: 'ERROR' } } });
|
||||
const resp = await server.inject({
|
||||
method: 'GET',
|
||||
url: '/api/upgrade_assistant/deprecation_logging',
|
||||
payload: {
|
||||
isEnabled: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(JSON.parse(resp.payload)).toEqual({ isEnabled: false });
|
||||
});
|
||||
|
||||
it('returns an error if it throws', async () => {
|
||||
callWithRequest.mockRejectedValue(new Error(`scary error!`));
|
||||
const resp = await server.inject({
|
||||
method: 'PUT',
|
||||
url: '/api/upgrade_assistant/deprecation_logging',
|
||||
payload: {
|
||||
isEnabled: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(resp.statusCode).toEqual(500);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 Boom from 'boom';
|
||||
import Joi from 'joi';
|
||||
import { Legacy } from 'kibana';
|
||||
|
||||
import {
|
||||
getDeprecationLoggingStatus,
|
||||
setDeprecationLogging,
|
||||
} from '../lib/es_deprecation_logging_apis';
|
||||
|
||||
export function registerDeprecationLoggingRoutes(server: Legacy.Server) {
|
||||
const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin');
|
||||
|
||||
server.route({
|
||||
path: '/api/upgrade_assistant/deprecation_logging',
|
||||
method: 'GET',
|
||||
async handler(request) {
|
||||
try {
|
||||
return await getDeprecationLoggingStatus(callWithRequest, request);
|
||||
} catch (e) {
|
||||
return Boom.boomify(e, { statusCode: 500 });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
server.route({
|
||||
path: '/api/upgrade_assistant/deprecation_logging',
|
||||
method: 'PUT',
|
||||
options: {
|
||||
validate: {
|
||||
payload: Joi.object({
|
||||
isEnabled: Joi.boolean(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async handler(request) {
|
||||
try {
|
||||
const { isEnabled } = request.payload as { isEnabled: boolean };
|
||||
return await setDeprecationLogging(callWithRequest, request, isEnabled);
|
||||
} catch (e) {
|
||||
return Boom.boomify(e, { statusCode: 500 });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
|
@ -3,10 +3,10 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { TestInvoker } from './lib/types';
|
||||
import { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default function statusPage({ loadTestFile }: TestInvoker) {
|
||||
export default function statusPage({ loadTestFile }: KibanaFunctionalTestDefaultProviders) {
|
||||
describe('Status page', function statusPageTestSuite() {
|
||||
this.tags('ciGroup4');
|
||||
|
||||
|
|
15
x-pack/test/functional/apps/upgrade_assistant/index.ts
Normal file
15
x-pack/test/functional/apps/upgrade_assistant/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default function upgradeCheckup({ loadTestFile }: KibanaFunctionalTestDefaultProviders) {
|
||||
describe('Upgrade checkup ', function upgradeAssistantTestSuite() {
|
||||
this.tags('ciGroup4');
|
||||
|
||||
loadTestFile(require.resolve('./upgrade_assistant'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 { KibanaFunctionalTestDefaultProviders } from '../../../types/providers';
|
||||
|
||||
// tslint:disable:no-default-export
|
||||
export default function upgradeAssistantFunctionalTests({
|
||||
getService,
|
||||
getPageObjects,
|
||||
}: KibanaFunctionalTestDefaultProviders) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const PageObjects = getPageObjects(['upgradeAssistant']);
|
||||
|
||||
describe('Upgrade Checkup', () => {
|
||||
before(async () => await esArchiver.load('empty_kibana'));
|
||||
after(async () => await esArchiver.unload('empty_kibana'));
|
||||
|
||||
it('allows user to navigate to upgrade checkup', async () => {
|
||||
await PageObjects.upgradeAssistant.navigateToPage();
|
||||
await PageObjects.upgradeAssistant.expectUpgradeAssistant();
|
||||
});
|
||||
|
||||
it('allows user to toggle deprecation logging', async () => {
|
||||
await PageObjects.upgradeAssistant.navigateToPage();
|
||||
await PageObjects.upgradeAssistant.expectDeprecationLoggingLabel('On');
|
||||
await PageObjects.upgradeAssistant.toggleDeprecationLogging();
|
||||
await PageObjects.upgradeAssistant.expectDeprecationLoggingLabel('Off');
|
||||
});
|
||||
|
||||
it('allows user to open cluster tab', async () => {
|
||||
await PageObjects.upgradeAssistant.navigateToPage();
|
||||
await PageObjects.upgradeAssistant.clickTab('cluster');
|
||||
await PageObjects.upgradeAssistant.expectIssueSummary('You have no cluster issues.');
|
||||
});
|
||||
|
||||
it('allows user to open indices tab', async () => {
|
||||
await PageObjects.upgradeAssistant.navigateToPage();
|
||||
await PageObjects.upgradeAssistant.clickTab('indices');
|
||||
await PageObjects.upgradeAssistant.expectIssueSummary('You have no index issues.');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -20,6 +20,7 @@ import {
|
|||
AccountSettingProvider,
|
||||
InfraHomePageProvider,
|
||||
StatusPagePageProvider,
|
||||
UpgradeAssistantProvider,
|
||||
} from './page_objects';
|
||||
|
||||
import {
|
||||
|
@ -78,6 +79,7 @@ export default async function ({ readConfigFile }) {
|
|||
resolve(__dirname, './apps/grok_debugger'),
|
||||
resolve(__dirname, './apps/infra'),
|
||||
resolve(__dirname, './apps/status_page'),
|
||||
resolve(__dirname, './apps/upgrade_assistant'),
|
||||
],
|
||||
|
||||
// define the name and providers for services that should be
|
||||
|
@ -129,6 +131,7 @@ export default async function ({ readConfigFile }) {
|
|||
spaceSelector: SpaceSelectorPageProvider,
|
||||
infraHome: InfraHomePageProvider,
|
||||
statusPage: StatusPagePageProvider,
|
||||
upgradeAssistant: UpgradeAssistantProvider,
|
||||
},
|
||||
|
||||
servers: kibanaFunctionalConfig.get('servers'),
|
||||
|
|
|
@ -15,3 +15,4 @@ export { SpaceSelectorPageProvider } from './space_selector_page';
|
|||
export { AccountSettingProvider } from './accountsetting_page';
|
||||
export { InfraHomePageProvider } from './infra_home_page';
|
||||
export { StatusPagePageProvider } from './status_page';
|
||||
export { UpgradeAssistantProvider } from './upgrade_assistant';
|
||||
|
|
74
x-pack/test/functional/page_objects/upgrade_assistant.js
Normal file
74
x-pack/test/functional/page_objects/upgrade_assistant.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 expect from 'expect.js';
|
||||
|
||||
export function UpgradeAssistantProvider({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const log = getService('log');
|
||||
const browser = getService('browser');
|
||||
const find = getService('find');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['common', 'settings', 'security']);
|
||||
|
||||
class UpgradeAssistant {
|
||||
async initTests() {
|
||||
log.debug('UpgradeAssistant:initTests');
|
||||
}
|
||||
|
||||
async navigateToPage() {
|
||||
return await retry.try(async () => {
|
||||
await PageObjects.common.navigateToApp('settings');
|
||||
await testSubjects.click('upgrade_assistant');
|
||||
});
|
||||
}
|
||||
|
||||
async expectUpgradeAssistant() {
|
||||
return await retry.try(async () => {
|
||||
log.debug(`expectUpgradeAssistant()`);
|
||||
expect(testSubjects.exists('upgradeAssistantRoot')).to.be.true;
|
||||
const url = await browser.getCurrentUrl();
|
||||
expect(url).to.contain(`/upgrade_assistant`);
|
||||
});
|
||||
}
|
||||
|
||||
async toggleDeprecationLogging() {
|
||||
return await retry.try(async () => {
|
||||
log.debug('toggleDeprecationLogging()');
|
||||
await testSubjects.click('upgradeAssistantDeprecationToggle');
|
||||
});
|
||||
}
|
||||
|
||||
async expectDeprecationLoggingLabel(labelText) {
|
||||
return await retry.try(async () => {
|
||||
log.debug('expectDeprecationLoggingLabel()');
|
||||
const toggle = await testSubjects.find('upgradeAssistantDeprecationToggle');
|
||||
const div = await toggle.getProperty('parentElement');
|
||||
const label = await div.findByCssSelector('label');
|
||||
expect(await label.getVisibleText()).to.eql(labelText);
|
||||
});
|
||||
}
|
||||
|
||||
async clickTab(tabId) {
|
||||
return await retry.try(async () => {
|
||||
log.debug('clickTab()');
|
||||
const tab = await find.byCssSelector(`.euiTabs .euiTab#${tabId}`);
|
||||
await tab.click();
|
||||
});
|
||||
}
|
||||
|
||||
async expectIssueSummary(summary) {
|
||||
return await retry.try(async () => {
|
||||
log.debug('expectIssueSummary()');
|
||||
const summaryEl = await testSubjects.find('upgradeAssistantIssueSummary');
|
||||
const summaryElText = await summaryEl.getVisibleText();
|
||||
expect(summaryElText).to.eql(summary);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new UpgradeAssistant();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue