From 788fe2cd5d54570b7af5193f6725f7269428b99f Mon Sep 17 00:00:00 2001 From: Derek Ho Date: Tue, 21 May 2024 13:01:48 -0400 Subject: [PATCH] [Backport 2.x] Remove tenant tab when disabled via yaml (#1960) (#1965) * Remove tenant tab when disabled via yaml (#1960) --------- Signed-off-by: Derek Ho * Update snapshot Signed-off-by: Derek Ho --------- Signed-off-by: Derek Ho --- .../cypress-test-tenancy-disabled.yml | 2 +- public/apps/configuration/app-router.tsx | 81 +++++++++++-------- .../apps/configuration/panels/get-started.tsx | 68 ++++++++-------- .../tenant-list/tenant-instruction-view.tsx | 37 --------- .../panels/tenant-list/tenant-list.tsx | 9 +-- .../tenant-instruction-view.test.tsx.snap | 31 ------- .../test/tenant-instruction-view.test.tsx | 25 ------ .../tenant-list/test/tenant-list.test.tsx | 28 ------- .../__snapshots__/get-started.test.tsx.snap | 6 ++ .../panels/test/get-started.test.tsx | 6 ++ .../__snapshots__/app-router.test.tsx.snap | 58 +++---------- .../configuration/test/app-router.test.tsx | 36 ++++++--- .../configuration/test/top-nav-menu.test.tsx | 6 ++ 13 files changed, 136 insertions(+), 257 deletions(-) delete mode 100644 public/apps/configuration/panels/tenant-list/tenant-instruction-view.tsx delete mode 100644 public/apps/configuration/panels/tenant-list/test/__snapshots__/tenant-instruction-view.test.tsx.snap delete mode 100644 public/apps/configuration/panels/tenant-list/test/tenant-instruction-view.test.tsx diff --git a/.github/workflows/cypress-test-tenancy-disabled.yml b/.github/workflows/cypress-test-tenancy-disabled.yml index 024dd9cbc..d67e478a4 100644 --- a/.github/workflows/cypress-test-tenancy-disabled.yml +++ b/.github/workflows/cypress-test-tenancy-disabled.yml @@ -83,4 +83,4 @@ jobs: git clone https://github.com/opensearch-project/opensearch-dashboards-functional-test.git cd opensearch-dashboards-functional-test npm install cypress --save-dev - yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security-dashboards-plugin/inaccessible_tenancy_features.js" + yarn cypress:run-with-security --browser chrome --spec "cypress/integration/plugins/security/inaccessible_tenancy_features.js" diff --git a/public/apps/configuration/app-router.tsx b/public/apps/configuration/app-router.tsx index 2d29f2d9d..960c119d8 100644 --- a/public/apps/configuration/app-router.tsx +++ b/public/apps/configuration/app-router.tsx @@ -65,10 +65,6 @@ const ROUTE_MAP: { [key: string]: RouteItem } = { name: 'Tenants', href: buildUrl(ResourceType.tenants), }, - [ResourceType.tenantsManageTab]: { - name: 'TenantsManageTab', - href: buildUrl(ResourceType.tenantsManageTab), - }, [ResourceType.tenantsConfigureTab]: { name: '', href: buildUrl(ResourceType.tenantsConfigureTab), @@ -83,21 +79,26 @@ const ROUTE_MAP: { [key: string]: RouteItem } = { }, }; -const ROUTE_LIST = [ - ROUTE_MAP.getStarted, - ROUTE_MAP[ResourceType.auth], - ROUTE_MAP[ResourceType.roles], - ROUTE_MAP[ResourceType.users], - ROUTE_MAP[ResourceType.permissions], - ROUTE_MAP[ResourceType.tenants], - ROUTE_MAP[ResourceType.auditLogging], - ROUTE_MAP[ResourceType.tenantsConfigureTab], -]; +const getRouteList = (multitenancyEnabled: boolean) => { + return [ + ROUTE_MAP.getStarted, + ROUTE_MAP[ResourceType.auth], + ROUTE_MAP[ResourceType.roles], + ROUTE_MAP[ResourceType.users], + ROUTE_MAP[ResourceType.permissions], + ...(multitenancyEnabled ? [ROUTE_MAP[ResourceType.tenants]] : []), + ROUTE_MAP[ResourceType.auditLogging], + ]; +}; -const allNavPanelUrls = ROUTE_LIST.map((route) => route.href).concat([ - buildUrl(ResourceType.auditLogging) + SUB_URL_FOR_GENERAL_SETTINGS_EDIT, - buildUrl(ResourceType.auditLogging) + SUB_URL_FOR_COMPLIANCE_SETTINGS_EDIT, -]); +export const allNavPanelUrls = (multitenancyEnabled: boolean) => + getRouteList(multitenancyEnabled) + .map((route) => route.href) + .concat([ + buildUrl(ResourceType.auditLogging) + SUB_URL_FOR_GENERAL_SETTINGS_EDIT, + buildUrl(ResourceType.auditLogging) + SUB_URL_FOR_COMPLIANCE_SETTINGS_EDIT, + ...(multitenancyEnabled ? [buildUrl(ResourceType.tenantsConfigureTab)] : []), + ]); export function getBreadcrumbs( resourceType?: ResourceType, @@ -149,21 +150,46 @@ export const LocalCluster = { label: 'Local cluster', id: '' }; export const DataSourceContext = createContext(null); export function AppRouter(props: AppDependencies) { + const multitenancyEnabled = props.config.multitenancy.enabled; const dataSourceEnabled = !!props.depsStart.dataSource?.dataSourceEnabled; const setGlobalBreadcrumbs = flow(getBreadcrumbs, props.coreStart.chrome.setBreadcrumbs); const dataSourceFromUrl = dataSourceEnabled ? getDataSourceFromUrl() : LocalCluster; const [dataSource, setDataSource] = useState(dataSourceFromUrl); + function getTenancyRoutes() { + if (multitenancyEnabled) { + return ( + <> + { + setGlobalBreadcrumbs(ResourceType.tenants); + return ; + }} + /> + { + setGlobalBreadcrumbs(ResourceType.tenants); + return ; + }} + /> + + ); + } + return null; + } + return ( - {allNavPanelUrls.map((route) => ( + {allNavPanelUrls(multitenancyEnabled).map((route) => ( // Create different routes to update the 'selected' nav item . - + ))} @@ -254,20 +280,6 @@ export function AppRouter(props: AppDependencies) { return ; }} /> - { - setGlobalBreadcrumbs(ResourceType.tenants); - return ; - }} - /> - { - setGlobalBreadcrumbs(ResourceType.tenants); - return ; - }} - /> { @@ -275,6 +287,7 @@ export function AppRouter(props: AppDependencies) { return ; }} /> + {getTenancyRoutes()} diff --git a/public/apps/configuration/panels/get-started.tsx b/public/apps/configuration/panels/get-started.tsx index 4d3b8c461..5903f88f6 100644 --- a/public/apps/configuration/panels/get-started.tsx +++ b/public/apps/configuration/panels/get-started.tsx @@ -276,39 +276,41 @@ export function GetStarted(props: AppDependencies) { - - -

Optional: Multi-tenancy

-
- -

- By default tenancy is activated in Dashboards. Tenants in OpenSearch Dashboards are - spaces for saving index patterns, visualizations, dashboards, and other OpenSearch - Dashboards objects. -

- - - { - window.location.href = buildHashUrl(ResourceType.tenants); - }} - > - Manage Multi-tenancy - - - - { - window.location.href = buildHashUrl(ResourceType.tenantsConfigureTab); - }} - > - Configure Multi-tenancy - - - -
-
+ {props.config.multitenancy.enabled ? ( + + +

Optional: Multi-tenancy

+
+ +

+ By default tenancy is activated in Dashboards. Tenants in OpenSearch Dashboards are + spaces for saving index patterns, visualizations, dashboards, and other OpenSearch + Dashboards objects. +

+ + + { + window.location.href = buildHashUrl(ResourceType.tenants); + }} + > + Manage Multi-tenancy + + + + { + window.location.href = buildHashUrl(ResourceType.tenantsConfigureTab); + }} + > + Configure Multi-tenancy + + + +
+
+ ) : null} diff --git a/public/apps/configuration/panels/tenant-list/tenant-instruction-view.tsx b/public/apps/configuration/panels/tenant-list/tenant-instruction-view.tsx deleted file mode 100644 index d5e5ffe83..000000000 --- a/public/apps/configuration/panels/tenant-list/tenant-instruction-view.tsx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -import React from 'react'; -import { EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; - -export function TenantInstructionView() { - return ( - <> - -

Tenants

-
- - - - -

You have not enabled multi tenancy

-
- - - Contact your administrator to enable multi tenancy. - - - ); -} diff --git a/public/apps/configuration/panels/tenant-list/tenant-list.tsx b/public/apps/configuration/panels/tenant-list/tenant-list.tsx index 0b97c6ae1..bc6aa71b8 100644 --- a/public/apps/configuration/panels/tenant-list/tenant-list.tsx +++ b/public/apps/configuration/panels/tenant-list/tenant-list.tsx @@ -30,7 +30,6 @@ import { AppDependencies } from '../../../types'; import { ExternalLink } from '../../utils/display-utils'; import { DocLinks } from '../../constants'; import { getDashboardsInfo } from '../../../../utils/dashboards-info-utils'; -import { TenantInstructionView } from './tenant-instruction-view'; import { LocalCluster } from '../../app-router'; import { SecurityPluginTopNavMenu } from '../../top-nav-menu'; @@ -59,8 +58,8 @@ export function TenantList(props: TenantListProps) { <>

- Tenancy is currently disabled and users don't have access to this feature. To create, - edit tenants you must enabled tenanc throught he configure tenancy page. + Tenancy is currently disabled and users don't have access to this feature. Enable + tenancy through the configure tenancy page.

; - } - return ( <> - -

- Tenants -

-
- - -

- You have not enabled multi tenancy -

-
- - Contact your administrator to enable multi tenancy. - - -`; diff --git a/public/apps/configuration/panels/tenant-list/test/tenant-instruction-view.test.tsx b/public/apps/configuration/panels/tenant-list/test/tenant-instruction-view.test.tsx deleted file mode 100644 index 929ab0629..000000000 --- a/public/apps/configuration/panels/tenant-list/test/tenant-instruction-view.test.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -import { shallow } from 'enzyme'; -import React from 'react'; -import { TenantInstructionView } from '../tenant-instruction-view'; - -describe('Tenant instruction view', () => { - it('renders', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); - }); -}); diff --git a/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx b/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx index a00a417d8..e6f5bfbf3 100644 --- a/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx +++ b/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx @@ -20,7 +20,6 @@ import { EuiInMemoryTable } from '@elastic/eui'; import { useDeleteConfirmState } from '../../../utils/delete-confirm-modal-utils'; import { Tenant } from '../../../types'; import { TenantEditModal } from '../edit-modal'; -import { TenantInstructionView } from '../tenant-instruction-view'; import { getDashboardsInfo } from '../../../../../utils/dashboards-info-utils'; jest.mock('../../../utils/tenant-utils'); @@ -107,33 +106,6 @@ describe('Tenant list', () => { expect(component.find(EuiInMemoryTable).prop('items').length).toBe(0); }); - it('renders when multitenancy is disabled in the opensearch_dashboards.yml', () => { - (getDashboardsInfo as jest.Mock).mockImplementation(() => { - return { - multitenancy_enabled: false, - private_tenant_enabled: true, - default_tenant: '', - }; - }); - const config1 = { - multitenancy: { - enabled: false, - tenants: { - enable_private: true, - }, - }, - }; - const component = shallow( - - ); - expect(component.find(TenantInstructionView).length).toBe(0); - }); - it('fetch data error', (done) => { jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); // Hide the error message diff --git a/public/apps/configuration/panels/test/__snapshots__/get-started.test.tsx.snap b/public/apps/configuration/panels/test/__snapshots__/get-started.test.tsx.snap index 0b2126950..b7bb4bc7b 100644 --- a/public/apps/configuration/panels/test/__snapshots__/get-started.test.tsx.snap +++ b/public/apps/configuration/panels/test/__snapshots__/get-started.test.tsx.snap @@ -8,6 +8,9 @@ exports[`Get started (landing page) renders when backend configuration is disabl { ui: { backend_configurable: true, }, + multitenancy: { + enabled: true, + }, }; it('renders when backend configuration is enabled', () => { @@ -62,6 +65,9 @@ describe('Get started (landing page)', () => { ui: { backend_configurable: false, }, + multitenancy: { + enabled: true, + }, }; const component = shallow( @@ -99,10 +95,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -145,10 +137,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -191,10 +179,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -237,10 +221,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -283,10 +263,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -329,10 +305,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/auditLogging", "name": "Audit logs", }, - Object { - "href": "/tenantsConfigureTab", - "name": "", - }, ] } /> @@ -340,8 +312,8 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab
@@ -386,8 +354,8 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab @@ -432,8 +396,8 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab @@ -523,15 +483,15 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab render={[Function]} /> ({ @@ -33,23 +33,28 @@ describe('SecurityPluginTopNavMenu', () => { }, }; - const dataSourceMenuMock = jest.fn(() =>
Mock DataSourceMenu
); + const securityPluginConfigMock = { + multitenancy: { + enabled: true, + }, + ui: {}, + }; - const dataSourceManagementMock = { - ui: { - DataSourceMenu: dataSourceMenuMock, + const securityPluginConfigMockMultitenancyDisabled = { + multitenancy: { + enabled: false, }, + ui: {}, }; it('renders DataSourceMenu when dataSource is enabled', () => { - const securityPluginStartDepsMock = { - dataSource: { - dataSourceEnabled: true, - }, - }; - const wrapper = shallow( - + ); expect(wrapper).toMatchSnapshot(); @@ -67,6 +72,7 @@ describe('SecurityPluginTopNavMenu', () => { coreStart={coreStartMock} depsStart={securityPluginStartDepsMock} params={{ appBasePath: '' }} + config={securityPluginConfigMock} /> ); @@ -85,9 +91,15 @@ describe('SecurityPluginTopNavMenu', () => { coreStart={coreStartMock} depsStart={securityPluginStartDepsMock} params={{ appBasePath: '' }} + config={securityPluginConfigMock} /> ); expect(getDataSourceFromUrl).toHaveBeenCalled(); }); + + it('checks paths returned with multitenancy off vs on', () => { + expect(allNavPanelUrls(true)).toContain('/tenants'); + expect(allNavPanelUrls(false)).not.toContain('/tenants'); + }); }); diff --git a/public/apps/configuration/test/top-nav-menu.test.tsx b/public/apps/configuration/test/top-nav-menu.test.tsx index 2e2872f65..4ea26ebbd 100644 --- a/public/apps/configuration/test/top-nav-menu.test.tsx +++ b/public/apps/configuration/test/top-nav-menu.test.tsx @@ -39,11 +39,17 @@ describe('SecurityPluginTopNavMenu', () => { dataSourceEnabled: true, }, }; + const securityPluginConfigMock = { + multitenancy: { + enabled: false, + }, + }; const wrapper = render(