Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.x] [Workspace] Handle data sources and advanced settings as global object. #6611

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/6524.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- [Workspace] Handle data sources and advanced settings as global object. ([#6524](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6524))
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,30 @@

import { SavedObject } from 'src/core/types';
import { isEqual } from 'lodash';
import packageInfo from '../../../../../../package.json';
import * as osdTestServer from '../../../../../core/test_helpers/osd_server';
import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../../../data_source/common';

const dashboard: Omit<SavedObject, 'id'> = {
type: 'dashboard',
attributes: {},
references: [],
};

const dataSource: Omit<SavedObject, 'id'> = {
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
attributes: {
title: 'test data source',
},
references: [],
};

const advancedSettings: Omit<SavedObject, 'id'> = {
type: 'config',
attributes: {},
references: [],
};

interface WorkspaceAttributes {
id: string;
name?: string;
Expand All @@ -32,6 +48,9 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
adjustTimeout: (t: number) => jest.setTimeout(t),
settings: {
osd: {
data_source: {
enabled: true,
},
workspace: {
enabled: true,
},
Expand Down Expand Up @@ -145,6 +164,40 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
});
});

it('create disallowed types within workspace', async () => {
const createDataSourceResult = await osdTestServer.request
.post(root, `/api/saved_objects/${dataSource.type}`)
.send({
attributes: dataSource.attributes,
workspaces: [createdFooWorkspace.id],
})
.expect(400);

expect(createDataSourceResult.body).toMatchInlineSnapshot(`
Object {
"error": "Bad Request",
"message": "Unsupported type in workspace: 'data-source' is not allowed to be created in workspace.",
"statusCode": 400,
}
`);

const createConfigResult = await osdTestServer.request
.post(root, `/api/saved_objects/config`)
.send({
attributes: advancedSettings.attributes,
workspaces: [createdFooWorkspace.id],
})
.expect(400);

expect(createConfigResult.body).toMatchInlineSnapshot(`
Object {
"error": "Bad Request",
"message": "Unsupported type in workspace: 'config' is not allowed to be created in workspace.",
"statusCode": 400,
}
`);
});

it('bulk create', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down Expand Up @@ -254,6 +307,80 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
);
});

it('bulk create with disallowed types in workspace', async () => {
await clearFooAndBar();

// import advanced settings and data sources should throw error
const createResultFoo = await osdTestServer.request
.post(root, `/w/${createdFooWorkspace.id}/api/saved_objects/_bulk_create`)
.send([
{
...dataSource,
id: 'foo',
},
{
...advancedSettings,
id: packageInfo.version,
},
])
.expect(200);
expect(createResultFoo.body.saved_objects[0].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'data-source' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
expect(createResultFoo.body.saved_objects[1].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'config' is not allowed to be imported in workspace.",
statusCode: 400,
})
);

// Data source should not be created
await osdTestServer.request
.get(
root,
`/w/${createdFooWorkspace.id}/api/saved_objects/${DATA_SOURCE_SAVED_OBJECT_TYPE}/foo`
)
.expect(404);

// Advanced settings should not be created within workspace
const findAdvancedSettings = await osdTestServer.request
.get(root, `/w/${createdFooWorkspace.id}/api/saved_objects/_find?type=config`)
.expect(200);
expect(findAdvancedSettings.body.total).toEqual(0);
});

it('bulk create with disallowed types out of workspace', async () => {
await clearFooAndBar();

// import advanced settings and data sources should throw error
const createResultFoo = await osdTestServer.request
.post(root, `/api/saved_objects/_bulk_create`)
.send([
{
...advancedSettings,
id: packageInfo.version,
},
])
.expect(200);
expect(createResultFoo.body).toEqual({
saved_objects: [
expect.objectContaining({
type: advancedSettings.type,
}),
],
});

const findAdvancedSettings = await osdTestServer.request
.get(root, `/api/saved_objects/_find?type=${advancedSettings.type}`)
.expect(200);
expect(findAdvancedSettings.body.total).toEqual(1);
});

it('checkConflicts when importing ndjson', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SavedObject } from '../../../../core/public';
import { httpServerMock, savedObjectsClientMock, coreMock } from '../../../../core/server/mocks';
import { WorkspaceConflictSavedObjectsClientWrapper } from './saved_objects_wrapper_for_check_workspace_conflict';
import { SavedObjectsSerializer } from '../../../../core/server';
import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../../../plugins/data_source/common';

describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
const requestHandlerContext = coreMock.createRequestHandlerContext();
Expand Down Expand Up @@ -115,6 +116,38 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
})
);
});

it(`Should throw error when trying to create disallowed types in workspace`, async () => {
await expect(
wrapperClient.create(
DATA_SOURCE_SAVED_OBJECT_TYPE,
{
name: 'foo',
},

{
workspaces: ['foo'],
}
)
).rejects.toMatchInlineSnapshot(
`[Error: Unsupported type in workspace: 'data-source' is not allowed to be created in workspace.]`
);

await expect(
wrapperClient.create(
'config',
{
name: 'foo',
},

{
workspaces: ['foo'],
}
)
).rejects.toMatchInlineSnapshot(
`[Error: Unsupported type in workspace: 'config' is not allowed to be created in workspace.]`
);
});
});

describe('bulkCreateWithWorkspaceConflictCheck', () => {
Expand Down Expand Up @@ -291,6 +324,42 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
}
`);
});
it(`Should return error when trying to create disallowed types within a workspace`, async () => {
mockedClient.bulkCreate.mockResolvedValueOnce({ saved_objects: [] });
const result = await wrapperClient.bulkCreate(
[
getSavedObject({
type: 'config',
id: 'foo',
}),
getSavedObject({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
id: 'foo',
}),
],
{
workspaces: ['foo'],
}
);

expect(mockedClient.bulkCreate).toBeCalledWith([], {
workspaces: ['foo'],
});
expect(result.saved_objects[0].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'config' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
expect(result.saved_objects[1].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'data-source' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
});
});

describe('checkConflictWithWorkspaceConflictCheck', () => {
Expand Down Expand Up @@ -393,4 +462,20 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
`);
});
});

describe('find', () => {
beforeEach(() => {
mockedClient.find.mockClear();
});

it(`workspaces parameters should be removed when finding data sources`, async () => {
await wrapperClient.find({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
workspaces: ['foo'],
});
expect(mockedClient.find).toBeCalledWith({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
});
});
});
});
Loading
Loading