[ML] [8.8] fix saved object sync check for jobs in different space (#160402)

Manual backport of https://github.com/elastic/kibana/pull/160266
This commit is contained in:
James Gowdy 2023-06-23 15:21:30 +01:00 committed by GitHub
parent 4298c3ce94
commit 913ea518cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 6 deletions

View file

@ -248,8 +248,7 @@ export function mlSavedObjectServiceFactory(
filter,
};
const jobs = await _savedObjectsClientFindMemo<JobObject>(options);
return jobs.saved_objects;
return (await internalSavedObjectsClient.find<JobObject>(options)).saved_objects;
}
async function addDatafeed(datafeedId: string, jobId: string) {

View file

@ -84,6 +84,7 @@ export default ({ getService }: FtrProviderContext) => {
await ml.api.deleteAnomalyDetectionJobES(job.job_id);
}
await ml.api.cleanMlIndices();
await ml.testResources.cleanMLSavedObjects();
});
it('succeeds for ML Poweruser and keeps user annotations', async () => {

View file

@ -22,10 +22,16 @@ export default ({ getService }: FtrProviderContext) => {
const adJobId3 = 'fq_single_3';
const adJobIdES = 'fq_single_es';
const idSpace1 = 'space1';
const idSpace2 = 'space2';
async function runSyncRequest(user: USER, expectedStatusCode: number) {
async function runSyncRequest(
user: USER,
expectedStatusCode: number,
simulate: boolean = false,
space: string = idSpace1
) {
const { body, status } = await supertest
.get(`/s/${idSpace1}/api/ml/saved_objects/sync`)
.get(`/s/${space}/api/ml/saved_objects/sync?simulate=${simulate}`)
.auth(user, ml.securityCommon.getPasswordForUser(user))
.set(COMMON_REQUEST_HEADERS);
ml.api.assertResponseStatusCode(expectedStatusCode, status, body);
@ -36,10 +42,11 @@ export default ({ getService }: FtrProviderContext) => {
async function runSyncCheckRequest(
user: USER,
mlSavedObjectType: MlSavedObjectType,
expectedStatusCode: number
expectedStatusCode: number,
space: string = idSpace1
) {
const { body, status } = await supertest
.post(`/s/${idSpace1}/api/ml/saved_objects/sync_check`)
.post(`/s/${space}/api/ml/saved_objects/sync_check`)
.auth(user, ml.securityCommon.getPasswordForUser(user))
.set(COMMON_REQUEST_HEADERS)
.send({ mlSavedObjectType });
@ -52,11 +59,13 @@ export default ({ getService }: FtrProviderContext) => {
beforeEach(async () => {
await ml.api.initSavedObjects();
await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] });
await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] });
await ml.testResources.setKibanaTimeZoneToUTC();
});
afterEach(async () => {
await spacesService.delete(idSpace1);
await spacesService.delete(idSpace2);
await ml.api.cleanMlIndices();
await ml.testResources.cleanMLSavedObjects();
});
@ -131,6 +140,122 @@ export default ({ getService }: FtrProviderContext) => {
});
});
it('should simulate syncing saved objects', async () => {
// check to see if a sync is needed
const syncNeeded = await runSyncCheckRequest(
USER.ML_POWERUSER_ALL_SPACES,
'anomaly-detector',
200
);
expect(syncNeeded.result).to.eql(false, 'sync should not be needed');
// prepare test data
await ml.api.createAnomalyDetectionJobES(
ml.commonConfig.getADFqSingleMetricJobConfig(adJobId1)
);
await ml.api.createDatafeedES(ml.commonConfig.getADFqDatafeedConfig(adJobId1));
// check to see if a sync is needed
const syncNeeded2 = await runSyncCheckRequest(
USER.ML_POWERUSER_ALL_SPACES,
'anomaly-detector',
200
);
expect(syncNeeded2.result).to.eql(true, 'sync should be needed');
// run the sync request and verify the response
const body = await runSyncRequest(USER.ML_POWERUSER_ALL_SPACES, 200, true);
expect(body).to.eql({
datafeedsAdded: {},
datafeedsRemoved: {},
savedObjectsCreated: {
'anomaly-detector': {
[adJobId1]: { success: true },
},
},
savedObjectsDeleted: {},
});
const syncNeeded3 = await runSyncCheckRequest(
USER.ML_POWERUSER_ALL_SPACES,
'anomaly-detector',
200
);
expect(syncNeeded3.result).to.eql(true, 'sync should still be needed');
const body2 = await runSyncRequest(USER.ML_POWERUSER_ALL_SPACES, 200, true);
expect(body2).to.eql({
datafeedsAdded: {},
datafeedsRemoved: {},
savedObjectsCreated: {
'anomaly-detector': {
[adJobId1]: { success: true },
},
},
savedObjectsDeleted: {},
});
});
// add a job to space 2, then check that it is not synced from space 1
it('should not sync saved objects in different space', async () => {
// check to see if a sync is needed
const syncNeeded = await runSyncCheckRequest(
USER.ML_POWERUSER_ALL_SPACES,
'anomaly-detector',
200
);
expect(syncNeeded.result).to.eql(false, 'sync should not be needed');
// prepare test data
await ml.api.createAnomalyDetectionJob(
ml.commonConfig.getADFqSingleMetricJobConfig(adJobId1),
idSpace2
);
await ml.api.createDatafeed(ml.commonConfig.getADFqDatafeedConfig(adJobId1), idSpace2);
// check to see if a sync is needed
const syncNeeded2 = await runSyncCheckRequest(
USER.ML_POWERUSER_ALL_SPACES,
'anomaly-detector',
200
);
expect(syncNeeded2.result).to.eql(
false,
'sync should be needed for a user who can see all spaces'
);
const syncNeeded3 = await runSyncCheckRequest(
USER.ML_POWERUSER_SPACE1,
'anomaly-detector',
200
);
expect(syncNeeded3.result).to.eql(
false,
'sync should be needed for a user who can only see space 1'
);
// check sync outputs
const body = await runSyncRequest(USER.ML_POWERUSER_ALL_SPACES, 200, true);
expect(body).to.eql({
datafeedsAdded: {},
datafeedsRemoved: {},
savedObjectsCreated: {},
savedObjectsDeleted: {},
});
const body2 = await runSyncRequest(USER.ML_POWERUSER_SPACE1, 200, true);
expect(body2).to.eql({
datafeedsAdded: {},
datafeedsRemoved: {},
savedObjectsCreated: {},
savedObjectsDeleted: {},
});
});
it('should sync datafeeds after recreation in ES with different name', async () => {
// check to see if a sync is needed
const syncNeeded = await runSyncCheckRequest(