[Synthetics] Show data retention privileges prompt (#156681)

This commit is contained in:
Shahzad 2023-05-08 21:11:11 +02:00 committed by GitHub
parent d14ba925dd
commit 14b86951e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 125 additions and 9 deletions

View file

@ -740,5 +740,8 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
appSearch: `${SEARCH_UI_DOCS}tutorials/app-search`,
elasticsearch: `${SEARCH_UI_DOCS}tutorials/elasticsearch`,
},
synthetics: {
featureRoles: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/synthetics-feature-roles.html`,
},
});
};

View file

@ -509,4 +509,7 @@ export interface DocLinks {
readonly appSearch: string;
readonly elasticsearch: string;
};
readonly synthetics: {
readonly featureRoles: string;
};
}

View file

@ -6,14 +6,29 @@
*/
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiBasicTable, EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui';
import {
EuiBasicTable,
EuiCallOut,
EuiEmptyPrompt,
EuiIcon,
EuiLink,
EuiMarkdownFormat,
EuiSpacer,
} from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { PolicyLink } from './policy_link';
import { css } from '@emotion/react';
import { IHttpFetchError, ResponseErrorBody } from '@kbn/core-http-browser';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { PolicyLink, PolicyNameLabel } from './policy_link';
import { useGetIlmPolicies } from './hooks/use_get_ilm_policies';
export const DataRetentionTab = () => {
const { data, loading } = useGetIlmPolicies();
const { data, loading, error } = useGetIlmPolicies();
if (error && (error as unknown as IHttpFetchError<ResponseErrorBody>).body?.statusCode === 403) {
return <Unprivileged />;
}
const columns = [
{
@ -36,9 +51,7 @@ export const DataRetentionTab = () => {
},
{
field: 'policy.name',
name: i18n.translate('xpack.synthetics.settingsRoute.table.policy', {
defaultMessage: 'Policy',
}),
name: <PolicyNameLabel />,
render: (name: string, _item: typeof data[0]) => <PolicyLink name={name} />,
},
];
@ -76,6 +89,65 @@ export const DataRetentionTab = () => {
);
};
const Unprivileged = () => {
const {
services: { docLinks },
} = useKibana();
return (
<EuiEmptyPrompt
data-test-subj="syntheticsUnprivileged"
color="plain"
icon={<EuiIcon type="logoObservability" size="xl" />}
title={
<h2>
<FormattedMessage
id="xpack.synthetics.dataRetention.unprivileged.unprivilegedTitle"
defaultMessage="Missing privileges"
/>
</h2>
}
body={
<p>
<FormattedMessage
id="xpack.synthetics.params.unprivileged.unprivilegedDescription"
defaultMessage="You need additional privileges to view Synthetics app data usage and retention settings. {docsLink}"
values={{
docsLink: (
<EuiLink
data-test-subj="syntheticsUnprivilegedLearnMoreLink"
href={docLinks?.links.synthetics.featureRoles}
target="_blank"
>
{i18n.translate('xpack.synthetics.monitorManagement.projectDelete.docsLink', {
defaultMessage: 'Learn more',
})}
</EuiLink>
),
}}
/>
</p>
}
footer={
<EuiMarkdownFormat
css={css`
text-align: initial;
`}
children={`\n- ${INDEX_PRIVILEGES} \n- ${CLUSTER_PRIVILEGES}`}
/>
}
/>
);
};
const INDEX_PRIVILEGES = i18n.translate('xpack.synthetics.dataRetention.unprivileged.index', {
defaultMessage: '`read`, `monitor` on the following Elasticsearch indices: `synthetics-*`',
});
const CLUSTER_PRIVILEGES = i18n.translate('xpack.synthetics.dataRetention.unprivileged.cluster', {
defaultMessage:
'`read_ilm`, `monitor` to view and `manage_ilm` to manage ILM policies on the Elasticsearch cluster.',
});
const CALLOUT_TITLE = i18n.translate('xpack.synthetics.settingsRoute.retentionCalloutTitle', {
defaultMessage: 'Synthetics data is configured by managed index lifecycle policies',
});

View file

@ -106,7 +106,7 @@ export const useGetIlmPolicies = () => {
const formatAge = (age?: string) => {
if (!age) {
return '';
return '--';
}
const [value] = age.split('d');
return i18n.translate('xpack.synthetics.settingsRoute.table.retentionPeriodValue', {

View file

@ -6,15 +6,17 @@
*/
import React from 'react';
import { EuiLink, EuiLoadingContent } from '@elastic/eui';
import { EuiIconTip, EuiLink, EuiLoadingContent, EuiToolTip, EuiText } from '@elastic/eui';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { ILM_LOCATOR_ID } from '@kbn/index-lifecycle-management-plugin/public';
import { useFetcher } from '@kbn/observability-plugin/public';
import { i18n } from '@kbn/i18n';
import { useSyntheticsSettingsContext } from '../../contexts';
import { ClientPluginsStart } from '../../../../plugin';
export const PolicyLink = ({ name }: { name: string }) => {
const { share } = useKibana<ClientPluginsStart>().services;
const { share, application } = useKibana<ClientPluginsStart>().services;
const canManageILM = application.capabilities.management?.data?.index_lifecycle_management;
const ilmLocator = share.url.locators.get(ILM_LOCATOR_ID);
@ -28,6 +30,18 @@ export const PolicyLink = ({ name }: { name: string }) => {
return <EuiLoadingContent lines={1} />;
}
if (!name) {
return <>--</>;
}
if (!canManageILM) {
return (
<EuiToolTip content={PERMISSIONS_NEEDED}>
<EuiText size="m">{name}</EuiText>
</EuiToolTip>
);
}
return (
<EuiLink
href={`${basePath}/app/${data.app}${data.path}`}
@ -38,3 +52,27 @@ export const PolicyLink = ({ name }: { name: string }) => {
</EuiLink>
);
};
export const PolicyNameLabel = () => {
const { application } = useKibana<ClientPluginsStart>().services;
const canManageILM = application.capabilities.management?.data?.index_lifecycle_management;
if (canManageILM) {
return <>{POLICY_LABEL}</>;
}
return (
<>
{POLICY_LABEL} <EuiIconTip content={PERMISSIONS_NEEDED} position="right" />
</>
);
};
const POLICY_LABEL = i18n.translate('xpack.synthetics.settingsRoute.table.policy', {
defaultMessage: 'Policy',
});
const PERMISSIONS_NEEDED = i18n.translate('xpack.synthetics.settingsRoute.policy.manageILM', {
defaultMessage: 'You need the "manage_ilm" cluster permission to manage ILM policies.',
});