diff --git a/x-pack/plugins/ml/public/privilege/get_privileges.js b/x-pack/plugins/ml/public/privilege/get_privileges.js
index 568fc8962d74d..c6f54899b97c3 100644
--- a/x-pack/plugins/ml/public/privilege/get_privileges.js
+++ b/x-pack/plugins/ml/public/privilege/get_privileges.js
@@ -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;
+ }
+}
diff --git a/x-pack/plugins/ml/public/services/upgrade_service.js b/x-pack/plugins/ml/public/services/upgrade_service.js
new file mode 100644
index 0000000000000..9087ab854ff7d
--- /dev/null
+++ b/x-pack/plugins/ml/public/services/upgrade_service.js
@@ -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;
+}
diff --git a/x-pack/plugins/ml/server/routes/system.js b/x-pack/plugins/ml/server/routes/system.js
index e723defdabf01..1ff37b879e5c5 100644
--- a/x-pack/plugins/ml/server/routes/system.js
+++ b/x-pack/plugins/ml/server/routes/system.js
@@ -39,20 +39,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: {