Skip to content

Commit

Permalink
Upgrade assistant - Phase 1 (#25168)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
joshdover authored Dec 18, 2018
1 parent fcb0a6d commit 4d295c7
Show file tree
Hide file tree
Showing 64 changed files with 4,916 additions and 3 deletions.
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/elasticsearch/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ export interface CallClusterWithRequest {
<T = any>(
request: Request,
endpoint: string,
clientParams: GenericParams,
clientParams: any,
options?: CallClusterOptions
): Promise<T>;
}
Expand Down
2 changes: 2 additions & 0 deletions x-pack/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 [
Expand Down Expand Up @@ -57,5 +58,6 @@ module.exports = function (kibana) {
kueryAutocomplete(kibana),
infra(kibana),
rollup(kibana),
upgradeAssistant(kibana),
];
};
2 changes: 2 additions & 0 deletions x-pack/plugins/__mocks__/ui/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
}
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/infra/types/eui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ declare module '@elastic/eui' {
rel?: string;
target?: string;
type?: string;
hasActiveFilters?: boolean;
numFilters?: number;
};
export const EuiFilterButton: React.SFC<EuiFilterButtonProps>;

Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/upgrade_assistant/common/version.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions x-pack/plugins/upgrade_assistant/index.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions x-pack/plugins/upgrade_assistant/public/_app.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
upgrade-assistant {
flex-grow: 1;
background-color: $euiColorLightestShade;
}
36 changes: 36 additions & 0 deletions x-pack/plugins/upgrade_assistant/public/app.tsx
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import './tabs/checkup/index';
@import './tabs/overview/index';
Original file line number Diff line number Diff line change
@@ -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>
);
61 changes: 61 additions & 0 deletions x-pack/plugins/upgrade_assistant/public/components/tabs.test.tsx
Original file line number Diff line number Diff line change
@@ -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);
});
});
Loading

0 comments on commit 4d295c7

Please sign in to comment.