mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* Create x-pack/plugins skeleton for upgrade assistant * Move public folder contents Move the public folder of Upgrade Assistant and migrate public to use HttpSetup (remove axios) * Include stylesheets in public * Move server side out of legacy Begin migration of Reindex worker to new platform Move imports around so that it satsifies new platform constraints like not importing server side code (even types) in client. * Updated the routes with new dependencies and removed server shim * Fix router unit tests * Fix server lib tests After changing function signatures for the reindex server factory (and others) all of the tests needed to be revisited and brought in line with the new APIs. Also used core/server mocks where appropriate * Clean up types issues * Fix setting credentials on request header * Removed the security plugin from Upgrade Assistant The security plugin is a potential future consumer of the Upgrade Assistant's deprecation feature and we would therefore not want to create a circular depedency here. We pull in the licensing plugin rather (as it is less likely that we will depend on that) and use it to determine whether security is available and enabled. * Migrate to config to new platform config xpack.upgrade_assistant.enabled * Remove unused types * Fix import issue * Move upgrade assistant back to Elasticsearch management section * Update dotfiles Added elasticsearch ui team as upgrade assistant code owner Updated i18nrc.json path * Alphabetical ordering in xpack/i18nrc.json * Implemented PR feedback Renamed callCluster -> callAsUser to be more consistent with platform naming. Added comment about why we are not using security plugin directly inside of Upgrade Assistant. Fixed long path imports and use 'src/core/..' throughout. Fixed import ordering. Renamed variables inside of telemetry lib. * Revert to longer import path In plugin.ts importing from 'kibana/server' or 'src/core/server' results in a module not found error. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
253 lines
7.8 KiB
TypeScript
253 lines
7.8 KiB
TypeScript
/*
|
|
* 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 { findIndex, get, set } from 'lodash';
|
|
import React from 'react';
|
|
|
|
import {
|
|
EuiEmptyPrompt,
|
|
EuiPageContent,
|
|
EuiPageContentBody,
|
|
EuiTabbedContent,
|
|
EuiTabbedContentTab,
|
|
} from '@elastic/eui';
|
|
import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
|
|
import { HttpSetup } from 'src/core/public';
|
|
|
|
import { UpgradeAssistantStatus } from '../../../common/types';
|
|
import { LatestMinorBanner } from './latest_minor_banner';
|
|
import { CheckupTab } from './tabs/checkup';
|
|
import { OverviewTab } from './tabs/overview';
|
|
import { LoadingState, TelemetryState, UpgradeAssistantTabProps } from './types';
|
|
|
|
enum ClusterUpgradeState {
|
|
needsUpgrade,
|
|
partiallyUpgraded,
|
|
upgraded,
|
|
}
|
|
|
|
interface TabsState {
|
|
loadingState: LoadingState;
|
|
loadingError?: Error;
|
|
checkupData?: UpgradeAssistantStatus;
|
|
selectedTabIndex: number;
|
|
telemetryState: TelemetryState;
|
|
clusterUpgradeState: ClusterUpgradeState;
|
|
}
|
|
|
|
type Props = ReactIntl.InjectedIntlProps & { http: HttpSetup };
|
|
|
|
export class UpgradeAssistantTabsUI extends React.Component<Props, TabsState> {
|
|
constructor(props: Props) {
|
|
super(props);
|
|
this.state = {
|
|
loadingState: LoadingState.Loading,
|
|
clusterUpgradeState: ClusterUpgradeState.needsUpgrade,
|
|
selectedTabIndex: 0,
|
|
telemetryState: TelemetryState.Complete,
|
|
};
|
|
}
|
|
|
|
public async componentDidMount() {
|
|
await this.loadData();
|
|
|
|
// Send telemetry info about the default selected tab
|
|
this.sendTelemetryInfo(this.tabs[this.state.selectedTabIndex].id);
|
|
}
|
|
|
|
public render() {
|
|
const { selectedTabIndex, telemetryState, clusterUpgradeState } = this.state;
|
|
const tabs = this.tabs;
|
|
|
|
if (clusterUpgradeState === ClusterUpgradeState.partiallyUpgraded) {
|
|
return (
|
|
<EuiPageContent>
|
|
<EuiPageContentBody>
|
|
<EuiEmptyPrompt
|
|
iconType="logoElasticsearch"
|
|
title={
|
|
<h2>
|
|
<FormattedMessage
|
|
id="xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingTitle"
|
|
defaultMessage="Your cluster is upgrading"
|
|
/>
|
|
</h2>
|
|
}
|
|
body={
|
|
<p>
|
|
<FormattedMessage
|
|
id="xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingDescription"
|
|
defaultMessage="One or more Elasticsearch nodes have a newer version of
|
|
Elasticsearch than Kibana. Once all your nodes are upgraded, upgrade Kibana."
|
|
/>
|
|
</p>
|
|
}
|
|
/>
|
|
</EuiPageContentBody>
|
|
</EuiPageContent>
|
|
);
|
|
} else if (clusterUpgradeState === ClusterUpgradeState.upgraded) {
|
|
return (
|
|
<EuiPageContent>
|
|
<EuiPageContentBody>
|
|
<EuiEmptyPrompt
|
|
iconType="logoElasticsearch"
|
|
title={
|
|
<h2>
|
|
<FormattedMessage
|
|
id="xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradeCompleteTitle"
|
|
defaultMessage="Your cluster has been upgraded"
|
|
/>
|
|
</h2>
|
|
}
|
|
body={
|
|
<p>
|
|
<FormattedMessage
|
|
id="xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradeCompleteDescription"
|
|
defaultMessage="All Elasticsearch nodes have been upgraded. You may now upgrade Kibana."
|
|
/>
|
|
</p>
|
|
}
|
|
/>
|
|
</EuiPageContentBody>
|
|
</EuiPageContent>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<EuiTabbedContent
|
|
data-test-subj={
|
|
telemetryState === TelemetryState.Running ? 'upgradeAssistantTelemetryRunning' : undefined
|
|
}
|
|
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`);
|
|
}
|
|
|
|
// Send telemetry info about the current selected tab
|
|
// only in case the clicked tab id it's different from the
|
|
// current selected tab id
|
|
if (this.tabs[this.state.selectedTabIndex].id !== selectedTab.id) {
|
|
this.sendTelemetryInfo(selectedTab.id);
|
|
}
|
|
|
|
this.setSelectedTabIndex(selectedTabIndex);
|
|
};
|
|
|
|
private setSelectedTabIndex = (selectedTabIndex: number) => {
|
|
this.setState({ selectedTabIndex });
|
|
};
|
|
|
|
private loadData = async () => {
|
|
try {
|
|
this.setState({ loadingState: LoadingState.Loading });
|
|
const resp = await this.props.http.get('/api/upgrade_assistant/status');
|
|
this.setState({
|
|
loadingState: LoadingState.Success,
|
|
checkupData: resp,
|
|
});
|
|
} catch (e) {
|
|
if (get(e, 'response.status') === 426) {
|
|
this.setState({
|
|
loadingState: LoadingState.Success,
|
|
clusterUpgradeState: get(e, 'response.data.attributes.allNodesUpgraded', false)
|
|
? ClusterUpgradeState.upgraded
|
|
: ClusterUpgradeState.partiallyUpgraded,
|
|
});
|
|
} else {
|
|
this.setState({ loadingState: LoadingState.Error, loadingError: e });
|
|
}
|
|
}
|
|
};
|
|
|
|
private get tabs() {
|
|
const { intl } = this.props;
|
|
const { loadingError, loadingState, checkupData } = this.state;
|
|
const commonProps: UpgradeAssistantTabProps = {
|
|
loadingError,
|
|
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}
|
|
/>
|
|
),
|
|
},
|
|
];
|
|
}
|
|
|
|
private async sendTelemetryInfo(tabName: string) {
|
|
// In case we don't have any data yet, we wanna to ignore the
|
|
// telemetry info update
|
|
if (this.state.loadingState !== LoadingState.Success) {
|
|
return;
|
|
}
|
|
|
|
this.setState({ telemetryState: TelemetryState.Running });
|
|
|
|
await this.props.http.fetch('/api/upgrade_assistant/telemetry/ui_open', {
|
|
method: 'PUT',
|
|
body: JSON.stringify(set({}, tabName, true)),
|
|
});
|
|
|
|
this.setState({ telemetryState: TelemetryState.Complete });
|
|
}
|
|
}
|
|
|
|
export const UpgradeAssistantTabs = injectI18n(UpgradeAssistantTabsUI);
|