[8.0] Use doc link service in ILM (#122104) (#122617)

* Use doc link service in ILM (#122104)

(cherry picked from commit b5d5ba972d)

* Fixes linting
This commit is contained in:
Lisa Cawley 2022-01-10 16:58:52 -08:00 committed by GitHub
parent a596b34429
commit 2503fa64b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 92 additions and 90 deletions

View file

@ -8,6 +8,7 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest';
import { docLinksServiceMock } from 'src/core/public/mocks';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock';
import { licensingMock } from '../../../../licensing/public/mocks';
@ -17,7 +18,13 @@ const breadcrumbService = createBreadcrumbsMock();
const AppWithContext = (props: any) => {
return (
<KibanaContextProvider services={{ breadcrumbService, license: licensingMock.createLicense() }}>
<KibanaContextProvider
services={{
breadcrumbService,
license: licensingMock.createLicense(),
docLinks: docLinksServiceMock.createStartContract(),
}}
>
<App {...props} />
</KibanaContextProvider>
);

View file

@ -7,6 +7,7 @@
import React from 'react';
import { registerTestBed, TestBedConfig } from '@kbn/test/jest';
import { docLinksServiceMock } from 'src/core/public/mocks';
import '../helpers/global_mocks';
@ -35,6 +36,7 @@ const EditPolicyContainer = ({ appServicesContext, ...rest }: any) => {
services={{
breadcrumbService,
license: licensingMock.createLicense({ license: { type: 'enterprise' } }),
docLinks: docLinksServiceMock.createStartContract(),
getUrlForApp: () => {},
...appServicesContext,
}}

View file

@ -14,6 +14,7 @@ import { findTestSubject, takeMountedSnapshot } from '@elastic/eui/lib/test';
import {
fatalErrorsServiceMock,
injectedMetadataServiceMock,
docLinksServiceMock,
} from '../../../../src/core/public/mocks';
import { HttpService } from '../../../../src/core/public/http';
import { usageCollectionPluginMock } from '../../../../src/plugins/usage_collection/public/mocks';
@ -99,7 +100,9 @@ const testSort = (headerName: string) => {
const TestComponent = ({ testPolicies }: { testPolicies: PolicyFromES[] }) => {
return (
<KibanaContextProvider services={{ getUrlForApp: () => '' }}>
<KibanaContextProvider
services={{ getUrlForApp: () => '', docLinks: docLinksServiceMock.createStartContract() }}
>
<PolicyListContextProvider>
<PolicyList updatePolicies={jest.fn()} policies={testPolicies} />
</PolicyListContextProvider>

View file

@ -7,7 +7,7 @@
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { I18nStart, ScopedHistory, ApplicationStart } from 'kibana/public';
import { I18nStart, ScopedHistory, ApplicationStart, DocLinksStart } from 'kibana/public';
import { UnmountCallback } from 'src/core/public';
import { CloudSetup } from '../../../cloud/public';
import { ILicense } from '../../../licensing/public';
@ -26,13 +26,16 @@ export const renderApp = (
application: ApplicationStart,
breadcrumbService: BreadcrumbService,
license: ILicense,
docLinks: DocLinksStart,
cloud?: CloudSetup
): UnmountCallback => {
const { getUrlForApp } = application;
render(
<RedirectAppLinks application={application} className={APP_WRAPPER_CLASS}>
<I18nContext>
<KibanaContextProvider services={{ cloud, breadcrumbService, license, getUrlForApp }}>
<KibanaContextProvider
services={{ cloud, breadcrumbService, license, getUrlForApp, docLinks }}
>
<App history={history} />
</KibanaContextProvider>
</I18nContext>

View file

@ -9,8 +9,6 @@ import React, { ReactNode } from 'react';
import { EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { createDocLink } from '../../../services/documentation';
interface Props {
docPath: string;
text?: ReactNode;
@ -23,7 +21,7 @@ export const LearnMoreLink: React.FunctionComponent<Props> = ({ docPath, text })
<FormattedMessage id="xpack.indexLifecycleMgmt.learnMore" defaultMessage="Learn more" />
);
return (
<EuiLink href={createDocLink(docPath)} target="_blank" external={true}>
<EuiLink href={docPath} target="_blank" external={true}>
{content}
</EuiLink>
);

View file

@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiCallOut, EuiTextColor, EuiSwitch, EuiText } from '@elastic/eui';
import { useFormData } from '../../../../../../shared_imports';
import { useFormData, useKibana } from '../../../../../../shared_imports';
import { i18nTexts } from '../../../i18n_texts';
@ -52,6 +52,8 @@ export const HotPhase: FunctionComponent = () => {
const showEmptyRolloverFieldsError = useRolloverValueRequiredValidation();
const { docLinks } = useKibana().services;
return (
<Phase phase="hot">
<DescribedFormRow
@ -89,7 +91,7 @@ export const HotPhase: FunctionComponent = () => {
defaultMessage="Learn more"
/>
}
docPath="ilm-rollover.html"
docPath={docLinks.links.elasticsearch.ilmRollover}
/>
</p>
</EuiTextColor>

View file

@ -10,9 +10,6 @@ import { EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { DocLinksStart } from 'src/core/public';
import { getNodeAllocationMigrationLink } from '../../../../../../../services/documentation';
export interface Props {
docLinks: DocLinksStart;
}
@ -28,7 +25,11 @@ export const nodeAllocationMigrationGuidance = ({ docLinks }: Props) => (
defaultMessage="To allocate data to particular data nodes, {roleBasedGuidance} or configure custom node attributes in elasticsearch.yml."
values={{
roleBasedGuidance: (
<EuiLink href={getNodeAllocationMigrationLink(docLinks)} target="_blank" external={true}>
<EuiLink
href={docLinks.links.elasticsearch.migrateIndexAllocationFilters}
target="_blank"
external={true}
>
{i18n.translate(
'xpack.indexLifecycleMgmt.editPolicy.defaultToDataNodesDescription.migrationGuidanceMessage',
{

View file

@ -11,7 +11,7 @@ import { get } from 'lodash';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButtonEmpty, EuiText, EuiSpacer } from '@elastic/eui';
import { SelectField, useFormData } from '../../../../../../../../shared_imports';
import { SelectField, useFormData, useKibana } from '../../../../../../../../shared_imports';
import { UseField } from '../../../../../form';
@ -21,18 +21,6 @@ import { NodeAttrsDetails } from './node_attrs_details';
import { SharedProps } from './types';
const learnMoreLink = (
<LearnMoreLink
text={
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.learnAboutShardAllocationLink"
defaultMessage="Learn about shard allocation"
/>
}
docPath="modules-cluster.html#cluster-shard-allocation-settings"
/>
);
const i18nTexts = {
allocateToDataNodesOption: i18n.translate(
'xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.allocateToDataNodesOption',
@ -52,7 +40,8 @@ export const NodeAllocation: FunctionComponent<SharedProps> = ({
const [formData] = useFormData({
watch: [allocationNodeAttributePath],
});
const { docLinks } = useKibana().services;
const shardAllocationSettingsUrl = docLinks.links.elasticsearch.shardAllocationSettings;
const selectedAllocationNodeAttribute = get(formData, allocationNodeAttributePath);
const [selectedNodeAttrsForDetails, setSelectedNodeAttrsForDetails] = useState<string | null>(
@ -79,7 +68,6 @@ export const NodeAllocation: FunctionComponent<SharedProps> = ({
}
nodeAllocationOptions = nodeAllocationOptions.concat(nodeOptions);
return (
<>
<EuiText size="s">
@ -87,7 +75,19 @@ export const NodeAllocation: FunctionComponent<SharedProps> = ({
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description"
defaultMessage="Use node attributes to control shard allocation. {learnMoreLink}."
values={{ learnMoreLink }}
values={{
learnMoreLink: (
<LearnMoreLink
text={
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.learnAboutShardAllocationLink"
defaultMessage="Learn about shard allocation"
/>
}
docPath={shardAllocationSettingsUrl}
/>
),
}}
/>
</p>
</EuiText>

View file

@ -10,8 +10,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import uuid from 'uuid';
import { EuiCheckbox, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiIconTip } from '@elastic/eui';
import { NumericField } from '../../../../../../shared_imports';
import { NumericField, useKibana } from '../../../../../../shared_imports';
import { i18nTexts } from '../../../i18n_texts';
import { useEditPolicyContext } from '../../../edit_policy_context';
@ -31,6 +30,8 @@ export const ForcemergeField: React.FunctionComponent<Props> = ({ phase }) => {
return policy.phases[phase]?.actions?.forcemerge != null;
}, [policy, phase]);
const { docLinks } = useKibana().services;
return (
<DescribedFormRow
title={
@ -47,7 +48,7 @@ export const ForcemergeField: React.FunctionComponent<Props> = ({ phase }) => {
id="xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableExplanationText"
defaultMessage="Reduce the number of segments in each index shard and clean up deleted documents."
/>{' '}
<LearnMoreLink docPath="ilm-forcemerge.html" />
<LearnMoreLink docPath={docLinks.links.elasticsearch.ilmForceMerge} />
</>
}
titleSize="xs"

View file

@ -17,6 +17,7 @@ import { useEditPolicyContext } from '../../../edit_policy_context';
import { UseField } from '../../../form';
import { LearnMoreLink, DescribedFormRow } from '../..';
import { useKibana } from '../../../../../../shared_imports';
interface Props {
phase: PhaseExceptDelete;
@ -33,6 +34,8 @@ export const IndexPriorityField: FunctionComponent<Props> = ({ phase }) => {
);
}, [isNewPolicy, policy.phases, phase]);
const { docLinks } = useKibana().services;
return (
<DescribedFormRow
title={
@ -50,7 +53,7 @@ export const IndexPriorityField: FunctionComponent<Props> = ({ phase }) => {
defaultMessage="Set the priority for recovering your indices after a node restart.
Indices with higher priorities are recovered before indices with lower priorities."
/>{' '}
<LearnMoreLink docPath="ilm-set-priority.html" />
<LearnMoreLink docPath={docLinks.links.elasticsearch.ilmSetPriority} />
</EuiTextColor>
}
titleSize="xs"

View file

@ -10,12 +10,13 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { EuiTextColor } from '@elastic/eui';
import { LearnMoreLink } from '../../learn_more_link';
import { ToggleFieldWithDescribedFormRow } from '../../described_form_row';
import { useKibana } from '../../../../../../shared_imports';
interface Props {
phase: 'hot' | 'warm' | 'cold';
}
export const ReadonlyField: React.FunctionComponent<Props> = ({ phase }) => {
const { docLinks } = useKibana().services;
return (
<ToggleFieldWithDescribedFormRow
title={
@ -32,7 +33,7 @@ export const ReadonlyField: React.FunctionComponent<Props> = ({ phase }) => {
id="xpack.indexLifecycleMgmt.editPolicy.readonlyDescription"
defaultMessage="Enable to make the index and index metadata read only, disable to allow writes and metadata changes."
/>{' '}
<LearnMoreLink docPath="ilm-readonly.html" />
<LearnMoreLink docPath={docLinks.links.elasticsearch.ilmReadOnly} />
</EuiTextColor>
}
fullWidth

View file

@ -25,7 +25,11 @@ export interface Props {
canBeDisabled?: boolean;
}
const geti18nTexts = (phase: Props['phase']) => {
const geti18nTexts = (
phase: Props['phase'],
fullyMountedSearchableSnapshotLink: string,
partiallyMountedSearchableSnapshotLink: string
) => {
switch (phase) {
// Hot and cold phases both create fully mounted snapshots.
case 'hot':
@ -42,7 +46,7 @@ const geti18nTexts = (phase: Props['phase']) => {
id="xpack.indexLifecycleMgmt.editPolicy.fullyMountedSearchableSnapshotField.description"
defaultMessage="Convert to a fully-mounted index that contains a complete copy of your data and is backed by a snapshot. You can reduce the number of replicas and rely on the snapshot for resiliency. {learnMoreLink}"
values={{
learnMoreLink: <LearnMoreLink docPath="ilm-searchable-snapshot.html" />,
learnMoreLink: <LearnMoreLink docPath={fullyMountedSearchableSnapshotLink} />,
}}
/>
),
@ -66,9 +70,7 @@ const geti18nTexts = (phase: Props['phase']) => {
id="xpack.indexLifecycleMgmt.editPolicy.frozenPhase.partiallyMountedSearchableSnapshotField.description"
defaultMessage="Convert to a partially-mounted index that caches the index metadata. Data is retrieved from the snapshot as needed to process search requests. This minimizes the index footprint while keeping all of your data fully searchable. {learnMoreLink}"
values={{
learnMoreLink: (
<LearnMoreLink docPath="searchable-snapshots.html#searchable-snapshots-shared-cache" />
),
learnMoreLink: <LearnMoreLink docPath={partiallyMountedSearchableSnapshotLink} />,
}}
/>
),
@ -85,7 +87,7 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({
canBeDisabled = true,
}) => {
const {
services: { cloud, getUrlForApp },
services: { cloud, docLinks, getUrlForApp },
} = useKibana();
const { policy, license, isNewPolicy } = useEditPolicyContext();
const { isUsingSearchableSnapshotInHotPhase } = useConfiguration();
@ -109,8 +111,14 @@ export const SearchableSnapshotField: FunctionComponent<Props> = ({
policy.phases[phase]?.actions?.searchable_snapshot?.snapshot_repository
)
);
const i18nTexts = geti18nTexts(phase);
const fullyMountedSearchableSnapshotLink = docLinks.links.elasticsearch.ilmSearchableSnapshot;
const partiallyMountedSearchableSnapshotLink =
docLinks.links.elasticsearch.searchableSnapshotSharedCache;
const i18nTexts = geti18nTexts(
phase,
fullyMountedSearchableSnapshotLink,
partiallyMountedSearchableSnapshotLink
);
useEffect(() => {
if (isDisabledDueToLicense) {

View file

@ -19,6 +19,7 @@ import { i18nTexts } from '../../../i18n_texts';
import { LearnMoreLink, DescribedFormRow } from '../../';
import { byteSizeUnits } from '../../../constants';
import { UnitField } from './unit_field';
import { useKibana } from '../../../../../../shared_imports';
interface Props {
phase: 'hot' | 'warm';
@ -35,6 +36,7 @@ export const ShrinkField: FunctionComponent<Props> = ({ phase }) => {
const path = `phases.${phase}.actions.shrink.${
isUsingShardSize ? 'max_primary_shard_size' : 'number_of_shards'
}`;
const { docLinks } = useKibana().services;
return (
<DescribedFormRow
title={
@ -51,7 +53,7 @@ export const ShrinkField: FunctionComponent<Props> = ({ phase }) => {
id="xpack.indexLifecycleMgmt.editPolicy.shrinkIndexExplanationText"
defaultMessage="Shrink the index to a new index with fewer primary shards."
/>{' '}
<LearnMoreLink docPath="ilm-shrink.html" />
<LearnMoreLink docPath={docLinks.links.elasticsearch.ilmShrink} />
</EuiTextColor>
}
titleSize="xs"

View file

@ -29,7 +29,7 @@ const waitForSnapshotFormField = 'phases.delete.actions.wait_for_snapshot.policy
export const SnapshotPoliciesField: React.FunctionComponent = () => {
const {
services: { getUrlForApp },
services: { docLinks, getUrlForApp },
} = useKibana();
const { error, isLoading, data, resendRequest } = useLoadSnapshotPolicies();
const [formData] = useFormData({
@ -159,7 +159,7 @@ export const SnapshotPoliciesField: React.FunctionComponent = () => {
id="xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotDescription"
defaultMessage="Specify a snapshot policy to be executed before the deletion of the index. This ensures that a snapshot of the deleted index is available."
/>{' '}
<LearnMoreLink docPath="ilm-wait-for-snapshot.html" />
<LearnMoreLink docPath={docLinks.links.alerting.ilmWaitForSnapshot} />
</>
}
titleSize="xs"

View file

@ -11,6 +11,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import React, { FunctionComponent, memo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiText, EuiIconTip } from '@elastic/eui';
import { useKibana } from '../../../../../shared_imports';
import { PhaseExceptDelete } from '../../../../../../common/types';
import {
@ -141,6 +143,8 @@ export const Timeline: FunctionComponent<Props> = memo(
<InfinityIcon color="subdued" aria-label={i18nTexts.foreverIcon.ariaLabel} />
) : null;
const { docLinks } = useKibana().services;
return (
<EuiFlexGroup gutterSize="s" direction="column" responsive={false}>
<EuiFlexItem>
@ -151,7 +155,7 @@ export const Timeline: FunctionComponent<Props> = memo(
{i18nTexts.description}
&nbsp;
<LearnMoreLink
docPath="ilm-index-lifecycle.html#ilm-phase-transitions"
docPath={docLinks.links.elasticsearch.ilmPhaseTransitions}
text={
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.learnAboutTimingText"

View file

@ -26,7 +26,6 @@ import {
import { TextField, useForm, useFormData, useKibana } from '../../../shared_imports';
import { toasts } from '../../services/notification';
import { createDocLink } from '../../services/documentation';
import { UseField } from './form';
import { savePolicy } from './save_policy';
import {
@ -67,7 +66,7 @@ export const EditPolicy: React.FunctionComponent = () => {
} = useEditPolicyContext();
const {
services: { cloud },
services: { cloud, docLinks },
} = useKibana();
const [isClonedPolicy, setIsClonedPolicy] = useState(false);
@ -166,11 +165,7 @@ export const EditPolicy: React.FunctionComponent = () => {
}
bottomBorder
rightSideItems={[
<EuiButtonEmpty
href={createDocLink('index-lifecycle-management.html')}
target="_blank"
iconType="help"
>
<EuiButtonEmpty href={docLinks.links.elasticsearch.ilm} target="_blank" iconType="help">
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.documentationLinkText"
defaultMessage="Documentation"

View file

@ -27,6 +27,7 @@ import { addLifecyclePolicyToTemplate, useLoadIndexTemplates } from '../../../se
import { toasts } from '../../../services/notification';
import { showApiError } from '../../../services/api_errors';
import { LearnMoreLink } from '../../edit_policy/components';
import { useKibana } from '../../../../shared_imports';
interface Props {
policy: PolicyFromES;
@ -257,6 +258,8 @@ export const AddPolicyToTemplateConfirmModal: React.FunctionComponent<Props> = (
}
);
const { docLinks } = useKibana().services;
return (
<EuiConfirmModal
data-test-subj="addPolicyToTemplateModal"
@ -285,7 +288,7 @@ export const AddPolicyToTemplateConfirmModal: React.FunctionComponent<Props> = (
all indices which match the index template."
/>{' '}
<LearnMoreLink
docPath="index-templates.html"
docPath={docLinks.links.elasticsearch.indexTemplates}
text={
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.learnAboutIndexTemplatesLink"

View file

@ -1,28 +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.
*/
/**
* TODO:
* IMPORTANT: Please see how {@link BreadcrumbService} is set up for an example of how these services should be set up
* in future. The pattern in this file is legacy and should be updated to conform to the plugin lifecycle.
*/
import { DocLinksStart } from 'src/core/public';
export let skippingDisconnectedClustersUrl: string;
export let remoteClustersUrl: string;
export let transportPortUrl: string;
let _esDocBasePath: string;
export function init(esDocBasePath: string): void {
_esDocBasePath = esDocBasePath;
}
export const createDocLink = (docPath: string): string => `${_esDocBasePath}${docPath}`;
export const getNodeAllocationMigrationLink = ({ links }: DocLinksStart) =>
`${links.elasticsearch.migrateIndexAllocationFilters}`;

View file

@ -11,7 +11,6 @@ import { CoreSetup, PluginInitializerContext, Plugin } from 'src/core/public';
import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public';
import { PLUGIN } from '../common/constants';
import { init as initHttp } from './application/services/http';
import { init as initDocumentation } from './application/services/documentation';
import { init as initUiMetric } from './application/services/ui_metric';
import { init as initNotification } from './application/services/notification';
import { BreadcrumbService } from './application/services/breadcrumbs';
@ -55,8 +54,8 @@ export class IndexLifecycleManagementPlugin
const {
chrome: { docTitle },
i18n: { Context: I18nContext },
docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION },
application,
docLinks,
} = coreStart;
const license = await licensing.license$.pipe(first()).toPromise();
@ -64,11 +63,6 @@ export class IndexLifecycleManagementPlugin
docTitle.change(PLUGIN.TITLE);
this.breadcrumbService.setup(setBreadcrumbs);
// Initialize additional services.
initDocumentation(
`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`
);
const { renderApp } = await import('./application');
const unmountAppCallback = renderApp(
@ -78,6 +72,7 @@ export class IndexLifecycleManagementPlugin
application,
this.breadcrumbService,
license,
docLinks,
cloud
);

View file

@ -6,6 +6,7 @@
*/
import { ApplicationStart } from 'kibana/public';
import { DocLinksStart } from 'src/core/public';
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
import { ManagementSetup } from '../../../../src/plugins/management/public';
@ -40,4 +41,5 @@ export interface AppServicesContext {
license: ILicense;
cloud?: CloudSetup;
getUrlForApp: ApplicationStart['getUrlForApp'];
docLinks: DocLinksStart;
}