From 0644dcb71d8ebbf8df122dcb5675769ba66316a4 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Mon, 4 Mar 2024 16:28:16 +0800 Subject: [PATCH] feat: backport pr 5949 to workspace-pr-inte (#275) * feat: merge 5949 Signed-off-by: SuZhou-Joe * feat: update snapshot Signed-off-by: SuZhou-Joe * fix: bootstrap error Signed-off-by: SuZhou-Joe * fix: unit test error Signed-off-by: SuZhou-Joe --------- Signed-off-by: SuZhou-Joe --- CHANGELOG.md | 9 ++ .../build_active_mappings.test.ts.snap | 8 -- .../migrations/core/build_active_mappings.ts | 3 - .../migrations/core/index_migrator.test.ts | 12 --- ...pensearch_dashboards_migrator.test.ts.snap | 4 - .../service/lib/repository.test.js | 93 ------------------- .../saved_objects/service/lib/repository.ts | 4 +- .../service/lib/search_dsl/query_params.ts | 11 ++- .../service/saved_objects_client.ts | 4 + src/plugins/workspace/server/plugin.ts | 9 ++ 10 files changed, 33 insertions(+), 124 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0adcbc43f515..df9fe2cf3497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/core/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap b/src/core/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap index 09e8ad8b5407..6f67893104e7 100644 --- a/src/core/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap +++ b/src/core/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap @@ -14,7 +14,6 @@ Object { "references": "7997cf5a56cc02bdc9c93361bde732b0", "type": "2f4316de49999235636386fe51dc06c1", "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "workspaces": "2f4316de49999235636386fe51dc06c1", }, }, "dynamic": "strict", @@ -112,9 +111,6 @@ Object { "updated_at": Object { "type": "date", }, - "workspaces": Object { - "type": "keyword", - }, }, } `; @@ -134,7 +130,6 @@ Object { "thirdType": "510f1f0adb69830cf8a1c5ce2923ed82", "type": "2f4316de49999235636386fe51dc06c1", "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "workspaces": "2f4316de49999235636386fe51dc06c1", }, }, "dynamic": "strict", @@ -249,9 +244,6 @@ Object { "updated_at": Object { "type": "date", }, - "workspaces": Object { - "type": "keyword", - }, }, } `; diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts index fac64bf78b01..efedd9351a22 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts @@ -219,9 +219,6 @@ function defaultMapping(): IndexMapping { }, }, }, - workspaces: { - type: 'keyword', - }, permissions: { properties: { read: principals, diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts index de2e14572278..f22234fc8996 100644 --- a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts @@ -231,7 +231,6 @@ describe('IndexMigrator', () => { references: '7997cf5a56cc02bdc9c93361bde732b0', type: '2f4316de49999235636386fe51dc06c1', updated_at: '00da57df13e94e9d98437d13ace4bfe0', - workspaces: '2f4316de49999235636386fe51dc06c1', }, }, properties: { @@ -242,9 +241,6 @@ describe('IndexMigrator', () => { originId: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, - workspaces: { - type: 'keyword', - }, permissions: { properties: { library_read: { @@ -387,7 +383,6 @@ describe('IndexMigrator', () => { references: '7997cf5a56cc02bdc9c93361bde732b0', type: '2f4316de49999235636386fe51dc06c1', updated_at: '00da57df13e94e9d98437d13ace4bfe0', - workspaces: '2f4316de49999235636386fe51dc06c1', }, }, properties: { @@ -399,9 +394,6 @@ describe('IndexMigrator', () => { originId: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, - workspaces: { - type: 'keyword', - }, permissions: { properties: { library_read: { @@ -487,7 +479,6 @@ describe('IndexMigrator', () => { references: '7997cf5a56cc02bdc9c93361bde732b0', type: '2f4316de49999235636386fe51dc06c1', updated_at: '00da57df13e94e9d98437d13ace4bfe0', - workspaces: '2f4316de49999235636386fe51dc06c1', }, }, properties: { @@ -499,9 +490,6 @@ describe('IndexMigrator', () => { originId: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, - workspaces: { - type: 'keyword', - }, permissions: { properties: { library_read: { diff --git a/src/core/server/saved_objects/migrations/opensearch_dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap b/src/core/server/saved_objects/migrations/opensearch_dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap index 2748ad2eaf6a..5e39af788d79 100644 --- a/src/core/server/saved_objects/migrations/opensearch_dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap +++ b/src/core/server/saved_objects/migrations/opensearch_dashboards/__snapshots__/opensearch_dashboards_migrator.test.ts.snap @@ -14,7 +14,6 @@ Object { "references": "7997cf5a56cc02bdc9c93361bde732b0", "type": "2f4316de49999235636386fe51dc06c1", "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "workspaces": "2f4316de49999235636386fe51dc06c1", }, }, "dynamic": "strict", @@ -120,9 +119,6 @@ Object { "updated_at": Object { "type": "date", }, - "workspaces": Object { - "type": "keyword", - }, }, } `; diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index 5189c754a326..3dfa293c0dc0 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -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', () => { @@ -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', () => { @@ -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`); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 46a3d62e6e82..42d45ea73e16 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -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); @@ -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 ), }; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts index 186457145103..0d056f624bf1 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts @@ -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 { diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index 1b268e033d97..7ebe525df0ed 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -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[]; } /** diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index b7fd9017d798..145aacaf9bb8 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -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 { private readonly logger: Logger; @@ -57,6 +59,13 @@ export class WorkspacePlugin implements Plugin