[ML] Fixing management app race condition (#100785)
* [ML] Fixing management app race condition * updating test id * translation id * adding link to license page * fixing tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0bcd78b0e9
commit
e93c18fea7
|
@ -25,7 +25,7 @@ export function checkGetManagementMlJobsResolver() {
|
|||
if (isManageML === true && isPlatinumOrTrialLicense === true) {
|
||||
return resolve({ mlFeatureEnabledInSpace });
|
||||
} else {
|
||||
return reject();
|
||||
return reject({ capabilities, isPlatinumOrTrialLicense, mlFeatureEnabledInSpace });
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
|
|
|
@ -31,8 +31,8 @@ export const AccessDeniedPage = () => (
|
|||
<EuiTitle>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.management.jobsList.accessDeniedTitle"
|
||||
defaultMessage="Access denied"
|
||||
id="xpack.ml.management.jobsList.insufficientLicenseTitle"
|
||||
defaultMessage="Machine Learning"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
|
@ -42,7 +42,7 @@ export const AccessDeniedPage = () => (
|
|||
<EuiSpacer size="m" />
|
||||
<EuiCallOut
|
||||
title={i18n.translate('xpack.ml.management.jobsList.noPermissionToAccessLabel', {
|
||||
defaultMessage: 'You need permission to access ML jobs',
|
||||
defaultMessage: 'Access denied',
|
||||
})}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, Fragment } from 'react';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreStart } from 'kibana/public';
|
||||
|
||||
import {
|
||||
EuiCallOut,
|
||||
EuiPage,
|
||||
EuiPageBody,
|
||||
EuiPageContentBody,
|
||||
EuiPageContentHeader,
|
||||
EuiPageContentHeaderSection,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
|
||||
interface Props {
|
||||
basePath: CoreStart['http']['basePath'];
|
||||
}
|
||||
|
||||
export const InsufficientLicensePage: FC<Props> = ({ basePath }) => (
|
||||
<Fragment>
|
||||
<EuiPage data-test-subj="mlPageInsufficientLicense">
|
||||
<EuiPageBody>
|
||||
<EuiPageContentHeader>
|
||||
<EuiPageContentHeaderSection>
|
||||
<EuiTitle>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.management.jobsList.insufficientLicenseTitle"
|
||||
defaultMessage="Machine Learning"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
</EuiPageContentHeaderSection>
|
||||
</EuiPageContentHeader>
|
||||
<EuiPageContentBody>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiCallOut
|
||||
title={i18n.translate('xpack.ml.management.jobsList.insufficientLicenseLabel', {
|
||||
defaultMessage:
|
||||
'Machine Learning is only available on a trial, platinum or enterprise license',
|
||||
})}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
>
|
||||
<EuiText size="s">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.management.jobsList.insufficientLicenseDescription"
|
||||
defaultMessage="Please {link} to use Machine Learning features"
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
href={`${basePath.get()}/app/management/stack/license_management/home`}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.management.jobsList.insufficientLicenseDescription.link"
|
||||
defaultMessage="upgrade your license or start a trial"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiCallOut>
|
||||
</EuiPageContentBody>
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
</Fragment>
|
||||
);
|
|
@ -38,6 +38,7 @@ import { getDocLinks } from '../../../../util/dependency_cache';
|
|||
import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_view/index';
|
||||
import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list';
|
||||
import { AccessDeniedPage } from '../access_denied_page';
|
||||
import { InsufficientLicensePage } from '../insufficient_license_page';
|
||||
import { SharePluginStart } from '../../../../../../../../../src/plugins/share/public';
|
||||
import type { SpacesPluginStart } from '../../../../../../../spaces/public';
|
||||
import { JobSpacesSyncFlyout } from '../../../../components/job_spaces_sync';
|
||||
|
@ -128,6 +129,7 @@ export const JobsListPage: FC<{
|
|||
const spacesEnabled = spacesApi !== undefined;
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const [accessDenied, setAccessDenied] = useState(false);
|
||||
const [isPlatinumOrTrialLicense, setIsPlatinumOrTrialLicense] = useState(true);
|
||||
const [showSyncFlyout, setShowSyncFlyout] = useState(false);
|
||||
const [isMlEnabledInSpace, setIsMlEnabledInSpace] = useState(false);
|
||||
const tabs = useTabs(isMlEnabledInSpace, spacesApi);
|
||||
|
@ -139,7 +141,11 @@ export const JobsListPage: FC<{
|
|||
const { mlFeatureEnabledInSpace } = await checkGetManagementMlJobsResolver();
|
||||
setIsMlEnabledInSpace(mlFeatureEnabledInSpace);
|
||||
} catch (e) {
|
||||
setAccessDenied(true);
|
||||
if (e.mlFeatureEnabledInSpace && e.isPlatinumOrTrialLicense === false) {
|
||||
setIsPlatinumOrTrialLicense(false);
|
||||
} else {
|
||||
setAccessDenied(true);
|
||||
}
|
||||
}
|
||||
setInitialized(true);
|
||||
};
|
||||
|
@ -191,6 +197,10 @@ export const JobsListPage: FC<{
|
|||
return <AccessDeniedPage />;
|
||||
}
|
||||
|
||||
if (isPlatinumOrTrialLicense === false) {
|
||||
return <InsufficientLicensePage basePath={coreStart.http.basePath} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<RedirectAppLinks application={coreStart.application}>
|
||||
<I18nContext>
|
||||
|
|
|
@ -53,6 +53,7 @@ import {
|
|||
} from '../../triggers_actions_ui/public';
|
||||
import { FileDataVisualizerPluginStart } from '../../file_data_visualizer/public';
|
||||
import { PluginSetupContract as AlertingSetup } from '../../alerting/public';
|
||||
import { registerManagementSection } from './application/management';
|
||||
|
||||
export interface MlStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
|
@ -133,6 +134,10 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
this.urlGenerator = registerUrlGenerator(pluginsSetup.share, core);
|
||||
}
|
||||
|
||||
if (pluginsSetup.management) {
|
||||
registerManagementSection(pluginsSetup.management, core).enable();
|
||||
}
|
||||
|
||||
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
|
||||
licensing.subscribe(async (license) => {
|
||||
const [coreStart] = await core.getStartServices();
|
||||
|
@ -160,7 +165,6 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
// note including registerFeature in register_helper would cause the page bundle size to increase significantly
|
||||
const {
|
||||
registerEmbeddables,
|
||||
registerManagementSection,
|
||||
registerMlUiActions,
|
||||
registerSearchLinks,
|
||||
registerMlAlerts,
|
||||
|
@ -172,11 +176,6 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
registerSearchLinks(this.appUpdater$, fullLicense);
|
||||
|
||||
if (fullLicense) {
|
||||
const canManageMLJobs =
|
||||
capabilities.management?.insightsAndAlerting?.jobsListLink ?? false;
|
||||
if (canManageMLJobs && pluginsSetup.management !== undefined) {
|
||||
registerManagementSection(pluginsSetup.management, core).enable();
|
||||
}
|
||||
registerEmbeddables(pluginsSetup.embeddable, core);
|
||||
registerMlUiActions(pluginsSetup.uiActions, core);
|
||||
|
||||
|
|
|
@ -145,6 +145,15 @@ export function MachineLearningNavigationProvider({
|
|||
});
|
||||
},
|
||||
|
||||
async navigateToStackManagementInsuficientLicensePage() {
|
||||
// clicks the jobsListLink and loads the jobs list page
|
||||
await testSubjects.click('jobsListLink');
|
||||
await retry.tryForTime(60 * 1000, async () => {
|
||||
// verify that the overall page is present
|
||||
await testSubjects.existOrFail('mlPageInsufficientLicense');
|
||||
});
|
||||
},
|
||||
|
||||
async navigateToStackManagementJobsListPageAnalyticsTab() {
|
||||
// clicks the `Analytics` tab and loads the analytics list page
|
||||
await testSubjects.click('mlStackManagementJobsListAnalyticsTab');
|
||||
|
|
|
@ -166,7 +166,12 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
await ml.testExecution.logTestStep(
|
||||
'should load the stack management with the ML menu item being absent'
|
||||
);
|
||||
await ml.navigation.navigateToStackManagement({ expectMlLink: false });
|
||||
await ml.navigation.navigateToStackManagement();
|
||||
|
||||
await ml.testExecution.logTestStep(
|
||||
'should load the stack management with insufficient license warning'
|
||||
);
|
||||
await ml.navigation.navigateToStackManagementInsuficientLicensePage();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue