diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 248c91158679d..feca8da654920 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -22500,8 +22500,6 @@ "xpack.idxMgmt.goToDiscover.discoverIndexButtonLabel": "Découvrir les index", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "Montrer {indexName} dans Discover", "xpack.idxMgmt.home.appTitle": "Gestion des index", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesDescription": "Vérification des privilèges…", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesErrorMessage": "Erreur lors de la récupération des privilèges utilisateur depuis le serveur.", "xpack.idxMgmt.home.componentTemplates.confirmButtonLabel": "Supprimer {numComponentTemplatesToDelete, plural, one {le modèle de composant} other {les modèles de composants} }", "xpack.idxMgmt.home.componentTemplates.deleteModal.cancelButtonLabel": "Annuler", "xpack.idxMgmt.home.componentTemplates.deleteModal.deleteDescription": "Vous êtes sur le point de supprimer {numComponentTemplatesToDelete, plural, one {ce modèle de composant} other {ces modèles de composants} } :", @@ -22510,8 +22508,6 @@ "xpack.idxMgmt.home.componentTemplates.deleteModal.multipleErrorsNotificationMessageText": "Erreur lors de la suppression de {count} modèles de composants", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, one {# modèle de composant supprimé} other {# modèles de composants supprimés}}", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteSingleNotificationMessageText": "Le modèle de composant \"{componentTemplateName}\" a bien été supprimé", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeDescription": "Pour utiliser les modèles de composants, vous devez posséder {privilegesCount, plural, one {ce privilège de cluster} other {ces privilèges de cluster}} : {missingPrivileges}.", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeTitle": "Privilèges de cluster requis", "xpack.idxMgmt.home.componentTemplates.emptyPromptButtonLabel": "Créer un modèle de composant", "xpack.idxMgmt.home.componentTemplates.emptyPromptDescription": "Par exemple, vous pouvez créer un modèle de composant pour les paramètres d'index réutilisables dans tous les modèles d'index.", "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "En savoir plus.", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 2df6d17cb8406..c1e31464be0f8 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -22357,8 +22357,6 @@ "xpack.idxMgmt.goToDiscover.discoverIndexButtonLabel": "Discoverインデックス", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "Discoverで{indexName}を表示", "xpack.idxMgmt.home.appTitle": "インデックス管理", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesDescription": "権限を確認中…", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesErrorMessage": "サーバーからユーザー特権を取得中にエラーが発生。", "xpack.idxMgmt.home.componentTemplates.confirmButtonLabel": "{numComponentTemplatesToDelete, plural, other {個のコンポーネントテンプレート} }を削除", "xpack.idxMgmt.home.componentTemplates.deleteModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.home.componentTemplates.deleteModal.deleteDescription": "{numComponentTemplatesToDelete, plural, one {このコンポーネントテンプレート} other {これらのコンポーネントテンプレート} }を削除しようとしています。", @@ -22367,8 +22365,6 @@ "xpack.idxMgmt.home.componentTemplates.deleteModal.multipleErrorsNotificationMessageText": "{count}個のコンポーネントテンプレートの削除エラー", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, other {# 個のコンポーネントテンプレート}}を削除しました", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteSingleNotificationMessageText": "コンポーネントテンプレート''{componentTemplateName}''を削除しました", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeDescription": "コンポーネントテンプレートを使用するには、{privilegesCount, plural, one {このクラスター特権} other {これらのクラスター特権}}が必要です:{missingPrivileges}。", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeTitle": "クラスターの権限が必要です", "xpack.idxMgmt.home.componentTemplates.emptyPromptButtonLabel": "コンポーネントテンプレートを作成", "xpack.idxMgmt.home.componentTemplates.emptyPromptDescription": "たとえば、インデックステンプレート全体で再利用できるインデックス設定のコンポーネントテンプレートを作成できます。", "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "詳細情報", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 8a15e2785a759..2f5ae043ba772 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -22436,8 +22436,6 @@ "xpack.idxMgmt.goToDiscover.discoverIndexButtonLabel": "Discover 索引", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "在 Discover 中显示 {indexName}", "xpack.idxMgmt.home.appTitle": "索引管理", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesDescription": "正在检查权限……", - "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesErrorMessage": "从服务器获取用户权限时出错。", "xpack.idxMgmt.home.componentTemplates.confirmButtonLabel": "删除{numComponentTemplatesToDelete, plural, other {组件模板} }", "xpack.idxMgmt.home.componentTemplates.deleteModal.cancelButtonLabel": "取消", "xpack.idxMgmt.home.componentTemplates.deleteModal.deleteDescription": "您即将删除{numComponentTemplatesToDelete, plural, other {以下组件模板} }:", @@ -22446,8 +22444,6 @@ "xpack.idxMgmt.home.componentTemplates.deleteModal.multipleErrorsNotificationMessageText": "删除 {count} 个组件模板时出错", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteMultipleNotificationMessageText": "已删除 {numSuccesses, plural, other {# 个组件模板}}", "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteSingleNotificationMessageText": "已删除组件模板“{componentTemplateName}”", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeDescription": "要使用“组件模板”,必须具有{privilegesCount, plural, other {以下集群权限}}:{missingPrivileges}。", - "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeTitle": "需要集群权限", "xpack.idxMgmt.home.componentTemplates.emptyPromptButtonLabel": "创建组件模板", "xpack.idxMgmt.home.componentTemplates.emptyPromptDescription": "例如,您可以为可在多个索引模板上重复使用的索引设置创建组件模板。", "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "了解详情。", diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index 24f641ae2833f..535e0219bf823 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -95,6 +95,7 @@ const appDependencies = { monitor: true, manageEnrich: true, monitorEnrich: true, + manageIndexTemplates: true, }, } as any; diff --git a/x-pack/plugins/index_management/public/application/app_context.tsx b/x-pack/plugins/index_management/public/application/app_context.tsx index 3573ae33812d9..1019d580dec5d 100644 --- a/x-pack/plugins/index_management/public/application/app_context.tsx +++ b/x-pack/plugins/index_management/public/application/app_context.tsx @@ -84,6 +84,7 @@ export interface AppDependencies { monitor: boolean; manageEnrich: boolean; monitorEnrich: boolean; + manageIndexTemplates: boolean; }; } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx deleted file mode 100644 index 88da23007a4f6..0000000000000 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/auth_provider.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { AuthorizationProvider } from '../shared_imports'; -import { useComponentTemplatesContext } from '../component_templates_context'; - -export const ComponentTemplatesAuthProvider: React.FunctionComponent<{ - children?: React.ReactNode; -}> = ({ children }) => { - const { httpClient, apiBasePath } = useComponentTemplatesContext(); - - return ( - - {children} - - ); -}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx index 30cec15545610..e3583b41c1108 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list_container.tsx @@ -11,8 +11,6 @@ import { RouteComponentProps } from 'react-router-dom'; import qs from 'query-string'; import { useExecutionContext } from '../shared_imports'; import { useComponentTemplatesContext } from '../component_templates_context'; -import { ComponentTemplatesAuthProvider } from './auth_provider'; -import { ComponentTemplatesWithPrivileges } from './with_privileges'; import { ComponentTemplateList } from './component_template_list'; interface MatchParams { @@ -39,14 +37,10 @@ export const ComponentTemplateListContainer: React.FunctionComponent< const filter = urlParams.filter ?? ''; return ( - - - - - + ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx deleted file mode 100644 index 5ae9b2f14ec82..0000000000000 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FormattedMessage } from '@kbn/i18n-react'; -import React, { FunctionComponent } from 'react'; - -import { - PageLoading, - PageError, - useAuthorizationContext, - WithPrivileges, - NotAuthorizedSection, -} from '../shared_imports'; -import { APP_CLUSTER_REQUIRED_PRIVILEGES } from '../constants'; - -export const ComponentTemplatesWithPrivileges: FunctionComponent<{ - children?: React.ReactNode; -}> = ({ children }) => { - const { apiError } = useAuthorizationContext(); - - if (apiError) { - return ( - - } - error={apiError} - /> - ); - } - - return ( - `cluster.${privilege}`)} - > - {({ isLoading, hasPrivileges, privilegesMissing }) => { - if (isLoading) { - return ( - - - - ); - } - - if (!hasPrivileges) { - return ( - - } - message={ - - } - /> - ); - } - - return <>{children}; - }} - - ); -}; diff --git a/x-pack/plugins/index_management/public/application/mount_management_section.ts b/x-pack/plugins/index_management/public/application/mount_management_section.ts index 83cf620a0e8e0..003f5279ae520 100644 --- a/x-pack/plugins/index_management/public/application/mount_management_section.ts +++ b/x-pack/plugins/index_management/public/application/mount_management_section.ts @@ -73,7 +73,8 @@ export function getIndexManagementDependencies({ }): AppDependencies { const { docLinks, application, uiSettings, settings } = core; const { url } = startDependencies.share; - const { monitor, manageEnrich, monitorEnrich } = application.capabilities.index_management; + const { monitor, manageEnrich, monitorEnrich, manageIndexTemplates } = + application.capabilities.index_management; return { core: { @@ -109,6 +110,7 @@ export function getIndexManagementDependencies({ monitor: !!monitor, manageEnrich: !!manageEnrich, monitorEnrich: !!monitorEnrich, + manageIndexTemplates: !!manageIndexTemplates, }, }; } diff --git a/x-pack/plugins/index_management/public/application/sections/home/home.tsx b/x-pack/plugins/index_management/public/application/sections/home/home.tsx index 2d0fc7d4ec108..53ef500f597e0 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/home.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/home.tsx @@ -66,7 +66,10 @@ export const IndexManagementHome: React.FunctionComponent ), }, - { + ]; + + if (privs.manageIndexTemplates) { + tabs.push({ id: Section.ComponentTemplates, name: ( ), - }, - ]; + }); + } if (privs.monitorEnrich) { tabs.push({ @@ -139,14 +142,16 @@ export const IndexManagementHome: React.FunctionComponent - + {privs.manageIndexTemplates && ( + + )} {privs.monitorEnrich && ( )} diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index 06adcc75d80b3..35996a43e2cd6 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -105,8 +105,12 @@ export class IndexMgmtUIPlugin const { fleet, usageCollection, management, cloud } = plugins; this.capabilities$.subscribe((capabilities) => { - const { monitor, manageEnrich, monitorEnrich } = capabilities.index_management; - if (this.config.isIndexManagementUiEnabled && (monitor || manageEnrich || monitorEnrich)) { + const { monitor, manageEnrich, monitorEnrich, manageIndexTemplates } = + capabilities.index_management; + if ( + this.config.isIndexManagementUiEnabled && + (monitor || manageEnrich || monitorEnrich || manageIndexTemplates) + ) { management.sections.section.data.registerApp({ id: PLUGIN.id, title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), diff --git a/x-pack/plugins/index_management/server/plugin.ts b/x-pack/plugins/index_management/server/plugin.ts index ab6b058cddc78..d6689f02255bc 100644 --- a/x-pack/plugins/index_management/server/plugin.ts +++ b/x-pack/plugins/index_management/server/plugin.ts @@ -46,6 +46,10 @@ export class IndexMgmtServerPlugin implements Plugin { - const routeContextMock = { - core: { - elasticsearch: { - client: { - asCurrentUser: { - security: { - hasPrivileges, - }, - }, - }, - }, - }, - } as unknown as RequestHandlerContext; - - return routeContextMock; -}; - -describe('GET privileges', () => { - let routeHandler: RequestHandler; - - beforeEach(() => { - const router = httpService.createRouter(); - - registerPrivilegesRoute({ - router, - config: { - isSecurityEnabled: () => true, - isLegacyTemplatesEnabled: true, - isIndexStatsEnabled: true, - isSizeAndDocCountEnabled: false, - isDataStreamStatsEnabled: true, - enableMappingsSourceFieldSection: true, - enableTogglingDataRetention: true, - enableProjectLevelRetentionChecks: false, - }, - indexDataEnricher: mockedIndexDataEnricher, - lib: { - handleEsError: jest.fn(), - }, - }); - - routeHandler = router.get.mock.calls[0][1]; - }); - - it('should return the correct response when a user has privileges', async () => { - const privilegesResponseMock = { - username: 'elastic', - has_all_requested: true, - cluster: { manage_index_templates: true }, - index: {}, - application: {}, - }; - - const routeContextMock = mockRouteContext({ - hasPrivileges: jest.fn().mockResolvedValueOnce(privilegesResponseMock), - }); - - const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); - - expect(response.payload).toEqual({ - hasAllPrivileges: true, - missingPrivileges: { - cluster: [], - }, - }); - }); - - it('should return the correct response when a user does not have privileges', async () => { - const privilegesResponseMock = { - username: 'elastic', - has_all_requested: false, - cluster: { manage_index_templates: false }, - index: {}, - application: {}, - }; - - const routeContextMock = mockRouteContext({ - hasPrivileges: jest.fn().mockResolvedValueOnce(privilegesResponseMock), - }); - - const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); - - expect(response.payload).toEqual({ - hasAllPrivileges: false, - missingPrivileges: { - cluster: ['manage_index_templates'], - }, - }); - }); - - describe('With security disabled', () => { - beforeEach(() => { - const router = httpService.createRouter(); - - registerPrivilegesRoute({ - router, - config: { - isSecurityEnabled: () => false, - isLegacyTemplatesEnabled: true, - isIndexStatsEnabled: true, - isSizeAndDocCountEnabled: false, - isDataStreamStatsEnabled: true, - enableMappingsSourceFieldSection: true, - enableTogglingDataRetention: true, - enableProjectLevelRetentionChecks: false, - }, - indexDataEnricher: mockedIndexDataEnricher, - lib: { - handleEsError: jest.fn(), - }, - }); - - routeHandler = router.get.mock.calls[0][1]; - }); - - it('should return the default privileges response', async () => { - const routeContextMock = mockRouteContext({ - hasPrivileges: jest.fn(), - }); - - const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); - - expect(response.payload).toEqual({ - hasAllPrivileges: true, - missingPrivileges: { - cluster: [], - }, - }); - }); - }); -}); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts deleted file mode 100644 index a053eb44657cb..0000000000000 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Privileges } from '@kbn/es-ui-shared-plugin/public'; -import { RouteDependencies } from '../../../types'; -import { addBasePath } from '..'; - -const extractMissingPrivileges = (privilegesObject: { [key: string]: boolean } = {}): string[] => - Object.keys(privilegesObject).reduce((privileges: string[], privilegeName: string): string[] => { - if (!privilegesObject[privilegeName]) { - privileges.push(privilegeName); - } - return privileges; - }, []); - -export const registerPrivilegesRoute = ({ - router, - config, - lib: { handleEsError }, -}: RouteDependencies) => { - router.get( - { - path: addBasePath('/component_templates/privileges'), - validate: false, - }, - async (context, request, response) => { - const privilegesResult: Privileges = { - hasAllPrivileges: true, - missingPrivileges: { - cluster: [], - }, - }; - - // Skip the privileges check if security is not enabled - if (!config.isSecurityEnabled()) { - return response.ok({ body: privilegesResult }); - } - - const { client } = (await context.core).elasticsearch; - - try { - const { has_all_requested: hasAllPrivileges, cluster } = - await client.asCurrentUser.security.hasPrivileges({ - body: { - cluster: ['manage_index_templates'], - }, - }); - - if (!hasAllPrivileges) { - privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster); - } - - privilegesResult.hasAllPrivileges = hasAllPrivileges; - return response.ok({ body: privilegesResult }); - } catch (error) { - return handleEsError({ error, response }); - } - } - ); -}; diff --git a/x-pack/test/api_integration/apis/management/index_management/component_templates.ts b/x-pack/test/api_integration/apis/management/index_management/component_templates.ts index fb57f0813d843..e325f4bbfa588 100644 --- a/x-pack/test/api_integration/apis/management/index_management/component_templates.ts +++ b/x-pack/test/api_integration/apis/management/index_management/component_templates.ts @@ -10,13 +10,11 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { componentTemplatesApi } from './lib/component_templates.api'; import { componentTemplateHelpers } from './lib/component_template.helpers'; -import { API_BASE_PATH } from './constants'; const CACHE_TEMPLATES = true; export default function ({ getService }: FtrProviderContext) { const log = getService('log'); - const supertest = getService('supertest'); const { createComponentTemplate, @@ -395,21 +393,6 @@ export default function ({ getService }: FtrProviderContext) { }); }); - describe('Privileges', () => { - it('should return privileges result', async () => { - const uri = `${API_BASE_PATH}/component_templates/privileges`; - - const { body } = await supertest.get(uri).set('kbn-xsrf', 'xxx').expect(200); - - expect(body).to.eql({ - hasAllPrivileges: true, - missingPrivileges: { - cluster: [], - }, - }); - }); - }); - describe('Get datastreams', () => { const COMPONENT_NAME = 'test_get_component_template_datastreams'; const COMPONENT = { diff --git a/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts b/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts index d72aadd9dbb1a..66a0a0f33d545 100644 --- a/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts +++ b/x-pack/test_serverless/functional/test_suites/common/management/index_management/component_templates.ts @@ -13,94 +13,125 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['svlCommonPage', 'common', 'indexManagement', 'header']); const browser = getService('browser'); - const security = getService('security'); + const samlAuth = getService('samlAuth'); const testSubjects = getService('testSubjects'); const es = getService('es'); const TEST_COMPONENT_TEMPLATE = '.a_test_component_template'; describe('Index component templates', function () { - before(async () => { - await security.testUser.setRoles(['index_management_user']); - await pageObjects.svlCommonPage.loginAsAdmin(); - }); + describe('with access', () => { + before(async () => { + await pageObjects.svlCommonPage.loginAsAdmin(); + }); - beforeEach(async () => { - await pageObjects.common.navigateToApp('indexManagement'); - // Navigate to the index templates tab - await pageObjects.indexManagement.changeTabs('component_templatesTab'); - await pageObjects.header.waitUntilLoadingHasFinished(); - }); + beforeEach(async () => { + await pageObjects.common.navigateToApp('indexManagement'); + // Navigate to the index templates tab + await pageObjects.indexManagement.changeTabs('component_templatesTab'); + await pageObjects.header.waitUntilLoadingHasFinished(); + }); - it('renders the component templates tab', async () => { - const url = await browser.getCurrentUrl(); - expect(url).to.contain(`/component_templates`); - }); + it('renders the component templates tab', async () => { + const url = await browser.getCurrentUrl(); + expect(url).to.contain(`/component_templates`); + }); - describe('Component templates list', () => { - before(async () => { - await es.cluster.putComponentTemplate({ - name: TEST_COMPONENT_TEMPLATE, - body: { - template: { - settings: { - index: { - number_of_shards: 1, + describe('Component templates list', () => { + before(async () => { + await es.cluster.putComponentTemplate({ + name: TEST_COMPONENT_TEMPLATE, + body: { + template: { + settings: { + index: { + number_of_shards: 1, + }, }, }, }, - }, + }); }); - }); - after(async () => { - await es.cluster.deleteComponentTemplate( - { name: TEST_COMPONENT_TEMPLATE }, - { ignore: [404] } - ); + after(async () => { + await es.cluster.deleteComponentTemplate( + { name: TEST_COMPONENT_TEMPLATE }, + { ignore: [404] } + ); + }); + + it('Displays the test component template in the list', async () => { + const templates = await testSubjects.findAll('componentTemplateTableRow'); + + const getTemplateName = async (template: WebElementWrapper) => { + const templateNameElement = await template.findByTestSubject('templateDetailsLink'); + return await templateNameElement.getVisibleText(); + }; + + const componentTemplateList = await Promise.all( + templates.map((template) => getTemplateName(template)) + ); + + const newComponentTemplateExists = Boolean( + componentTemplateList.find((templateName) => templateName === TEST_COMPONENT_TEMPLATE) + ); + + expect(newComponentTemplateExists).to.be(true); + }); }); - it('Displays the test component template in the list', async () => { - const templates = await testSubjects.findAll('componentTemplateTableRow'); + describe('Create component template', () => { + after(async () => { + await es.cluster.deleteComponentTemplate( + { name: TEST_COMPONENT_TEMPLATE }, + { ignore: [404] } + ); + }); - const getTemplateName = async (template: WebElementWrapper) => { - const templateNameElement = await template.findByTestSubject('templateDetailsLink'); - return await templateNameElement.getVisibleText(); - }; + it('Creates component template', async () => { + await testSubjects.click('createPipelineButton'); - const componentTemplateList = await Promise.all( - templates.map((template) => getTemplateName(template)) - ); + await testSubjects.setValue('nameField', TEST_COMPONENT_TEMPLATE); - const newComponentTemplateExists = Boolean( - componentTemplateList.find((templateName) => templateName === TEST_COMPONENT_TEMPLATE) - ); + // Finish wizard flow + await testSubjects.click('nextButton'); + await testSubjects.click('nextButton'); + await testSubjects.click('nextButton'); + await testSubjects.click('nextButton'); + await testSubjects.click('nextButton'); - expect(newComponentTemplateExists).to.be(true); + expect(await testSubjects.getVisibleText('title')).to.contain(TEST_COMPONENT_TEMPLATE); + }); }); }); - describe('Create component template', () => { - after(async () => { - await es.cluster.deleteComponentTemplate( - { name: TEST_COMPONENT_TEMPLATE }, - { ignore: [404] } - ); + describe('no access', () => { + this.tags(['skipSvlOblt', 'skipMKI']); + before(async () => { + await samlAuth.setCustomRole({ + elasticsearch: { + cluster: ['monitor'], + indices: [{ names: ['*'], privileges: ['all'] }], + }, + kibana: [ + { + base: ['all'], + feature: {}, + spaces: ['*'], + }, + ], + }); + await pageObjects.svlCommonPage.loginWithCustomRole(); + await pageObjects.common.navigateToApp('indexManagement'); + await pageObjects.header.waitUntilLoadingHasFinished(); }); - it('Creates component template', async () => { - await testSubjects.click('createPipelineButton'); - - await testSubjects.setValue('nameField', TEST_COMPONENT_TEMPLATE); - - // Finish wizard flow - await testSubjects.click('nextButton'); - await testSubjects.click('nextButton'); - await testSubjects.click('nextButton'); - await testSubjects.click('nextButton'); - await testSubjects.click('nextButton'); + after(async () => { + await samlAuth.deleteCustomRole(); + }); - expect(await testSubjects.getVisibleText('title')).to.contain(TEST_COMPONENT_TEMPLATE); + it('hides the component templates tab', async () => { + await testSubjects.missingOrFail('component_templatesTab'); }); }); });