[ML] Adding endpoint capability checks (#64662)

* [ML] Adding endpoint capability checks

* adding missing capability checks

* fixing test

* removing commented code

* fixing functional test

* fixing functional tests

* changes based on review

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
James Gowdy 2020-04-29 18:25:48 +01:00 committed by GitHub
parent bac638a37e
commit d8c15f5ad3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 457 additions and 88 deletions

View file

@ -7,6 +7,7 @@
import { KibanaRequest } from 'kibana/server';
export const userMlCapabilities = {
canAccessML: false,
// Anomaly Detection
canGetJobs: false,
canGetDatafeeds: false,
@ -18,6 +19,10 @@ export const userMlCapabilities = {
canGetFilters: false,
// Data Frame Analytics
canGetDataFrameAnalytics: false,
// Annotations
canGetAnnotations: false,
canCreateAnnotation: false,
canDeleteAnnotation: false,
};
export const adminMlCapabilities = {
@ -26,9 +31,11 @@ export const adminMlCapabilities = {
canDeleteJob: false,
canOpenJob: false,
canCloseJob: false,
canForecastJob: false,
canStartStopDatafeed: false,
canUpdateJob: false,
canForecastJob: false,
canCreateDatafeed: false,
canDeleteDatafeed: false,
canStartStopDatafeed: false,
canUpdateDatafeed: false,
canPreviewDatafeed: false,
// Calendars
@ -38,8 +45,8 @@ export const adminMlCapabilities = {
canCreateFilter: false,
canDeleteFilter: false,
// Data Frame Analytics
canDeleteDataFrameAnalytics: false,
canCreateDataFrameAnalytics: false,
canDeleteDataFrameAnalytics: false,
canStartStopDataFrameAnalytics: false,
};
@ -47,7 +54,9 @@ export type UserMlCapabilities = typeof userMlCapabilities;
export type AdminMlCapabilities = typeof adminMlCapabilities;
export type MlCapabilities = UserMlCapabilities & AdminMlCapabilities;
export const basicLicenseMlCapabilities = ['canFindFileStructure'] as Array<keyof MlCapabilities>;
export const basicLicenseMlCapabilities = ['canAccessML', 'canFindFileStructure'] as Array<
keyof MlCapabilities
>;
export function getDefaultCapabilities(): MlCapabilities {
return {
@ -56,6 +65,23 @@ export function getDefaultCapabilities(): MlCapabilities {
};
}
export function getPluginPrivileges() {
const userMlCapabilitiesKeys = Object.keys(userMlCapabilities);
const adminMlCapabilitiesKeys = Object.keys(adminMlCapabilities);
const allMlCapabilities = [...adminMlCapabilitiesKeys, ...userMlCapabilitiesKeys];
return {
user: {
ui: userMlCapabilitiesKeys,
api: userMlCapabilitiesKeys.map(k => `ml:${k}`),
},
admin: {
ui: allMlCapabilities,
api: allMlCapabilities.map(k => `ml:${k}`),
},
};
}
export interface MlCapabilitiesResponse {
capabilities: MlCapabilities;
upgradeInProgress: boolean;

View file

@ -36,7 +36,7 @@ describe('check_capabilities', () => {
);
const { capabilities } = await getCapabilities();
const count = Object.keys(capabilities).length;
expect(count).toBe(22);
expect(count).toBe(28);
done();
});
});
@ -49,28 +49,42 @@ describe('check_capabilities', () => {
mlLicense,
mlIsEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(false);
expect(mlFeatureEnabledInSpace).toBe(true);
expect(isPlatinumOrTrialLicense).toBe(true);
expect(capabilities.canAccessML).toBe(true);
expect(capabilities.canGetJobs).toBe(true);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canGetAnnotations).toBe(true);
expect(capabilities.canCreateAnnotation).toBe(true);
expect(capabilities.canDeleteAnnotation).toBe(true);
expect(capabilities.canCreateJob).toBe(false);
expect(capabilities.canDeleteJob).toBe(false);
expect(capabilities.canOpenJob).toBe(false);
expect(capabilities.canCloseJob).toBe(false);
expect(capabilities.canForecastJob).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canStartStopDatafeed).toBe(false);
expect(capabilities.canUpdateJob).toBe(false);
expect(capabilities.canCreateDatafeed).toBe(false);
expect(capabilities.canDeleteDatafeed).toBe(false);
expect(capabilities.canUpdateDatafeed).toBe(false);
expect(capabilities.canPreviewDatafeed).toBe(false);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canCreateCalendar).toBe(false);
expect(capabilities.canDeleteCalendar).toBe(false);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canCreateFilter).toBe(false);
expect(capabilities.canDeleteFilter).toBe(false);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(false);
expect(capabilities.canCreateDataFrameAnalytics).toBe(false);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(false);
@ -84,28 +98,42 @@ describe('check_capabilities', () => {
mlLicense,
mlIsEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(false);
expect(mlFeatureEnabledInSpace).toBe(true);
expect(isPlatinumOrTrialLicense).toBe(true);
expect(capabilities.canAccessML).toBe(true);
expect(capabilities.canGetJobs).toBe(true);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canGetAnnotations).toBe(true);
expect(capabilities.canCreateAnnotation).toBe(true);
expect(capabilities.canDeleteAnnotation).toBe(true);
expect(capabilities.canCreateJob).toBe(true);
expect(capabilities.canDeleteJob).toBe(true);
expect(capabilities.canOpenJob).toBe(true);
expect(capabilities.canCloseJob).toBe(true);
expect(capabilities.canForecastJob).toBe(true);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canStartStopDatafeed).toBe(true);
expect(capabilities.canUpdateJob).toBe(true);
expect(capabilities.canCreateDatafeed).toBe(true);
expect(capabilities.canDeleteDatafeed).toBe(true);
expect(capabilities.canUpdateDatafeed).toBe(true);
expect(capabilities.canPreviewDatafeed).toBe(true);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canCreateCalendar).toBe(true);
expect(capabilities.canDeleteCalendar).toBe(true);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canCreateFilter).toBe(true);
expect(capabilities.canDeleteFilter).toBe(true);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(true);
expect(capabilities.canCreateDataFrameAnalytics).toBe(true);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(true);
@ -119,28 +147,42 @@ describe('check_capabilities', () => {
mlLicense,
mlIsEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(true);
expect(mlFeatureEnabledInSpace).toBe(true);
expect(isPlatinumOrTrialLicense).toBe(true);
expect(capabilities.canAccessML).toBe(true);
expect(capabilities.canGetJobs).toBe(true);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canGetAnnotations).toBe(true);
expect(capabilities.canCreateAnnotation).toBe(false);
expect(capabilities.canDeleteAnnotation).toBe(false);
expect(capabilities.canCreateJob).toBe(false);
expect(capabilities.canDeleteJob).toBe(false);
expect(capabilities.canOpenJob).toBe(false);
expect(capabilities.canCloseJob).toBe(false);
expect(capabilities.canForecastJob).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canStartStopDatafeed).toBe(false);
expect(capabilities.canUpdateJob).toBe(false);
expect(capabilities.canCreateDatafeed).toBe(false);
expect(capabilities.canDeleteDatafeed).toBe(false);
expect(capabilities.canUpdateDatafeed).toBe(false);
expect(capabilities.canPreviewDatafeed).toBe(false);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canCreateCalendar).toBe(false);
expect(capabilities.canDeleteCalendar).toBe(false);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canCreateFilter).toBe(false);
expect(capabilities.canDeleteFilter).toBe(false);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(false);
expect(capabilities.canCreateDataFrameAnalytics).toBe(false);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(false);
@ -154,28 +196,42 @@ describe('check_capabilities', () => {
mlLicense,
mlIsEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(true);
expect(mlFeatureEnabledInSpace).toBe(true);
expect(isPlatinumOrTrialLicense).toBe(true);
expect(capabilities.canAccessML).toBe(true);
expect(capabilities.canGetJobs).toBe(true);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canGetAnnotations).toBe(true);
expect(capabilities.canCreateAnnotation).toBe(false);
expect(capabilities.canDeleteAnnotation).toBe(false);
expect(capabilities.canCreateJob).toBe(false);
expect(capabilities.canDeleteJob).toBe(false);
expect(capabilities.canOpenJob).toBe(false);
expect(capabilities.canCloseJob).toBe(false);
expect(capabilities.canForecastJob).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(true);
expect(capabilities.canStartStopDatafeed).toBe(false);
expect(capabilities.canUpdateJob).toBe(false);
expect(capabilities.canCreateDatafeed).toBe(false);
expect(capabilities.canDeleteDatafeed).toBe(false);
expect(capabilities.canUpdateDatafeed).toBe(false);
expect(capabilities.canPreviewDatafeed).toBe(false);
expect(capabilities.canGetCalendars).toBe(true);
expect(capabilities.canCreateCalendar).toBe(false);
expect(capabilities.canDeleteCalendar).toBe(false);
expect(capabilities.canGetFilters).toBe(true);
expect(capabilities.canCreateFilter).toBe(false);
expect(capabilities.canDeleteFilter).toBe(false);
expect(capabilities.canFindFileStructure).toBe(true);
expect(capabilities.canGetDataFrameAnalytics).toBe(true);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(false);
expect(capabilities.canCreateDataFrameAnalytics).toBe(false);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(false);
@ -189,28 +245,42 @@ describe('check_capabilities', () => {
mlLicense,
mlIsNotEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(false);
expect(mlFeatureEnabledInSpace).toBe(false);
expect(isPlatinumOrTrialLicense).toBe(true);
expect(capabilities.canAccessML).toBe(false);
expect(capabilities.canGetJobs).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(false);
expect(capabilities.canGetCalendars).toBe(false);
expect(capabilities.canFindFileStructure).toBe(false);
expect(capabilities.canGetFilters).toBe(false);
expect(capabilities.canGetDataFrameAnalytics).toBe(false);
expect(capabilities.canGetAnnotations).toBe(false);
expect(capabilities.canCreateAnnotation).toBe(false);
expect(capabilities.canDeleteAnnotation).toBe(false);
expect(capabilities.canCreateJob).toBe(false);
expect(capabilities.canDeleteJob).toBe(false);
expect(capabilities.canOpenJob).toBe(false);
expect(capabilities.canCloseJob).toBe(false);
expect(capabilities.canForecastJob).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(false);
expect(capabilities.canStartStopDatafeed).toBe(false);
expect(capabilities.canUpdateJob).toBe(false);
expect(capabilities.canCreateDatafeed).toBe(false);
expect(capabilities.canDeleteDatafeed).toBe(false);
expect(capabilities.canUpdateDatafeed).toBe(false);
expect(capabilities.canPreviewDatafeed).toBe(false);
expect(capabilities.canGetCalendars).toBe(false);
expect(capabilities.canCreateCalendar).toBe(false);
expect(capabilities.canDeleteCalendar).toBe(false);
expect(capabilities.canGetFilters).toBe(false);
expect(capabilities.canCreateFilter).toBe(false);
expect(capabilities.canDeleteFilter).toBe(false);
expect(capabilities.canFindFileStructure).toBe(false);
expect(capabilities.canGetDataFrameAnalytics).toBe(false);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(false);
expect(capabilities.canCreateDataFrameAnalytics).toBe(false);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(false);
@ -225,28 +295,43 @@ describe('check_capabilities', () => {
mlLicenseBasic,
mlIsNotEnabled
);
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities();
const {
capabilities,
upgradeInProgress,
mlFeatureEnabledInSpace,
isPlatinumOrTrialLicense,
} = await getCapabilities();
expect(upgradeInProgress).toBe(false);
expect(mlFeatureEnabledInSpace).toBe(false);
expect(isPlatinumOrTrialLicense).toBe(false);
expect(capabilities.canAccessML).toBe(false);
expect(capabilities.canGetJobs).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(false);
expect(capabilities.canGetCalendars).toBe(false);
expect(capabilities.canFindFileStructure).toBe(false);
expect(capabilities.canGetFilters).toBe(false);
expect(capabilities.canGetDataFrameAnalytics).toBe(false);
expect(capabilities.canGetAnnotations).toBe(false);
expect(capabilities.canCreateAnnotation).toBe(false);
expect(capabilities.canDeleteAnnotation).toBe(false);
expect(capabilities.canCreateJob).toBe(false);
expect(capabilities.canDeleteJob).toBe(false);
expect(capabilities.canOpenJob).toBe(false);
expect(capabilities.canCloseJob).toBe(false);
expect(capabilities.canForecastJob).toBe(false);
expect(capabilities.canGetDatafeeds).toBe(false);
expect(capabilities.canStartStopDatafeed).toBe(false);
expect(capabilities.canUpdateJob).toBe(false);
expect(capabilities.canCreateDatafeed).toBe(false);
expect(capabilities.canDeleteDatafeed).toBe(false);
expect(capabilities.canUpdateDatafeed).toBe(false);
expect(capabilities.canPreviewDatafeed).toBe(false);
expect(capabilities.canGetCalendars).toBe(false);
expect(capabilities.canCreateCalendar).toBe(false);
expect(capabilities.canDeleteCalendar).toBe(false);
expect(capabilities.canGetFilters).toBe(false);
expect(capabilities.canCreateFilter).toBe(false);
expect(capabilities.canDeleteFilter).toBe(false);
expect(capabilities.canFindFileStructure).toBe(false);
expect(capabilities.canGetDataFrameAnalytics).toBe(false);
expect(capabilities.canDeleteDataFrameAnalytics).toBe(false);
expect(capabilities.canCreateDataFrameAnalytics).toBe(false);
expect(capabilities.canStartStopDataFrameAnalytics).toBe(false);

View file

@ -44,4 +44,6 @@ function disableAdminPrivileges(capabilities: MlCapabilities) {
Object.keys(adminMlCapabilities).forEach(k => {
capabilities[k as keyof MlCapabilities] = false;
});
capabilities.canCreateAnnotation = false;
capabilities.canDeleteAnnotation = false;
}

View file

@ -45,7 +45,7 @@ import { systemRoutes } from './routes/system';
import { MlLicense } from '../common/license';
import { MlServerLicense } from './lib/license';
import { createSharedServices, SharedServices } from './shared_services';
import { userMlCapabilities, adminMlCapabilities } from '../common/types/capabilities';
import { getPluginPrivileges } from '../common/types/capabilities';
import { setupCapabilitiesSwitcher } from './lib/capabilities';
import { registerKibanaSettings } from './lib/register_settings';
@ -75,8 +75,7 @@ export class MlServerPlugin implements Plugin<MlPluginSetup, MlPluginStart, Plug
}
public setup(coreSetup: CoreSetup, plugins: PluginsSetup): MlPluginSetup {
const userMlCapabilitiesKeys = Object.keys(userMlCapabilities);
const adminMlCapabilitiesKeys = Object.keys(adminMlCapabilities);
const { user, admin } = getPluginPrivileges();
plugins.features.registerFeature({
id: PLUGIN_ID,
@ -98,31 +97,32 @@ export class MlServerPlugin implements Plugin<MlPluginSetup, MlPluginStart, Plug
{
id: 'ml_user',
privilege: {
api: user.api,
app: [PLUGIN_ID, 'kibana'],
catalogue: [PLUGIN_ID],
savedObject: {
all: [],
read: [],
},
ui: userMlCapabilitiesKeys,
ui: user.ui,
},
},
{
id: 'ml_admin',
privilege: {
api: admin.api,
app: [PLUGIN_ID, 'kibana'],
catalogue: [PLUGIN_ID],
savedObject: {
all: [],
read: [],
},
ui: [...adminMlCapabilitiesKeys, ...userMlCapabilitiesKeys],
ui: admin.ui,
},
},
],
},
});
registerKibanaSettings(coreSetup);
this.mlLicense.setup(plugins.licensing.license$, [
@ -168,7 +168,7 @@ export class MlServerPlugin implements Plugin<MlPluginSetup, MlPluginStart, Plug
indicesRoutes(routeInit);
jobAuditMessagesRoutes(routeInit);
jobRoutes(routeInit);
jobServiceRoutes(routeInit, { resolveMlCapabilities });
jobServiceRoutes(routeInit);
notificationRoutes(routeInit);
resultsServiceRoutes(routeInit);
jobValidationRoutes(routeInit, this.version);

View file

@ -54,6 +54,9 @@ export function annotationRoutes(
validate: {
body: getAnnotationsSchema,
},
options: {
tags: ['access:ml:canGetAnnotations'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -86,6 +89,9 @@ export function annotationRoutes(
validate: {
body: indexAnnotationSchema,
},
options: {
tags: ['access:ml:canCreateAnnotation'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -130,6 +136,9 @@ export function annotationRoutes(
validate: {
params: deleteAnnotationSchema,
},
options: {
tags: ['access:ml:canDeleteAnnotation'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -37,6 +37,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/anomaly_detectors',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -65,6 +68,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: jobIdSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -93,6 +99,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/anomaly_detectors/_stats',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -121,6 +130,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: jobIdSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -154,6 +166,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: jobIdSchema,
body: schema.object(anomalyDetectionJobSchema),
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -188,6 +203,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: jobIdSchema,
body: anomalyDetectionUpdateJobSchema,
},
options: {
tags: ['access:ml:canUpdateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -220,6 +238,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: jobIdSchema,
},
options: {
tags: ['access:ml:canOpenJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -251,6 +272,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: jobIdSchema,
},
options: {
tags: ['access:ml:canCloseJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -286,6 +310,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: jobIdSchema,
},
options: {
tags: ['access:ml:canDeleteJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -319,6 +346,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
body: schema.any(),
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -351,6 +381,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: jobIdSchema,
body: forecastAnomalyDetector,
},
options: {
tags: ['access:ml:canForecastJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -389,6 +422,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: jobIdSchema,
body: getRecordsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -425,6 +461,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: getBucketParamsSchema,
body: getBucketsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -462,6 +501,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
params: jobIdSchema,
body: getOverallBucketsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -496,6 +538,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: getCategoriesSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -52,6 +52,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/calendars',
validate: false,
options: {
tags: ['access:ml:canGetCalendars'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -81,6 +84,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) {
validate: {
params: calendarIdsSchema,
},
options: {
tags: ['access:ml:canGetCalendars'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
let returnValue;
@ -117,6 +123,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) {
validate: {
body: calendarSchema,
},
options: {
tags: ['access:ml:canCreateCalendar'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -149,6 +158,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) {
params: calendarIdSchema,
body: calendarSchema,
},
options: {
tags: ['access:ml:canCreateCalendar'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -180,6 +192,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) {
validate: {
params: calendarIdSchema,
},
options: {
tags: ['access:ml:canDeleteCalendar'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -33,6 +33,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
{
path: '/api/ml/data_frame/analytics',
validate: false,
options: {
tags: ['access:ml:canGetDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -61,6 +64,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
params: analyticsIdSchema,
},
options: {
tags: ['access:ml:canGetDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -88,6 +94,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
{
path: '/api/ml/data_frame/analytics/_stats',
validate: false,
options: {
tags: ['access:ml:canGetDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -118,6 +127,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
params: analyticsIdSchema,
},
options: {
tags: ['access:ml:canGetDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -155,6 +167,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
params: analyticsIdSchema,
body: dataAnalyticsJobConfigSchema,
},
options: {
tags: ['access:ml:canCreateDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -190,6 +205,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
body: dataAnalyticsEvaluateSchema,
},
options: {
tags: ['access:ml:canCreateDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -224,6 +242,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
body: dataAnalyticsExplainSchema,
},
options: {
tags: ['access:ml:canCreateDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -257,6 +278,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
params: analyticsIdSchema,
},
options: {
tags: ['access:ml:canDeleteDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -291,6 +315,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
params: analyticsIdSchema,
},
options: {
tags: ['access:ml:canStartStopDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -324,6 +351,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
params: analyticsIdSchema,
query: stopsDataFrameAnalyticsJobQuerySchema,
},
options: {
tags: ['access:ml:canStartStopDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -364,6 +394,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat
validate: {
params: analyticsIdSchema,
},
options: {
tags: ['access:ml:canGetDataFrameAnalytics'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -88,6 +88,9 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization)
params: indexPatternTitleSchema,
body: dataVisualizerFieldStatsSchema,
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {
@ -150,6 +153,9 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization)
params: indexPatternTitleSchema,
body: dataVisualizerOverallStatsSchema,
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -28,6 +28,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/datafeeds',
validate: false,
options: {
tags: ['access:ml:canGetDatafeeds'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -57,6 +60,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: datafeedIdSchema,
},
options: {
tags: ['access:ml:canGetDatafeeds'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -83,6 +89,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/datafeeds/_stats',
validate: false,
options: {
tags: ['access:ml:canGetDatafeeds'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -112,6 +121,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: datafeedIdSchema,
},
options: {
tags: ['access:ml:canGetDatafeeds'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -146,6 +158,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
params: datafeedIdSchema,
body: datafeedConfigSchema,
},
options: {
tags: ['access:ml:canCreateDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -181,6 +196,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
params: datafeedIdSchema,
body: datafeedConfigSchema,
},
options: {
tags: ['access:ml:canUpdateDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -216,6 +234,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
params: datafeedIdSchema,
query: deleteDatafeedQuerySchema,
},
options: {
tags: ['access:ml:canDeleteDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -255,6 +276,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
params: datafeedIdSchema,
body: startDatafeedSchema,
},
options: {
tags: ['access:ml:canStartStopDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -291,6 +315,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: datafeedIdSchema,
},
options: {
tags: ['access:ml:canStartStopDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -324,6 +351,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: datafeedIdSchema,
},
options: {
tags: ['access:ml:canPreviewDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -46,8 +46,10 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) {
validate: {
body: getCardinalityOfFieldsSchema,
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
const resp = await getCardinalityOfFields(context, request.body);
@ -79,6 +81,9 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) {
validate: {
body: getTimeFieldRangeSchema,
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -71,6 +71,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat
accepts: ['text/*', 'application/json'],
maxBytes: MAX_FILE_SIZE_BYTES,
},
tags: ['access:ml:canFindFileStructure'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
@ -105,6 +106,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat
accepts: ['application/json'],
maxBytes: MAX_FILE_SIZE_BYTES,
},
tags: ['access:ml:canFindFileStructure'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {

View file

@ -57,6 +57,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/filters',
validate: false,
options: {
tags: ['access:ml:canGetFilters'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -89,6 +92,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: filterIdSchema,
},
options: {
tags: ['access:ml:canGetFilters'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -120,6 +126,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
body: createFilterSchema,
},
options: {
tags: ['access:ml:canCreateFilter'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -155,6 +164,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
params: filterIdSchema,
body: updateFilterSchema,
},
options: {
tags: ['access:ml:canCreateFilter'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -186,6 +198,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
params: filterIdSchema,
},
options: {
tags: ['access:ml:canDeleteFilter'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -216,6 +231,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/filters/_stats',
validate: false,
options: {
tags: ['access:ml:canGetFilters'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -27,6 +27,9 @@ export function indicesRoutes({ router, mlLicense }: RouteInitialization) {
validate: {
body: indicesSchema,
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -33,6 +33,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio
params: jobAuditMessagesJobIdSchema,
query: jobAuditMessagesQuerySchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -67,6 +70,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio
validate: {
query: jobAuditMessagesQuerySchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -4,11 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import Boom from 'boom';
import { schema } from '@kbn/config-schema';
import { KibanaRequest } from 'kibana/server';
import { wrapError } from '../client/error_wrapper';
import { RouteInitialization, JobServiceRouteDeps } from '../types';
import { RouteInitialization } from '../types';
import {
categorizationFieldExamplesSchema,
chartSchema,
@ -27,19 +25,7 @@ import { categorizationExamplesProvider } from '../models/job_service/new_job';
/**
* Routes for job service
*/
export function jobServiceRoutes(
{ router, mlLicense }: RouteInitialization,
{ resolveMlCapabilities }: JobServiceRouteDeps
) {
async function hasPermissionToCreateJobs(request: KibanaRequest) {
const mlCapabilities = await resolveMlCapabilities(request);
if (mlCapabilities === null) {
throw new Error('resolveMlCapabilities is not defined');
}
return mlCapabilities.canCreateJob;
}
export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) {
/**
* @apiGroup JobService
*
@ -55,6 +41,9 @@ export function jobServiceRoutes(
validate: {
body: forceStartDatafeedSchema,
},
options: {
tags: ['access:ml:canStartStopDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -86,6 +75,9 @@ export function jobServiceRoutes(
validate: {
body: datafeedIdsSchema,
},
options: {
tags: ['access:ml:canStartStopDatafeed'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -117,6 +109,9 @@ export function jobServiceRoutes(
validate: {
body: jobIdsSchema,
},
options: {
tags: ['access:ml:canDeleteJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -148,6 +143,9 @@ export function jobServiceRoutes(
validate: {
body: jobIdsSchema,
},
options: {
tags: ['access:ml:canCloseJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -184,6 +182,9 @@ export function jobServiceRoutes(
validate: {
body: jobIdsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -215,6 +216,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(jobsWithTimerangeSchema),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -245,6 +249,9 @@ export function jobServiceRoutes(
validate: {
body: jobIdsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -272,6 +279,9 @@ export function jobServiceRoutes(
{
path: '/api/ml/jobs/groups',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -302,6 +312,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(updateGroupsSchema),
},
options: {
tags: ['access:ml:canUpdateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -329,6 +342,9 @@ export function jobServiceRoutes(
{
path: '/api/ml/jobs/deleting_jobs_tasks',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -359,6 +375,9 @@ export function jobServiceRoutes(
validate: {
body: jobIdsSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -389,6 +408,9 @@ export function jobServiceRoutes(
params: schema.object({ indexPattern: schema.string() }),
query: schema.maybe(schema.object({ rollup: schema.maybe(schema.string()) })),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -422,6 +444,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(chartSchema),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -474,6 +499,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(chartSchema),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -522,6 +550,9 @@ export function jobServiceRoutes(
{
path: '/api/ml/jobs/all_jobs_and_group_ids',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -552,6 +583,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(lookBackProgressSchema),
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -583,17 +617,12 @@ export function jobServiceRoutes(
validate: {
body: schema.object(categorizationFieldExamplesSchema),
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
// due to the use of the _analyze endpoint which is called by the kibana user,
// basic job creation privileges are required to use this endpoint
if ((await hasPermissionToCreateJobs(request)) === false) {
throw Boom.forbidden(
'Insufficient privileges, the machine_learning_admin role is required.'
);
}
const { validateCategoryExamples } = categorizationExamplesProvider(
context.ml!.mlClient.callAsCurrentUser,
context.ml!.mlClient.callAsInternalUser
@ -644,6 +673,9 @@ export function jobServiceRoutes(
validate: {
body: schema.object(topCategoriesSchema),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -57,6 +57,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization,
validate: {
body: estimateBucketSpanSchema,
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -106,6 +109,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization,
validate: {
body: modelMemoryLimitSchema,
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -135,6 +141,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization,
validate: {
body: validateCardinalitySchema,
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -167,6 +176,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization,
validate: {
body: validateJobSchema,
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -97,6 +97,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) {
indexPatternTitle: schema.string(),
}),
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -127,6 +130,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) {
...getModuleIdParamSchema(true),
}),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -161,6 +167,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) {
params: schema.object(getModuleIdParamSchema()),
body: setupModuleBodySchema,
},
options: {
tags: ['access:ml:canCreateJob'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -218,6 +227,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) {
validate: {
params: schema.object(getModuleIdParamSchema()),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -22,6 +22,9 @@ export function notificationRoutes({ router, mlLicense }: RouteInitialization) {
{
path: '/api/ml/notification_settings',
validate: false,
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -88,6 +88,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization)
validate: {
body: anomaliesTableDataSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -117,6 +120,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization)
validate: {
body: categoryDefinitionSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -146,6 +152,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization)
validate: {
body: maxAnomalyScoreSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -175,6 +184,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization)
validate: {
body: categoryExamplesSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {
@ -204,6 +216,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization)
validate: {
body: partitionFieldValuesSchema,
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -54,6 +54,9 @@ export function systemRoutes(
validate: {
body: schema.maybe(schema.any()),
},
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {
@ -110,6 +113,9 @@ export function systemRoutes(
{
path: '/api/ml/ml_capabilities',
validate: false,
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {
@ -150,7 +156,11 @@ export function systemRoutes(
{
path: '/api/ml/ml_node_count',
validate: false,
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {
// check for basic license first for consistency with other
@ -201,6 +211,9 @@ export function systemRoutes(
{
path: '/api/ml/info',
validate: false,
options: {
tags: ['access:ml:canAccessML'],
},
},
mlLicense.basicLicenseAPIGuard(async (context, request, response) => {
try {
@ -229,6 +242,9 @@ export function systemRoutes(
validate: {
body: schema.maybe(schema.any()),
},
options: {
tags: ['access:ml:canGetJobs'],
},
},
mlLicense.fullLicenseAPIGuard(async (context, request, response) => {
try {

View file

@ -30,10 +30,6 @@ export interface SystemRouteDeps {
resolveMlCapabilities: ResolveMlCapabilities;
}
export interface JobServiceRouteDeps {
resolveMlCapabilities: ResolveMlCapabilities;
}
export interface PluginsSetup {
cloud: CloudSetup;
features: FeaturesPluginSetup;

View file

@ -91,12 +91,11 @@ export default ({ getService }: FtrProviderContext) => {
model_plot_config: { enabled: true },
},
expected: {
responseCode: 403,
responseCode: 404,
responseBody: {
statusCode: 403,
error: 'Forbidden',
message:
'[security_exception] action [cluster:admin/xpack/ml/job/put] is unauthorized for user [ml_viewer]',
statusCode: 404,
error: 'Not Found',
message: 'Not Found',
},
},
},

View file

@ -197,8 +197,8 @@ export default ({ getService }: FtrProviderContext) => {
requestBody: {},
// Note that the jobs and datafeeds are loaded async so the actual error message is not deterministic.
expected: {
responseCode: 403,
error: 'Forbidden',
responseCode: 404,
error: 'Not Found',
},
},
];

View file

@ -84,10 +84,9 @@ export default ({ getService }: FtrProviderContext) => {
startDatafeed: false,
},
expected: {
responseCode: 403,
error: 'Forbidden',
message:
'[security_exception] action [cluster:monitor/xpack/ml/info/get] is unauthorized for user [ml_unauthorized]',
responseCode: 404,
error: 'Not Found',
message: 'Not Found',
},
},
];