From eb62c990164faf8dfc45c1683b39aa1590a47b3f Mon Sep 17 00:00:00 2001 From: Abhi Kalra <99718513+abhivka7@users.noreply.github.com> Date: Sat, 6 May 2023 03:27:11 +0530 Subject: [PATCH] Fixing dynamic tenancy changes for issues 1412 (#1419) * Fixing dynamic tenancy changes for opensearchdasbhoard.yaml Signed-off-by: Abhi Kalra Co-authored-by: Abhi Kalra Co-authored-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> (cherry picked from commit c4e6c376d91b596892972696568ca2e41fb2d195) Signed-off-by: Darshit Chanpura --- .../cypress-test-tenancy-disabled.yml | 70 +++++++++++++++++++ public/apps/account/account-nav-button.tsx | 4 +- .../account/test/account-nav-button.test.tsx | 2 +- .../panels/tenant-list/manage_tab.tsx | 25 +++---- .../panels/tenant-list/tenant-list.tsx | 5 ++ .../tenant-list/test/tenant-list.test.tsx | 2 +- public/plugin.ts | 6 +- server/multitenancy/tenant_resolver.ts | 2 +- 8 files changed, 95 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/cypress-test-tenancy-disabled.yml diff --git a/.github/workflows/cypress-test-tenancy-disabled.yml b/.github/workflows/cypress-test-tenancy-disabled.yml new file mode 100644 index 000000000..c494f1390 --- /dev/null +++ b/.github/workflows/cypress-test-tenancy-disabled.yml @@ -0,0 +1,70 @@ +name: Cypress Tests Multitenancy Disabled + +on: [ push, pull_request ] + +env: + TEST_BROWSER_HEADLESS: 1 + CI: 1 + FTR_PATH: 'ftr' + START_CMD: 'node ../scripts/opensearch_dashboards --dev --no-base-path --no-watch --opensearch_security.multitenancy.enable_aggregation_view=true' + OPENSEARCH_SNAPSHOT_CMD: 'node ../scripts/opensearch snapshot' + SPEC: 'cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js,' + OPENSEARCH_VERSION: 3.0.0 + PLUGIN_NAME: opensearch-security + PLUGIN_VERSION: 3.0.0.0 + +jobs: + tests: + name: Run Cypress Tests Multitenancy Disabled + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest , windows-latest ] + runs-on: ${{ matrix.os }} + + steps: + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Checkout Branch + uses: actions/checkout@v3 + + - name: Download security plugin and create setup scripts + uses: ./.github/actions/download-plugin + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + plugin-version: ${{ env.PLUGIN_VERSION }} + + - name: Run Opensearch with A Single Plugin + uses: opensearch-project/security/.github/actions/start-opensearch-with-one-plugin@main + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + setup-script-name: setup + + - name: Run Dashboard with Security Dashboards Plugin + uses: ./.github/actions/install-dashboards + with: + plugin_name: security-dashboards-plugin + + - name: Configure and Run OpenSearch Dashboards with Cypress Test Cases + run: | + cd ./OpenSearch-Dashboards + echo 'server.host: "0.0.0.0"' >> ./config/opensearch_dashboards.yml + echo 'opensearch.hosts: ["https://localhost:9200"]' >> ./config/opensearch_dashboards.yml + echo 'opensearch.ssl.verificationMode: none' >> ./config/opensearch_dashboards.yml + echo 'opensearch.username: "kibanaserver"' >> ./config/opensearch_dashboards.yml + echo 'opensearch.password: "kibanaserver"' >> ./config/opensearch_dashboards.yml + echo 'opensearch.requestHeadersWhitelist: [ authorization,securitytenant ]' >> ./config/opensearch_dashboards.yml + echo 'opensearch_security.multitenancy.enabled: false' >> ./config/opensearch_dashboards.yml + echo 'opensearch_security.readonly_mode.roles: ["kibana_read_only"]' >> ./config/opensearch_dashboards.yml + echo 'opensearch_security.cookie.secure: false' >> ./config/opensearch_dashboards.yml + nohup yarn start --no-base-path --no-watch & + sleep 500 + 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" diff --git a/public/apps/account/account-nav-button.tsx b/public/apps/account/account-nav-button.tsx index 6da1aec11..8f67c3328 100644 --- a/public/apps/account/account-nav-button.tsx +++ b/public/apps/account/account-nav-button.tsx @@ -85,7 +85,7 @@ export function AccountNavButton(props: { }, [props.coreStart.http]); // Check if the tenant modal should be shown on load - if (isMultiTenancyEnabled && getShouldShowTenantPopup()) { + if (isMultiTenancyEnabled && getShouldShowTenantPopup() && props.config.multitenancy.enabled) { setShouldShowTenantPopup(false); showTenantSwitchPanel(); } @@ -128,7 +128,7 @@ export function AccountNavButton(props: { > View roles and identities - {isMultiTenancyEnabled && ( + {isMultiTenancyEnabled && props.config.multitenancy.enabled && ( <> {horizontalRule} diff --git a/public/apps/account/test/account-nav-button.test.tsx b/public/apps/account/test/account-nav-button.test.tsx index 543a01087..0bf24798e 100644 --- a/public/apps/account/test/account-nav-button.test.tsx +++ b/public/apps/account/test/account-nav-button.test.tsx @@ -171,6 +171,6 @@ describe('Account navigation button, multitenancy disabled', () => { currAuthType={'dummy'} /> ); - expect(setState).toBeCalledTimes(1); + expect(setState).toBeCalledTimes(0); }); }); diff --git a/public/apps/configuration/panels/tenant-list/manage_tab.tsx b/public/apps/configuration/panels/tenant-list/manage_tab.tsx index 8dc956abf..8f813f82b 100644 --- a/public/apps/configuration/panels/tenant-list/manage_tab.tsx +++ b/public/apps/configuration/panels/tenant-list/manage_tab.tsx @@ -67,7 +67,6 @@ import { showTableStatusMessage } from '../../utils/loading-spinner-utils'; import { useContextMenuState } from '../../utils/context-menu'; import { generateResourceName } from '../../utils/resource-utils'; import { DocLinks } from '../../constants'; -import { TenantInstructionView } from './tenant-instruction-view'; import { TenantList } from './tenant-list'; import { getBreadcrumbs, Route_MAP } from '../../app-router'; import { buildUrl } from '../../utils/url-builder'; @@ -92,30 +91,29 @@ export function ManageTab(props: AppDependencies) { const [isPrivateTenantEnabled, setIsPrivateTenantEnabled] = useState(false); const [dashboardsDefaultTenant, setDashboardsDefaultTenant] = useState(''); + const { http } = props.coreStart; + const fetchData = useCallback(async () => { try { setLoading(true); - const rawTenantData = await fetchTenants(props.coreStart.http); + const rawTenantData = await fetchTenants(http); const processedTenantData = transformTenantData(rawTenantData); - const activeTenant = await fetchCurrentTenant(props.coreStart.http); - const currentUser = await getCurrentUser(props.coreStart.http); + const activeTenant = await fetchCurrentTenant(http); + const currentUser = await getCurrentUser(http); setCurrentUsername(currentUser); setCurrentTenant(resolveTenantName(activeTenant, currentUser)); setTenantData(processedTenantData); - setIsMultiTenancyEnabled( - (await getDashboardsInfo(props.coreStart.http)).multitenancy_enabled - ); - setIsPrivateTenantEnabled( - (await getDashboardsInfo(props.coreStart.http)).private_tenant_enabled - ); - setDashboardsDefaultTenant((await getDashboardsInfo(props.coreStart.http)).default_tenant); + const tenancyConfig = await getDashboardsInfo(http); + setIsMultiTenancyEnabled(tenancyConfig.multitenancy_enabled); + setIsPrivateTenantEnabled(tenancyConfig.private_tenant_enabled); + setDashboardsDefaultTenant(tenancyConfig.default_tenant); } catch (e) { console.log(e); setErrorFlag(true); } finally { setLoading(false); } - }, [props.coreStart.http]); + }, [http]); React.useEffect(() => { fetchData(); @@ -479,9 +477,6 @@ export function ManageTab(props: AppDependencies) { ); }; - if (!props.config.multitenancy.enabled) { - return ; - } /* eslint-disable */ return ( <> diff --git a/public/apps/configuration/panels/tenant-list/tenant-list.tsx b/public/apps/configuration/panels/tenant-list/tenant-list.tsx index 0d12162c1..f1d3079b5 100644 --- a/public/apps/configuration/panels/tenant-list/tenant-list.tsx +++ b/public/apps/configuration/panels/tenant-list/tenant-list.tsx @@ -31,6 +31,7 @@ import { ExternalLink } from '../../utils/display-utils'; import { displayBoolean } from '../../utils/display-utils'; import { DocLinks } from '../../constants'; import { getDashboardsInfo } from '../../../../utils/dashboards-info-utils'; +import { TenantInstructionView } from './tenant-instruction-view'; interface TenantListProps extends AppDependencies { tabID: string; @@ -127,6 +128,10 @@ export function TenantList(props: TenantListProps) { )); }; + if (!props.config.multitenancy.enabled) { + return ; + } + return ( <> 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 2be979f3d..b92dd8806 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 @@ -131,7 +131,7 @@ describe('Tenant list', () => { config={config1 as any} /> ); - expect(component.find(TenantInstructionView).length).toBe(1); + expect(component.find(TenantInstructionView).length).toBe(0); }); it('fetch data error', (done) => { diff --git a/public/plugin.ts b/public/plugin.ts index d627bcece..991c00834 100644 --- a/public/plugin.ts +++ b/public/plugin.ts @@ -155,7 +155,11 @@ export class SecurityPlugin }) ); - if (multitenancyEnabled && config.multitenancy.enable_aggregation_view) { + if ( + multitenancyEnabled && + config.multitenancy.enabled && + config.multitenancy.enable_aggregation_view + ) { deps.savedObjectsManagement.columns.register( (tenantColumn as unknown) as SavedObjectsManagementColumn ); diff --git a/server/multitenancy/tenant_resolver.ts b/server/multitenancy/tenant_resolver.ts index e6c97a708..c4ca9d5d4 100755 --- a/server/multitenancy/tenant_resolver.ts +++ b/server/multitenancy/tenant_resolver.ts @@ -19,7 +19,7 @@ import { SecurityPluginConfigType } from '..'; import { GLOBAL_TENANT_SYMBOL, PRIVATE_TENANT_SYMBOL, globalTenantName } from '../../common'; export const PRIVATE_TENANTS: string[] = [PRIVATE_TENANT_SYMBOL, 'private']; -export const GLOBAL_TENANTS: string[] = ['global', GLOBAL_TENANT_SYMBOL]; +export const GLOBAL_TENANTS: string[] = ['global', GLOBAL_TENANT_SYMBOL, 'Global']; /** * Resovles the tenant the user is using. *