Skip to content

Commit

Permalink
feat: backport pr 5949 to workspace-pr-inte (opensearch-project#275)
Browse files Browse the repository at this point in the history
* feat: merge 5949

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: update snapshot

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: bootstrap error

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: unit test error

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
  • Loading branch information
SuZhou-Joe committed Mar 18, 2024
1 parent a6f2f3f commit 0644dcb
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 124 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Discover] Enhanced the data source selector with added sorting functionality ([#5609](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/5609))
- [Multiple Datasource] Add datasource picker component and use it in devtools and tutorial page when multiple datasource is enabled ([#5756](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5756))
- [Multiple Datasource] Add datasource picker to import saved object flyout when multiple data source is enabled ([#5781](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5781))
- [Multiple Datasource] Add interfaces to register add-on authentication method from plug-in module ([#5851](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5851))
- [Multiple Datasource] Able to Hide "Local Cluster" option from datasource DropDown ([#5827](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5827))
- [Multiple Datasource] Add api registry and allow it to be added into client config in data source plugin ([#5895](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5895))
- [Multiple Datasource] Concatenate data source name with index pattern name and change delimiter to double colon ([#5907](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5907))
- [Multiple Datasource] Refactor client and legacy client to use authentication registry ([#5881](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5881))
- [Multiple Datasource] Improved error handling for the search API when a null value is passed for the dataSourceId ([#5882](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5882))
- [Multiple Datasource] Hide/Show authentication method in multi data source plugin based on configuration ([#5916](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5916))
- [[Dynamic Configurations] Add support for dynamic application configurations ([#5855](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5855))
- [Workspace] Optional workspaces params in repository ([#5949](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5949))

### 🐛 Bug Fixes

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,6 @@ function defaultMapping(): IndexMapping {
},
},
},
workspaces: {
type: 'keyword',
},
permissions: {
properties: {
read: principals,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ describe('IndexMigrator', () => {
references: '7997cf5a56cc02bdc9c93361bde732b0',
type: '2f4316de49999235636386fe51dc06c1',
updated_at: '00da57df13e94e9d98437d13ace4bfe0',
workspaces: '2f4316de49999235636386fe51dc06c1',
},
},
properties: {
Expand All @@ -242,9 +241,6 @@ describe('IndexMigrator', () => {
originId: { type: 'keyword' },
type: { type: 'keyword' },
updated_at: { type: 'date' },
workspaces: {
type: 'keyword',
},
permissions: {
properties: {
library_read: {
Expand Down Expand Up @@ -387,7 +383,6 @@ describe('IndexMigrator', () => {
references: '7997cf5a56cc02bdc9c93361bde732b0',
type: '2f4316de49999235636386fe51dc06c1',
updated_at: '00da57df13e94e9d98437d13ace4bfe0',
workspaces: '2f4316de49999235636386fe51dc06c1',
},
},
properties: {
Expand All @@ -399,9 +394,6 @@ describe('IndexMigrator', () => {
originId: { type: 'keyword' },
type: { type: 'keyword' },
updated_at: { type: 'date' },
workspaces: {
type: 'keyword',
},
permissions: {
properties: {
library_read: {
Expand Down Expand Up @@ -487,7 +479,6 @@ describe('IndexMigrator', () => {
references: '7997cf5a56cc02bdc9c93361bde732b0',
type: '2f4316de49999235636386fe51dc06c1',
updated_at: '00da57df13e94e9d98437d13ace4bfe0',
workspaces: '2f4316de49999235636386fe51dc06c1',
},
},
properties: {
Expand All @@ -499,9 +490,6 @@ describe('IndexMigrator', () => {
originId: { type: 'keyword' },
type: { type: 'keyword' },
updated_at: { type: 'date' },
workspaces: {
type: 'keyword',
},
permissions: {
properties: {
library_read: {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 0 additions & 93 deletions src/core/server/saved_objects/service/lib/repository.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -941,74 +941,6 @@ describe('SavedObjectsRepository', () => {
const expectedError = expectErrorResult(obj3, { message: JSON.stringify(opensearchError) });
await bulkCreateError(obj3, opensearchError, expectedError);
});

it(`returns error when there is a conflict with an existing saved object according to workspaces`, async () => {
const obj = { ...obj3, workspaces: ['foo'] };
const response1 = {
status: 200,
docs: [
{
found: true,
_id: `${obj1.type}:${obj1.id}`,
_source: {
type: obj1.type,
workspaces: ['bar'],
},
},
{
found: true,
_id: `${obj.type}:${obj.id}`,
_source: {
type: obj.type,
workspaces: obj.workspaces,
},
},
{
found: true,
_id: `${obj2.type}:${obj2.id}`,
_source: {
type: obj2.type,
},
},
],
};
client.mget.mockResolvedValueOnce(
opensearchClientMock.createSuccessTransportRequestPromise(response1)
);
const response2 = getMockBulkCreateResponse([obj1, obj, obj2]);
client.bulk.mockResolvedValueOnce(
opensearchClientMock.createSuccessTransportRequestPromise(response2)
);

const options = { overwrite: true, workspaces: ['bar'] };
const result = await savedObjectsRepository.bulkCreate([obj1, obj, obj2], options);
expect(client.bulk).toHaveBeenCalled();
expect(client.mget).toHaveBeenCalled();

const body1 = {
docs: [
expect.objectContaining({ _id: `${obj1.type}:${obj1.id}` }),
expect.objectContaining({ _id: `${obj.type}:${obj.id}` }),
expect.objectContaining({ _id: `${obj2.type}:${obj2.id}` }),
],
};
expect(client.mget).toHaveBeenCalledWith(
expect.objectContaining({ body: body1 }),
expect.anything()
);
const body2 = [...expectObjArgs(obj1)];
expect(client.bulk).toHaveBeenCalledWith(
expect.objectContaining({ body: body2 }),
expect.anything()
);
expect(result).toEqual({
saved_objects: [
expectSuccess(obj1),
expectErrorConflict(obj, { metadata: { isNotOverwritable: true } }),
expectErrorConflict(obj2, { metadata: { isNotOverwritable: true } }),
],
});
});
});

describe('migration', () => {
Expand Down Expand Up @@ -2289,16 +2221,6 @@ describe('SavedObjectsRepository', () => {
expect.anything()
);
});

it(`accepts permissions property`, async () => {
await createSuccess(type, attributes, { id, permissions });
expect(client.create).toHaveBeenCalledWith(
expect.objectContaining({
body: expect.objectContaining({ permissions }),
}),
expect.anything()
);
});
});

describe('errors', () => {
Expand Down Expand Up @@ -2359,21 +2281,6 @@ describe('SavedObjectsRepository', () => {
expect(client.get).toHaveBeenCalled();
});

it(`throws error when there is a conflict with an existing workspaces saved object`, async () => {
const response = getMockGetResponse({ workspaces: ['foo'], id });
client.get.mockResolvedValueOnce(
opensearchClientMock.createSuccessTransportRequestPromise(response)
);
await expect(
savedObjectsRepository.create('dashboard', attributes, {
id,
overwrite: true,
workspaces: ['bar'],
})
).rejects.toThrowError(createConflictError('dashboard', id));
expect(client.get).toHaveBeenCalled();
});

it.todo(`throws when automatic index creation fails`);

it.todo(`throws when an unexpected failure occurs`);
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/saved_objects/service/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ export class SavedObjectsRepository {
migrationVersion,
updated_at: time,
...(Array.isArray(references) && { references }),
...(Array.isArray(workspaces) && { workspaces }),
...(permissions && { permissions }),
...(Array.isArray(workspaces) && { workspaces }),
});

const raw = this._serializer.savedObjectToRaw(migrated as SavedObjectSanitizedDoc);
Expand Down Expand Up @@ -476,8 +476,8 @@ export class SavedObjectsRepository {
updated_at: time,
references: object.references || [],
originId: object.originId,
...(savedObjectWorkspaces && { workspaces: savedObjectWorkspaces }),
...(object.permissions && { permissions: object.permissions }),
...(savedObjectWorkspaces && { workspaces: savedObjectWorkspaces }),
}) as SavedObjectSanitizedDoc
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,19 @@ function getClauseForType(
},
};
}

/**
* Gets the clause that will filter for the workspace.
*/
function getClauseForWorkspace(workspace: string) {
if (!workspace) {
return {};
if (workspace === '*') {
return {
bool: {
must: {
match_all: {},
},
},
};
}

return {
Expand Down
4 changes: 4 additions & 0 deletions src/core/server/saved_objects/service/saved_objects_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions {
initialNamespaces?: string[];
/** permission control describe by ACL object */
permissions?: Permissions;
/**
* workspaces the new created objects belong to
*/
workspaces?: string[];
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/workspace/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { registerRoutes } from './routes';
import { WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID } from '../common/constants';
import { WorkspaceConflictSavedObjectsClientWrapper } from './saved_objects/saved_objects_wrapper_for_check_workspace_conflict';
import { cleanWorkspaceId, getWorkspaceIdFromUrl } from '../../../core/server/utils';
import { WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID } from '../common/constants';
import { WorkspaceConflictSavedObjectsClientWrapper } from './saved_objects/saved_objects_wrapper_for_check_workspace_conflict';

export class WorkspacePlugin implements Plugin<WorkspacePluginSetup, WorkspacePluginStart> {
private readonly logger: Logger;
Expand Down Expand Up @@ -57,6 +59,13 @@ export class WorkspacePlugin implements Plugin<WorkspacePluginSetup, WorkspacePl
this.workspaceConflictControl.wrapperFactory
);
this.proxyWorkspaceTrafficToRealHandler(core);
this.workspaceConflictControl = new WorkspaceConflictSavedObjectsClientWrapper();

core.savedObjects.addClientWrapper(
-1,
WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID,
this.workspaceConflictControl.wrapperFactory
);

registerRoutes({
http: core.http,
Expand Down

0 comments on commit 0644dcb

Please sign in to comment.