[ML] Fixing endpoint schema for can_delete_job endpoint (#86436)

* [ML] Fixing endpoint schema for can_delete_job endpoint

* changing get to post in docs

* renaming canUntag

* fixing typo

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
James Gowdy 2020-12-21 12:17:53 +00:00 committed by GitHub
parent c05533ebbd
commit 6d72042ca4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 30 deletions

View file

@ -21,7 +21,7 @@ export interface SyncSavedObjectResponse {
export interface CanDeleteJobResponse {
[jobId: string]: {
canDelete: boolean;
canUntag: boolean;
canRemoveFromSpace: boolean;
};
}
@ -41,5 +41,5 @@ export interface DeleteJobCheckResponse {
export interface DeleteJobPermission {
canDelete: boolean;
canUntag: boolean;
canRemoveFromSpace: boolean;
}

View file

@ -36,31 +36,31 @@ interface ModalContentReturnType {
interface JobCheckRespSummary {
canDelete: boolean;
canUntag: boolean;
canRemoveFromSpace: boolean;
canTakeAnyAction: boolean;
}
function getRespSummary(resp: CanDeleteJobResponse): JobCheckRespSummary {
const jobsChecked = Object.keys(resp);
// Default to first job's permissions
const { canDelete, canUntag } = resp[jobsChecked[0]];
const { canDelete, canRemoveFromSpace } = resp[jobsChecked[0]];
let canTakeAnyAction = true;
if (jobsChecked.length > 1) {
// Check all jobs and make sure they have the same permissions - otherwise no action can be taken
canTakeAnyAction = jobsChecked.every(
(id) => resp[id].canDelete === canDelete && resp[id].canUntag === canUntag
(id) => resp[id].canDelete === canDelete && resp[id].canRemoveFromSpace === canRemoveFromSpace
);
}
return { canDelete, canUntag, canTakeAnyAction };
return { canDelete, canRemoveFromSpace, canTakeAnyAction };
}
function getModalContent(
jobIds: string[],
respSummary: JobCheckRespSummary
): ModalContentReturnType {
const { canDelete, canUntag, canTakeAnyAction } = respSummary;
const { canDelete, canRemoveFromSpace, canTakeAnyAction } = respSummary;
if (canTakeAnyAction === false) {
return {
@ -116,7 +116,7 @@ function getModalContent(
</EuiText>
),
};
} else if (canUntag) {
} else if (canRemoveFromSpace) {
return {
buttonText: (
<FormattedMessage
@ -173,8 +173,8 @@ export const DeleteJobCheckModal: FC<Props> = ({
// Do the spaces check and set the content for the modal and buttons depending on results
canDeleteJob(jobType, jobIds).then((resp) => {
const respSummary = getRespSummary(resp);
const { canDelete, canUntag, canTakeAnyAction } = respSummary;
if (canTakeAnyAction && canDelete && !canUntag) {
const { canDelete, canRemoveFromSpace, canTakeAnyAction } = respSummary;
if (canTakeAnyAction && canDelete && !canRemoveFromSpace) {
// Go straight to delete flow if that's the only action available
canDeleteCallback();
return;
@ -260,7 +260,7 @@ export const DeleteJobCheckModal: FC<Props> = ({
<EuiFlexItem grow={false}>
{!hasUntagged &&
jobCheckRespSummary?.canTakeAnyAction &&
jobCheckRespSummary?.canUntag &&
jobCheckRespSummary?.canRemoveFromSpace &&
jobCheckRespSummary?.canDelete && (
<EuiButtonEmpty
isLoading={isUntagging}
@ -277,7 +277,7 @@ export const DeleteJobCheckModal: FC<Props> = ({
size="s"
onClick={
jobCheckRespSummary?.canTakeAnyAction &&
jobCheckRespSummary?.canUntag &&
jobCheckRespSummary?.canRemoveFromSpace &&
!jobCheckRespSummary?.canDelete
? onUntagClick
: onClick

View file

@ -151,7 +151,7 @@
"RemoveJobsFromSpaces",
"RemoveJobsFromCurrentSpace",
"JobsSpaces",
"DeleteJobCheck",
"CanDeleteJob",
"TrainedModels",
"GetTrainedModel",

View file

@ -12,8 +12,8 @@ import {
jobsAndCurrentSpace,
syncJobObjects,
jobTypeSchema,
canDeleteJobSchema,
} from './schemas/saved_objects';
import { jobIdsSchema } from './schemas/job_service_schema';
import { spacesUtilsProvider } from '../lib/spaces_utils';
import { JobType } from '../../common/types/saved_objects';
@ -284,13 +284,23 @@ export function savedObjectsRoutes(
/**
* @apiGroup JobSavedObjects
*
* @api {get} /api/ml/saved_objects/delete_job_check Check whether user can delete a job
* @apiName DeleteJobCheck
* @api {post} /api/ml/saved_objects/can_delete_job Check whether user can delete a job
* @apiName CanDeleteJob
* @apiDescription Check the user's ability to delete jobs. Returns whether they are able
* to fully delete the job and whether they are able to remove it from
* the current space.
* Note, this is only for enabling UI controls. A user calling endpoints
* directly will still be able to delete or remove the job from a space.
*
* @apiSchema (body) jobIdsSchema (params) jobTypeSchema
* @apiSchema (params) jobTypeSchema
* @apiSchema (body) jobIdsSchema
* @apiSuccessExample {json} Error-Response:
* {
* "my_job": {
* "canDelete": false,
* "canRemoveFromSpace": true
* }
* }
*
*/
router.post(
@ -298,7 +308,7 @@ export function savedObjectsRoutes(
path: '/api/ml/saved_objects/can_delete_job/{jobType}',
validate: {
params: jobTypeSchema,
body: jobIdsSchema,
body: canDeleteJobSchema,
},
options: {
tags: ['access:ml:canGetJobs', 'access:ml:canGetDataFrameAnalytics'],

View file

@ -22,3 +22,8 @@ export const syncJobObjects = schema.object({ simulate: schema.maybe(schema.bool
export const jobTypeSchema = schema.object({
jobType: schema.string(),
});
export const canDeleteJobSchema = schema.object({
/** List of job IDs. */
jobIds: schema.arrayOf(schema.maybe(schema.string())),
});

View file

@ -180,7 +180,7 @@ export function checksFactory(
return jobIds.reduce((results, jobId) => {
results[jobId] = {
canDelete: false,
canUntag: false,
canRemoveFromSpace: false,
};
return results;
}, {} as DeleteJobCheckResponse);
@ -191,7 +191,7 @@ export function checksFactory(
return jobIds.reduce((results, jobId) => {
results[jobId] = {
canDelete: true,
canUntag: false,
canRemoveFromSpace: false,
};
return results;
}, {} as DeleteJobCheckResponse);
@ -208,7 +208,7 @@ export function checksFactory(
// job saved object not found
results[jobId] = {
canDelete: false,
canUntag: false,
canRemoveFromSpace: false,
};
return results;
}
@ -220,7 +220,7 @@ export function checksFactory(
if (canCreateGlobalJobs && isGlobalJob) {
results[jobId] = {
canDelete: true,
canUntag: false,
canRemoveFromSpace: false,
};
return results;
}
@ -229,20 +229,20 @@ export function checksFactory(
if (isGlobalJob) {
results[jobId] = {
canDelete: false,
canUntag: false,
canRemoveFromSpace: false,
};
return results;
}
// jobs with are in individual spaces can only be untagged
// from current space if the job is in more than 1 space
const canUntag = namespaces.length > 1;
const canRemoveFromSpace = namespaces.length > 1;
// job is in individual spaces, user cannot see all of them - untag only, no delete
if (namespaces.includes('?')) {
results[jobId] = {
canDelete: false,
canUntag,
canRemoveFromSpace,
};
return results;
}
@ -250,7 +250,7 @@ export function checksFactory(
// job is individual spaces, user can see all of them - delete and option to untag
results[jobId] = {
canDelete: true,
canUntag,
canRemoveFromSpace,
};
return results;
}, {} as DeleteJobCheckResponse);

View file

@ -75,7 +75,7 @@ export default ({ getService }: FtrProviderContext) => {
idSpace1
);
expect(body).to.eql({ [adJobIdSpace12]: { canDelete: false, canUntag: true } });
expect(body).to.eql({ [adJobIdSpace12]: { canDelete: false, canRemoveFromSpace: true } });
});
it('job in individual spaces, all spaces user can delete and untag', async () => {
@ -87,7 +87,7 @@ export default ({ getService }: FtrProviderContext) => {
idSpace1
);
expect(body).to.eql({ [adJobIdSpace12]: { canDelete: true, canUntag: true } });
expect(body).to.eql({ [adJobIdSpace12]: { canDelete: true, canRemoveFromSpace: true } });
});
it('job in * space, single space user can not untag or delete', async () => {
@ -99,7 +99,7 @@ export default ({ getService }: FtrProviderContext) => {
idSpace1
);
expect(body).to.eql({ [adJobIdStarSpace]: { canDelete: false, canUntag: false } });
expect(body).to.eql({ [adJobIdStarSpace]: { canDelete: false, canRemoveFromSpace: false } });
});
it('job in * space, all spaces user can delete but not untag', async () => {
@ -111,7 +111,7 @@ export default ({ getService }: FtrProviderContext) => {
idStarSpace
);
expect(body).to.eql({ [adJobIdStarSpace]: { canDelete: true, canUntag: false } });
expect(body).to.eql({ [adJobIdStarSpace]: { canDelete: true, canRemoveFromSpace: false } });
});
});
};