Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Index Management] If an index template has a default_pipeline, show a link to it #206923

Merged
merged 8 commits into from
Jan 21, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export const REACT_ROOT_ID = 'indexManagementReactRoot';
export const ENRICH_POLICIES_REQUIRED_PRIVILEGES = ['manage_enrich'];

export * from './ilm_locator';

export * from './ingest_pipelines_locator';
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

export const INGEST_PIPELINES_LOCATOR_ID = 'INGEST_PIPELINES_APP_LOCATOR';
export const INGEST_PIPELINES_EDIT = 'pipeline_edit';
export const INGEST_PIPELINES_LIST = 'pipelines_list';
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import { useAppContext } from '../../../../../app_context';
import { serializeAsESLifecycle } from '../../../../../../../common/lib';
import { getLifecycleValue } from '../../../../../lib/data_streams';
import { TemplateDeserialized } from '../../../../../../../common';
import { ILM_PAGES_POLICY_EDIT } from '../../../../../constants';
import { ILM_PAGES_POLICY_EDIT, INGEST_PIPELINES_EDIT } from '../../../../../constants';
import { useIlmLocator } from '../../../../../services/use_ilm_locator';
import { useIngestPipelinesLocator } from '../../../../../services/use_ingest_pipeline_locator';
import { allowAutoCreateRadioIds } from '../../../../../../../common/constants';
import { indexModeLabels } from '../../../../../lib/index_mode_labels';

Expand Down Expand Up @@ -66,6 +67,13 @@ export const TabSummary: React.FunctionComponent<Props> = ({ templateDetails })
const { history, core } = useAppContext();
const ilmPolicyLink = useIlmLocator(ILM_PAGES_POLICY_EDIT, ilmPolicy?.name);

// Compute the linked ingest pipeline URL
const linkedIngestPipeline = templateDetails?.template?.settings?.index?.default_pipeline;
const linkedIngestPipelineUrl = useIngestPipelinesLocator(
INGEST_PIPELINES_EDIT,
linkedIngestPipeline
);

return (
<>
<EuiFlexGroup data-test-subj="summaryTab">
Expand Down Expand Up @@ -154,6 +162,25 @@ export const TabSummary: React.FunctionComponent<Props> = ({ templateDetails })
</EuiDescriptionListDescription>
</>
)}

{linkedIngestPipeline && (
<>
<EuiDescriptionListTitle>
<FormattedMessage
id="xpack.idxMgmt.templateDetails.summaryTab.linkedIngestPipelineDescriptionListTitle"
defaultMessage="Default pipeline"
/>
</EuiDescriptionListTitle>
<EuiDescriptionListDescription>
<EuiLink
onClick={() => core.application.navigateToUrl(linkedIngestPipelineUrl)}
data-test-subj="linkedIngestPipeline"
>
{linkedIngestPipeline}
</EuiLink>
</EuiDescriptionListDescription>
</>
)}
</EuiDescriptionList>
</EuiFlexItem>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { useLocatorUrl } from '@kbn/share-plugin/public';
import { useAppContext } from '../app_context';
import {
INGEST_PIPELINES_LOCATOR_ID,
INGEST_PIPELINES_EDIT,
INGEST_PIPELINES_LIST,
} from '../constants';

export const useIngestPipelinesLocator = (
page: typeof INGEST_PIPELINES_EDIT | typeof INGEST_PIPELINES_LIST,
pipelineId?: string
): string => {
const ctx = useAppContext();
const locator =
pipelineId === undefined ? null : ctx.url.locators.get(INGEST_PIPELINES_LOCATOR_ID)!;
const url = useLocatorUrl(locator, { page, pipelineId }, {}, [page, pipelineId]);

return url;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const security = getService('security');
const testSubjects = getService('testSubjects');
const es = getService('es');
const browser = getService('browser');

const INDEX_TEMPLATE_NAME = 'index-template-test-name';

Expand All @@ -28,10 +29,16 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});

afterEach(async () => {
await es.indices.deleteIndexTemplate({
name: INDEX_TEMPLATE_NAME,
});
await testSubjects.click('reloadButton');
await es.indices.deleteIndexTemplate(
{
name: INDEX_TEMPLATE_NAME,
},
{ ignore: [404] }
);

if (await testSubjects.exists('reloadButton')) {
await testSubjects.click('reloadButton');
}
});

describe('index template creation', () => {
Expand Down Expand Up @@ -221,5 +228,48 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
});
});

describe('Index template list', () => {
const TEST_TEMPLATE = 'a_test_template';
const INDEX_PATTERN = `index_pattern_${Math.random()}`;

before(async () => {
await es.indices.putIndexTemplate({
name: TEST_TEMPLATE,
body: {
index_patterns: [INDEX_PATTERN],
template: {
settings: {
default_pipeline: 'test_pipeline',
},
},
},
});

// Navigate to the index management
await pageObjects.common.navigateToApp('indexManagement');
// Navigate to the templates tab
await pageObjects.indexManagement.changeTabs('templatesTab');
});

after(async () => {
await es.indices.deleteIndexTemplate({ name: TEST_TEMPLATE }, { ignore: [404] });
});

it('shows link to ingest pipeline when default pipeline is set', async () => {
// Open details flyout
await pageObjects.indexManagement.clickIndexTemplateAt(0);

// Click on the linked ingest pipeline button
const linkedPipelineButton = await testSubjects.find('linkedIngestPipeline');
await linkedPipelineButton.click();

// Expect to navigate to the ingest pipeline page
await pageObjects.header.waitUntilLoadingHasFinished();
// We should've now navigated to the ingest pipelines app
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.contain('/ingest/ingest_pipelines/edit/test_pipeline');
});
});
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export function IndexManagementPageProvider({ getService }: FtrProviderContext)
await policyDetailsLinks[indexOfRow].click();
},

async clickIndexTemplateAt(indexOfRow: number): Promise<void> {
const indexTemplateDetailsLink = await testSubjects.findAll('templateDetailsLink');
await indexTemplateDetailsLink[indexOfRow].click();
},

async clickBulkEditDataRetention(dataStreamNames: string[]): Promise<void> {
for (const dsName of dataStreamNames) {
const checkbox = await testSubjects.find(`checkboxSelectRow-${dsName}`);
Expand Down