[ML] Adding index migration warnings (#28938)

* [ML] Adding index migration warnings

* small refactor

* correctlng comment

* adding upgrade service to manage upgradeInProgress state

* removing missing function
This commit is contained in:
James Gowdy 2019-02-05 12:27:32 +00:00 committed by GitHub
parent 07add3b9b6
commit fda6efed1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 205 additions and 99 deletions

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { UpgradeWarning } from './upgrade_warning';

View file

@ -0,0 +1,48 @@
/*
* 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,
EuiSpacer,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { isUpgradeInProgress } from '../../services/upgrade_service';
export function UpgradeWarning() {
if (isUpgradeInProgress() === true) {
return (
<React.Fragment>
<EuiCallOut
title={(<FormattedMessage
id="xpack.ml.upgrade.upgradeWarning.upgradeInProgressWarningTitle"
defaultMessage="Index migration in progress"
/>)}
color="warning"
iconType="alert"
>
<p>
<FormattedMessage
id="xpack.ml.upgrade.upgradeWarning.upgradeInProgressWarningDescription"
defaultMessage="Indices related to Machine Learning are currently being upgraded."
/>
<br />
<FormattedMessage
id="xpack.ml.upgrade.upgradeWarning.upgradeInProgressWarningDescriptionExtra"
defaultMessage="Some actions will not be available during this time."
/>
</p>
</EuiCallOut>
<EuiSpacer size="m" />
</React.Fragment>
);
}
return null;
}

View file

@ -20,6 +20,7 @@ import { MultiJobActions } from '../multi_job_actions';
import { NewJobButton } from '../new_job_button';
import { JobStatsBar } from '../jobs_stats_bar';
import { NodeAvailableWarning } from '../node_available_warning';
import { UpgradeWarning } from '../../../../components/upgrade';
import { RefreshJobsListButton } from '../refresh_jobs_list_button';
import React, {
@ -356,6 +357,7 @@ export class JobsListView extends Component {
/>
<div className="job-management">
<NodeAvailableWarning />
<UpgradeWarning />
<header>
<div className="job-buttons-container">
<EuiFlexGroup alignItems="center">

View file

@ -6,6 +6,7 @@
import { ml } from 'plugins/ml/services/ml_api_service';
import { setUpgradeInProgress } from '../services/upgrade_service';
export function getPrivileges() {
const privileges = {
@ -64,94 +65,20 @@ export function getPrivileges() {
ml.checkPrivilege(priv)
.then((resp) => {
// if security has been disabled, securityDisabled is returned from the endpoint
// therefore set all privileges to true
if (resp.securityDisabled) {
if(resp.upgradeInProgress === true) {
setUpgradeInProgress(true);
// only check for getting endpoints
// force all to be true if security is disabled
setGettingPrivileges(resp.cluster, privileges, (resp.securityDisabled === true));
}
else if (resp.securityDisabled) {
// if security has been disabled, securityDisabled is returned from the endpoint
// therefore set all privileges to true
Object.keys(privileges).forEach(k => privileges[k] = true);
} else {
if (resp.cluster['cluster:monitor/xpack/ml/job/get'] &&
resp.cluster['cluster:monitor/xpack/ml/job/stats/get']) {
privileges.canGetJobs = true;
}
if (resp.cluster['cluster:monitor/xpack/ml/datafeeds/get'] &&
resp.cluster['cluster:monitor/xpack/ml/datafeeds/stats/get']) {
privileges.canGetDatafeeds = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/put'] &&
resp.cluster['cluster:admin/xpack/ml/job/open'] &&
resp.cluster['cluster:admin/xpack/ml/datafeeds/put']) {
privileges.canCreateJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/update']) {
privileges.canUpdateJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/open']) {
privileges.canOpenJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/close']) {
privileges.canCloseJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/forecast']) {
privileges.canForecastJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/delete'] &&
resp.cluster['cluster:admin/xpack/ml/datafeeds/delete']) {
privileges.canDeleteJob = true;
}
if (resp.cluster['cluster:admin/xpack/ml/job/open'] &&
resp.cluster['cluster:admin/xpack/ml/datafeeds/start'] &&
resp.cluster['cluster:admin/xpack/ml/datafeeds/stop']) {
privileges.canStartStopDatafeed = true;
}
if (resp.cluster['cluster:admin/xpack/ml/datafeeds/update']) {
privileges.canUpdateDatafeed = true;
}
if (resp.cluster['cluster:admin/xpack/ml/datafeeds/preview']) {
privileges.canPreviewDatafeed = true;
}
if (resp.cluster['cluster:monitor/xpack/ml/calendars/get']) {
privileges.canGetCalendars = true;
}
if (resp.cluster['cluster:admin/xpack/ml/calendars/put'] &&
resp.cluster['cluster:admin/xpack/ml/calendars/jobs/update'] &&
resp.cluster['cluster:admin/xpack/ml/calendars/events/post']) {
privileges.canCreateCalendar = true;
}
if (resp.cluster['cluster:admin/xpack/ml/calendars/delete'] &&
resp.cluster['cluster:admin/xpack/ml/calendars/events/delete']) {
privileges.canDeleteCalendar = true;
}
if (resp.cluster['cluster:admin/xpack/ml/filters/get']) {
privileges.canGetFilters = true;
}
if (resp.cluster['cluster:admin/xpack/ml/filters/put'] &&
resp.cluster['cluster:admin/xpack/ml/filters/update']) {
privileges.canCreateFilter = true;
}
if (resp.cluster['cluster:admin/xpack/ml/filters/delete']) {
privileges.canDeleteFilter = true;
}
if (resp.cluster['cluster:monitor/xpack/ml/findfilestructure']) {
privileges.canFindFileStructure = true;
}
setGettingPrivileges(resp.cluster, privileges);
setActionPrivileges(resp.cluster, privileges);
}
resolve(privileges);
@ -162,3 +89,95 @@ export function getPrivileges() {
});
}
function setGettingPrivileges(cluster = {}, privileges = {}, forceTrue = false) {
if (
forceTrue ||
(cluster['cluster:monitor/xpack/ml/job/get'] &&
cluster['cluster:monitor/xpack/ml/job/stats/get'])
) {
privileges.canGetJobs = true;
}
if (
forceTrue ||
(cluster['cluster:monitor/xpack/ml/datafeeds/get'] &&
cluster['cluster:monitor/xpack/ml/datafeeds/stats/get'])
) {
privileges.canGetDatafeeds = true;
}
if (forceTrue || cluster['cluster:monitor/xpack/ml/calendars/get']) {
privileges.canGetCalendars = true;
}
if (forceTrue || cluster['cluster:admin/xpack/ml/filters/get']) {
privileges.canGetFilters = true;
}
if (forceTrue || cluster['cluster:monitor/xpack/ml/findfilestructure']) {
privileges.canFindFileStructure = true;
}
}
function setActionPrivileges(cluster = {}, privileges = {}) {
if (cluster['cluster:admin/xpack/ml/job/put'] &&
cluster['cluster:admin/xpack/ml/job/open'] &&
cluster['cluster:admin/xpack/ml/datafeeds/put']) {
privileges.canCreateJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/update']) {
privileges.canUpdateJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/open']) {
privileges.canOpenJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/close']) {
privileges.canCloseJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/forecast']) {
privileges.canForecastJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/delete'] &&
cluster['cluster:admin/xpack/ml/datafeeds/delete']) {
privileges.canDeleteJob = true;
}
if (cluster['cluster:admin/xpack/ml/job/open'] &&
cluster['cluster:admin/xpack/ml/datafeeds/start'] &&
cluster['cluster:admin/xpack/ml/datafeeds/stop']) {
privileges.canStartStopDatafeed = true;
}
if (cluster['cluster:admin/xpack/ml/datafeeds/update']) {
privileges.canUpdateDatafeed = true;
}
if (cluster['cluster:admin/xpack/ml/datafeeds/preview']) {
privileges.canPreviewDatafeed = true;
}
if (cluster['cluster:admin/xpack/ml/calendars/put'] &&
cluster['cluster:admin/xpack/ml/calendars/jobs/update'] &&
cluster['cluster:admin/xpack/ml/calendars/events/post']) {
privileges.canCreateCalendar = true;
}
if (cluster['cluster:admin/xpack/ml/calendars/delete'] &&
cluster['cluster:admin/xpack/ml/calendars/events/delete']) {
privileges.canDeleteCalendar = true;
}
if (cluster['cluster:admin/xpack/ml/filters/put'] &&
cluster['cluster:admin/xpack/ml/filters/update']) {
privileges.canCreateFilter = true;
}
if (cluster['cluster:admin/xpack/ml/filters/delete']) {
privileges.canDeleteFilter = true;
}
}

View file

@ -0,0 +1,16 @@
/*
* 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.
*/
let upgradeInProgress = false;
export function setUpgradeInProgress(show) {
upgradeInProgress = show;
}
export function isUpgradeInProgress() {
return upgradeInProgress;
}

View file

@ -40,20 +40,33 @@ export function systemRoutes(server, commonRouteConfig) {
server.route({
method: 'POST',
path: '/api/ml/_has_privileges',
handler(request) {
async handler(request) {
const callWithRequest = callWithRequestFactory(server, request);
// isSecurityDisabled will return true if it is a basic license
// this will cause the subsequent ml.privilegeCheck to fail.
// therefore, check for a basic license first and report that security
// is disabled because its not available on basic
if (isBasicLicense(server) || isSecurityDisabled(server)) {
// if xpack.security.enabled has been explicitly set to false
// return that security is disabled and don't call the privilegeCheck endpoint
return { securityDisabled: true };
} else {
const body = request.payload;
return callWithRequest('ml.privilegeCheck', { body })
.catch(resp => wrapError(resp));
try {
const info = await callWithRequest('ml.info');
// if ml indices are currently being migrated, upgrade_mode will be set to true
// pass this back with the privileges to allow for the disabling of UI controls.
const upgradeInProgress = (info.upgrade_mode === true);
// isSecurityDisabled will return true if it is a basic license
// this will cause the subsequent ml.privilegeCheck to fail.
// therefore, check for a basic license first and report that security
// is disabled because its not available on basic
if (isBasicLicense(server) || isSecurityDisabled(server)) {
// if xpack.security.enabled has been explicitly set to false
// return that security is disabled and don't call the privilegeCheck endpoint
return {
securityDisabled: true,
upgradeInProgress
};
} else {
const body = request.payload;
const resp = await callWithRequest('ml.privilegeCheck', { body });
resp.upgradeInProgress = upgradeInProgress;
return resp;
}
} catch (error) {
return wrapError(error);
}
},
config: {