mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Index Management] Disable legacy index templates (#163518)
This commit is contained in:
parent
e12ad9785c
commit
97f44c1e50
27 changed files with 259 additions and 26 deletions
|
@ -32,8 +32,11 @@ xpack.remote_clusters.enabled: false
|
|||
xpack.snapshot_restore.enabled: false
|
||||
xpack.license_management.enabled: false
|
||||
|
||||
# Disable index management actions from the UI
|
||||
# Management team UI configurations
|
||||
# Disable index actions from the Index Management UI
|
||||
xpack.index_management.enableIndexActions: false
|
||||
# Disable legacy index templates from Index Management UI
|
||||
xpack.index_management.enableLegacyTemplates: false
|
||||
|
||||
# Keep deeplinks visible so that they are shown in the sidenav
|
||||
dev_tools.deeplinks.navLinkStatus: visible
|
||||
|
|
|
@ -240,6 +240,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.ilm.ui.enabled (boolean)',
|
||||
'xpack.index_management.ui.enabled (boolean)',
|
||||
'xpack.index_management.enableIndexActions (any)',
|
||||
'xpack.index_management.enableLegacyTemplates (any)',
|
||||
'xpack.infra.sources.default.fields.message (array)',
|
||||
/**
|
||||
* xpack.infra.logs is conditional and will resolve to an object of properties
|
||||
|
|
|
@ -53,7 +53,7 @@ POST %25%7B%5B%40metadata%5D%5Bbeat%5D%7D-%25%7B%5B%40metadata%5D%5Bversion%5D%7
|
|||
|
||||
### Quick steps for testing
|
||||
|
||||
By default, **legacy index templates** are not shown in the UI. Make them appear by creating one in Console:
|
||||
**Legacy index templates** are only shown in the UI on stateful *and* if a user has existing legacy index templates. You can test this functionality by creating one in Console:
|
||||
|
||||
```
|
||||
PUT _template/template_1
|
||||
|
@ -62,6 +62,8 @@ PUT _template/template_1
|
|||
}
|
||||
```
|
||||
|
||||
On serverless, Elasticsearch does not support legacy index templates and therefore this functionality is disabled in Kibana via the config `xpack.index_management.enableLegacyTemplates`. For more details, see [#163518](https://github.com/elastic/kibana/pull/163518).
|
||||
|
||||
To test **Cloud-managed templates**:
|
||||
|
||||
1. Add `cluster.metadata.managed_index_templates` setting via Dev Tools:
|
||||
|
|
|
@ -56,6 +56,11 @@ const appDependencies = {
|
|||
executionContext: executionContextServiceMock.createStartContract(),
|
||||
},
|
||||
plugins: {},
|
||||
// Default stateful configuration
|
||||
config: {
|
||||
enableLegacyTemplates: true,
|
||||
enableIndexActions: true,
|
||||
},
|
||||
} as any;
|
||||
|
||||
export const kibanaVersion = new SemVer(MAJOR_VERSION);
|
||||
|
@ -82,7 +87,6 @@ export const WithAppDependencies =
|
|||
(props: any) => {
|
||||
httpService.setup(httpSetup);
|
||||
const mergedDependencies = merge({}, appDependencies, overridingDependencies);
|
||||
|
||||
return (
|
||||
<KibanaReactContextProvider>
|
||||
<AppContextProvider value={mergedDependencies}>
|
||||
|
|
|
@ -225,11 +225,11 @@ describe('<IndexManagementHome />', () => {
|
|||
]);
|
||||
httpRequestsMockHelpers.setReloadIndicesResponse({ indexNames: [indexNameA, indexNameB] });
|
||||
|
||||
testBed = await setup(httpSetup, {
|
||||
enableIndexActions: true,
|
||||
await act(async () => {
|
||||
testBed = await setup(httpSetup);
|
||||
});
|
||||
const { component, find } = testBed;
|
||||
|
||||
const { component, find } = testBed;
|
||||
component.update();
|
||||
|
||||
find('indexTableIndexNameLink').at(0).simulate('click');
|
||||
|
@ -270,8 +270,8 @@ describe('<IndexManagementHome />', () => {
|
|||
});
|
||||
|
||||
test('should be able to open a closed index', async () => {
|
||||
testBed = await setup(httpSetup, {
|
||||
enableIndexActions: true,
|
||||
await act(async () => {
|
||||
testBed = await setup(httpSetup);
|
||||
});
|
||||
const { component, find, actions } = testBed;
|
||||
|
||||
|
|
|
@ -168,7 +168,11 @@ describe('index table', () => {
|
|||
},
|
||||
plugins: {},
|
||||
url: urlServiceMock,
|
||||
enableIndexActions: true,
|
||||
// Default stateful configuration
|
||||
config: {
|
||||
enableLegacyTemplates: true,
|
||||
enableIndexActions: true,
|
||||
},
|
||||
};
|
||||
|
||||
component = (
|
||||
|
@ -515,8 +519,8 @@ describe('index table', () => {
|
|||
|
||||
describe('Common index actions', () => {
|
||||
beforeEach(() => {
|
||||
// Mock initialization of services
|
||||
setupMockComponent({ enableIndexActions: false });
|
||||
// Mock initialization of services; set enableIndexActions=false to verify config behavior
|
||||
setupMockComponent({ config: { enableIndexActions: false, enableLegacyTemplates: true } });
|
||||
});
|
||||
|
||||
test('Common index actions should be hidden when feature is turned off', async () => {
|
||||
|
|
|
@ -44,6 +44,10 @@ export interface AppDependencies {
|
|||
httpService: HttpService;
|
||||
notificationService: NotificationService;
|
||||
};
|
||||
config: {
|
||||
enableIndexActions: boolean;
|
||||
enableLegacyTemplates: boolean;
|
||||
};
|
||||
history: ScopedHistory;
|
||||
setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
|
||||
uiSettings: IUiSettingsClient;
|
||||
|
@ -52,7 +56,6 @@ export interface AppDependencies {
|
|||
docLinks: DocLinksStart;
|
||||
kibanaVersion: SemVer;
|
||||
theme$: Observable<CoreTheme>;
|
||||
enableIndexActions: boolean;
|
||||
}
|
||||
|
||||
export const AppContextProvider = ({
|
||||
|
|
|
@ -53,7 +53,8 @@ export async function mountManagementSection(
|
|||
extensionsService: ExtensionsService,
|
||||
isFleetEnabled: boolean,
|
||||
kibanaVersion: SemVer,
|
||||
enableIndexActions: boolean = true
|
||||
enableIndexActions: boolean = true,
|
||||
enableLegacyTemplates: boolean = true
|
||||
) {
|
||||
const { element, setBreadcrumbs, history, theme$ } = params;
|
||||
const [core, startDependencies] = await coreSetup.getStartServices();
|
||||
|
@ -95,7 +96,10 @@ export async function mountManagementSection(
|
|||
uiMetricService,
|
||||
extensionsService,
|
||||
},
|
||||
enableIndexActions,
|
||||
config: {
|
||||
enableIndexActions,
|
||||
enableLegacyTemplates,
|
||||
},
|
||||
history,
|
||||
setBreadcrumbs,
|
||||
uiSettings,
|
||||
|
|
|
@ -49,7 +49,9 @@ export class IndexActionsContextMenu extends Component {
|
|||
this.setState({ isActionConfirmed });
|
||||
};
|
||||
panels({ services: { extensionsService }, core: { getUrlForApp } }) {
|
||||
const { enableIndexActions } = this.context;
|
||||
const {
|
||||
config: { enableIndexActions },
|
||||
} = this.context;
|
||||
|
||||
const {
|
||||
closeIndices,
|
||||
|
|
|
@ -19,6 +19,7 @@ import { getTemplateDetailsLink } from '../../services/routing';
|
|||
import { saveTemplate, useLoadIndexTemplate } from '../../services/api';
|
||||
import { getIsLegacyFromQueryParams } from '../../lib/index_templates';
|
||||
import { attemptToURIDecode } from '../../../shared_imports';
|
||||
import { useAppContext } from '../../app_context';
|
||||
|
||||
interface MatchParams {
|
||||
name: string;
|
||||
|
@ -32,7 +33,11 @@ export const TemplateClone: React.FunctionComponent<RouteComponentProps<MatchPar
|
|||
history,
|
||||
}) => {
|
||||
const decodedTemplateName = attemptToURIDecode(name)!;
|
||||
const isLegacy = getIsLegacyFromQueryParams(location);
|
||||
const {
|
||||
config: { enableLegacyTemplates },
|
||||
} = useAppContext();
|
||||
// We don't expect the `legacy` query to be used when legacy templates are disabled, however, we add the `enableLegacyTemplates` check as a safeguard
|
||||
const isLegacy = enableLegacyTemplates && getIsLegacyFromQueryParams(location);
|
||||
|
||||
const [isSaving, setIsSaving] = useState<boolean>(false);
|
||||
const [saveError, setSaveError] = useState<any>(null);
|
||||
|
|
|
@ -18,12 +18,17 @@ import { TemplateForm } from '../../components';
|
|||
import { breadcrumbService } from '../../services/breadcrumbs';
|
||||
import { saveTemplate } from '../../services/api';
|
||||
import { getTemplateDetailsLink } from '../../services/routing';
|
||||
import { useAppContext } from '../../app_context';
|
||||
|
||||
export const TemplateCreate: React.FunctionComponent<RouteComponentProps> = ({ history }) => {
|
||||
const [isSaving, setIsSaving] = useState<boolean>(false);
|
||||
const [saveError, setSaveError] = useState<any>(null);
|
||||
const {
|
||||
config: { enableLegacyTemplates },
|
||||
} = useAppContext();
|
||||
const search = parse(useLocation().search.substring(1));
|
||||
const isLegacy = Boolean(search.legacy);
|
||||
// We don't expect the `legacy` query to be used when legacy templates are disabled, however, we add the `enableLegacyTemplates` check as a safeguard
|
||||
const isLegacy = enableLegacyTemplates && Boolean(search.legacy);
|
||||
|
||||
const onSave = async (template: TemplateDeserialized) => {
|
||||
const { name } = template;
|
||||
|
|
|
@ -23,6 +23,7 @@ import { useLoadIndexTemplate, updateTemplate } from '../../services/api';
|
|||
import { getTemplateDetailsLink } from '../../services/routing';
|
||||
import { TemplateForm } from '../../components';
|
||||
import { getIsLegacyFromQueryParams } from '../../lib/index_templates';
|
||||
import { useAppContext } from '../../app_context';
|
||||
|
||||
interface MatchParams {
|
||||
name: string;
|
||||
|
@ -36,7 +37,12 @@ export const TemplateEdit: React.FunctionComponent<RouteComponentProps<MatchPara
|
|||
history,
|
||||
}) => {
|
||||
const decodedTemplateName = attemptToURIDecode(name)!;
|
||||
const isLegacy = getIsLegacyFromQueryParams(location);
|
||||
const {
|
||||
config: { enableLegacyTemplates },
|
||||
} = useAppContext();
|
||||
|
||||
// We don't expect the `legacy` query to be used when legacy templates are disabled, however, we add the enableLegacyTemplates check as a safeguard
|
||||
const isLegacy = enableLegacyTemplates && getIsLegacyFromQueryParams(location);
|
||||
|
||||
const [isSaving, setIsSaving] = useState<boolean>(false);
|
||||
const [saveError, setSaveError] = useState<any>(null);
|
||||
|
|
|
@ -39,6 +39,7 @@ export class IndexMgmtUIPlugin {
|
|||
const {
|
||||
ui: { enabled: isIndexManagementUiEnabled },
|
||||
enableIndexActions,
|
||||
enableLegacyTemplates,
|
||||
} = this.ctx.config.get<ClientConfigType>();
|
||||
|
||||
if (isIndexManagementUiEnabled) {
|
||||
|
@ -57,7 +58,8 @@ export class IndexMgmtUIPlugin {
|
|||
this.extensionsService,
|
||||
Boolean(fleet),
|
||||
kibanaVersion,
|
||||
enableIndexActions
|
||||
enableIndexActions,
|
||||
enableLegacyTemplates
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -29,4 +29,5 @@ export interface ClientConfigType {
|
|||
enabled: boolean;
|
||||
};
|
||||
enableIndexActions?: boolean;
|
||||
enableLegacyTemplates?: boolean;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,14 @@ const schemaLatest = schema.object(
|
|||
schema.boolean({ defaultValue: true }),
|
||||
schema.never()
|
||||
),
|
||||
enableLegacyTemplates: schema.conditional(
|
||||
schema.contextRef('serverless'),
|
||||
true,
|
||||
// Legacy templates functionality is disabled in serverless; refer to the serverless.yml file as the source of truth
|
||||
// We take this approach in order to have a central place (serverless.yml) for serverless config across Kibana
|
||||
schema.boolean({ defaultValue: true }),
|
||||
schema.never()
|
||||
),
|
||||
},
|
||||
{ defaultValue: undefined }
|
||||
);
|
||||
|
@ -38,6 +46,7 @@ const configLatest: PluginConfigDescriptor<IndexManagementConfig> = {
|
|||
exposeToBrowser: {
|
||||
ui: true,
|
||||
enableIndexActions: true,
|
||||
enableLegacyTemplates: true,
|
||||
},
|
||||
schema: schemaLatest,
|
||||
deprecations: () => [],
|
||||
|
|
|
@ -12,6 +12,7 @@ import { Dependencies } from './types';
|
|||
import { ApiRoutes } from './routes';
|
||||
import { IndexDataEnricher } from './services';
|
||||
import { handleEsError } from './shared_imports';
|
||||
import { IndexManagementConfig } from './config';
|
||||
|
||||
export interface IndexManagementPluginSetup {
|
||||
indexDataEnricher: {
|
||||
|
@ -22,10 +23,12 @@ export interface IndexManagementPluginSetup {
|
|||
export class IndexMgmtServerPlugin implements Plugin<IndexManagementPluginSetup, void, any, any> {
|
||||
private readonly apiRoutes: ApiRoutes;
|
||||
private readonly indexDataEnricher: IndexDataEnricher;
|
||||
private readonly config: IndexManagementConfig;
|
||||
|
||||
constructor(initContext: PluginInitializerContext) {
|
||||
this.apiRoutes = new ApiRoutes();
|
||||
this.indexDataEnricher = new IndexDataEnricher();
|
||||
this.config = initContext.config.get();
|
||||
}
|
||||
|
||||
setup(
|
||||
|
@ -51,6 +54,7 @@ export class IndexMgmtServerPlugin implements Plugin<IndexManagementPluginSetup,
|
|||
router: http.createRouter(),
|
||||
config: {
|
||||
isSecurityEnabled: () => security !== undefined && security.license.isEnabled(),
|
||||
isLegacyTemplatesEnabled: this.config.enableLegacyTemplates,
|
||||
},
|
||||
indexDataEnricher: this.indexDataEnricher,
|
||||
lib: {
|
||||
|
|
|
@ -46,6 +46,7 @@ describe('GET privileges', () => {
|
|||
router,
|
||||
config: {
|
||||
isSecurityEnabled: () => true,
|
||||
isLegacyTemplatesEnabled: true,
|
||||
},
|
||||
indexDataEnricher: mockedIndexDataEnricher,
|
||||
lib: {
|
||||
|
@ -112,6 +113,7 @@ describe('GET privileges', () => {
|
|||
router,
|
||||
config: {
|
||||
isSecurityEnabled: () => false,
|
||||
isLegacyTemplatesEnabled: true,
|
||||
},
|
||||
indexDataEnricher: mockedIndexDataEnricher,
|
||||
lib: {
|
||||
|
|
|
@ -17,7 +17,7 @@ import { getCloudManagedTemplatePrefix } from '../../../lib/get_managed_template
|
|||
import { RouteDependencies } from '../../../types';
|
||||
import { addBasePath } from '..';
|
||||
|
||||
export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDependencies) {
|
||||
export function registerGetAllRoute({ router, config, lib: { handleEsError } }: RouteDependencies) {
|
||||
router.get(
|
||||
{ path: addBasePath('/index_templates'), validate: false },
|
||||
async (context, request, response) => {
|
||||
|
@ -25,17 +25,24 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep
|
|||
|
||||
try {
|
||||
const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client);
|
||||
|
||||
const legacyTemplatesEs = await client.asCurrentUser.indices.getTemplate();
|
||||
const { index_templates: templatesEs } =
|
||||
await client.asCurrentUser.indices.getIndexTemplate();
|
||||
|
||||
// @ts-expect-error TemplateSerialized.index_patterns not compatible with IndicesIndexTemplate.index_patterns
|
||||
const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix);
|
||||
|
||||
if (config.isLegacyTemplatesEnabled === false) {
|
||||
// If isLegacyTemplatesEnabled=false, we do not want to fetch legacy templates and return an empty array;
|
||||
// we retain the same response format to limit changes required on the client
|
||||
return response.ok({ body: { templates, legacyTemplates: [] } });
|
||||
}
|
||||
|
||||
const legacyTemplatesEs = await client.asCurrentUser.indices.getTemplate();
|
||||
|
||||
const legacyTemplates = deserializeLegacyTemplateList(
|
||||
legacyTemplatesEs,
|
||||
cloudManagedTemplatePrefix
|
||||
);
|
||||
// @ts-expect-error TemplateSerialized.index_patterns not compatible with IndicesIndexTemplate.index_patterns
|
||||
const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix);
|
||||
|
||||
const body = {
|
||||
templates,
|
||||
|
@ -59,7 +66,7 @@ const querySchema = schema.object({
|
|||
legacy: schema.maybe(schema.oneOf([schema.literal('true'), schema.literal('false')])),
|
||||
});
|
||||
|
||||
export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDependencies) {
|
||||
export function registerGetOneRoute({ router, config, lib: { handleEsError } }: RouteDependencies) {
|
||||
router.get(
|
||||
{
|
||||
path: addBasePath('/index_templates/{name}'),
|
||||
|
@ -68,7 +75,10 @@ export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDep
|
|||
async (context, request, response) => {
|
||||
const { client } = (await context.core).elasticsearch;
|
||||
const { name } = request.params as TypeOf<typeof paramsSchema>;
|
||||
const isLegacy = (request.query as TypeOf<typeof querySchema>).legacy === 'true';
|
||||
// We don't expect the `legacy` query to be used when legacy templates are disabled, however, we add the `enableLegacyTemplates` check as a safeguard
|
||||
const isLegacy =
|
||||
config.isLegacyTemplatesEnabled !== false &&
|
||||
(request.query as TypeOf<typeof querySchema>).legacy === 'true';
|
||||
|
||||
try {
|
||||
const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client);
|
||||
|
|
|
@ -12,6 +12,7 @@ import type { RouteDependencies } from '../../types';
|
|||
export const routeDependencies: Omit<RouteDependencies, 'router'> = {
|
||||
config: {
|
||||
isSecurityEnabled: jest.fn().mockReturnValue(true),
|
||||
isLegacyTemplatesEnabled: true,
|
||||
},
|
||||
indexDataEnricher: new IndexDataEnricher(),
|
||||
lib: {
|
||||
|
|
|
@ -23,6 +23,7 @@ export interface RouteDependencies {
|
|||
router: IRouter;
|
||||
config: {
|
||||
isSecurityEnabled: () => boolean;
|
||||
isLegacyTemplatesEnabled: boolean;
|
||||
};
|
||||
indexDataEnricher: IndexDataEnricher;
|
||||
lib: {
|
||||
|
|
|
@ -13,5 +13,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./spaces'));
|
||||
loadTestFile(require.resolve('./security_response_headers'));
|
||||
loadTestFile(require.resolve('./rollups'));
|
||||
loadTestFile(require.resolve('./index_management'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Index Management APIs', function () {
|
||||
loadTestFile(require.resolve('./index_templates'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 expect from 'expect';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
const API_BASE_PATH = '/api/index_management';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
|
||||
describe('Index templates', function () {
|
||||
const templateName = `template-${Math.random()}`;
|
||||
const indexTemplate = {
|
||||
name: templateName,
|
||||
body: {
|
||||
index_patterns: ['test*'],
|
||||
},
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
// Create a new index template to test against
|
||||
try {
|
||||
await es.indices.putIndexTemplate(indexTemplate);
|
||||
} catch (err) {
|
||||
log.debug('[Setup error] Error creating index template');
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
// Cleanup template created for testing purposes
|
||||
try {
|
||||
await es.indices.deleteIndexTemplate({
|
||||
name: templateName,
|
||||
});
|
||||
} catch (err) {
|
||||
log.debug('[Cleanup error] Error deleting index template');
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
describe('get all', () => {
|
||||
it('should list all the index templates with the expected parameters', async () => {
|
||||
const { body: allTemplates } = await supertest
|
||||
.get(`${API_BASE_PATH}/index_templates`)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'xxx')
|
||||
.expect(200);
|
||||
|
||||
// Legacy templates are not applicable on serverless
|
||||
expect(allTemplates.legacyTemplates.length).toEqual(0);
|
||||
|
||||
const indexTemplateFound = allTemplates.templates.find(
|
||||
(template: { name: string }) => template.name === indexTemplate.name
|
||||
);
|
||||
|
||||
expect(indexTemplateFound).toBeTruthy();
|
||||
|
||||
const expectedKeys = [
|
||||
'name',
|
||||
'indexPatterns',
|
||||
'hasSettings',
|
||||
'hasAliases',
|
||||
'hasMappings',
|
||||
'_kbnMeta',
|
||||
].sort();
|
||||
|
||||
expect(Object.keys(indexTemplateFound).sort()).toEqual(expectedKeys);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get one', () => {
|
||||
it('should return an index template with the expected parameters', async () => {
|
||||
const { body } = await supertest
|
||||
.get(`${API_BASE_PATH}/index_templates/${templateName}`)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'xxx')
|
||||
.expect(200);
|
||||
|
||||
const expectedKeys = ['name', 'indexPatterns', 'template', '_kbnMeta'].sort();
|
||||
|
||||
expect(body.name).toEqual(templateName);
|
||||
expect(Object.keys(body).sort()).toEqual(expectedKeys);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -55,6 +55,9 @@ export function createTestConfig(options: CreateTestConfigOptions) {
|
|||
management: {
|
||||
pathname: '/app/management',
|
||||
},
|
||||
indexManagement: {
|
||||
pathname: '/app/management/data/index_management',
|
||||
},
|
||||
},
|
||||
// choose where screenshots should be saved
|
||||
screenshots: {
|
||||
|
|
|
@ -14,5 +14,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
|
||||
// platform security
|
||||
loadTestFile(require.resolve('./security/navigation/avatar_menu'));
|
||||
|
||||
// Management
|
||||
loadTestFile(require.resolve('./index_management'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default ({ loadTestFile }: FtrProviderContext) => {
|
||||
describe('Index Management', function () {
|
||||
loadTestFile(require.resolve('./index_templates'));
|
||||
});
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const pageObjects = getPageObjects(['common', 'indexManagement', 'header']);
|
||||
const browser = getService('browser');
|
||||
const security = getService('security');
|
||||
const retry = getService('retry');
|
||||
|
||||
describe('Index Templates', function () {
|
||||
before(async () => {
|
||||
await security.testUser.setRoles(['index_management_user']);
|
||||
await pageObjects.common.navigateToApp('indexManagement');
|
||||
// Navigate to the index templates tab
|
||||
await pageObjects.indexManagement.changeTabs('templatesTab');
|
||||
});
|
||||
|
||||
it('renders the index templates tab', async () => {
|
||||
await retry.waitFor('index templates list to be visible', async () => {
|
||||
return await testSubjects.exists('templateList');
|
||||
});
|
||||
|
||||
const url = await browser.getCurrentUrl();
|
||||
expect(url).to.contain(`/templates`);
|
||||
});
|
||||
});
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue