diff --git a/x-pack/plugins/fleet/common/constants/output.ts b/x-pack/plugins/fleet/common/constants/output.ts index fb01ba991d3d2..5f6b247a6b289 100644 --- a/x-pack/plugins/fleet/common/constants/output.ts +++ b/x-pack/plugins/fleet/common/constants/output.ts @@ -139,3 +139,18 @@ export const OUTPUT_TYPES_WITH_PRESET_SUPPORT: Array> = [ ]; export const OUTPUT_HEALTH_DATA_STREAM = 'logs-fleet_server.output_health-default'; + +export const LOGSTASH_API_KEY_CLUSTER_PERMISSIONS = ['monitor', 'manage_own_api_key']; + +export const LOGSTASH_API_KEY_INDICES_PRIVILEGES = ['auto_configure', 'create_doc']; + +export const LOGSTASH_API_KEY_INDICES = [ + 'logs-*-*', + 'metrics-*-*', + 'traces-*-*', + 'synthetics-*-*', + '.logs-endpoint.diagnostic.collection-*', + '.logs-endpoint.action.responses-*', + 'profiling-*', + '.profiling-*', +]; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.ts deleted file mode 100644 index 228140ac290b6..0000000000000 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.ts +++ /dev/null @@ -1,47 +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 { useState, useMemo, useCallback } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { sendPostLogstashApiKeys, useStartServices } from '../../../../hooks'; - -export function useLogstashApiKey() { - const [isLoading, setIsLoading] = useState(false); - const [apiKey, setApiKey] = useState(); - const { notifications } = useStartServices(); - - const generateApiKey = useCallback(async () => { - try { - setIsLoading(true); - - const res = await sendPostLogstashApiKeys(); - if (res.error) { - throw res.error; - } - - setApiKey(res.data?.api_key); - } catch (err) { - notifications.toasts.addError(err, { - title: i18n.translate('xpack.fleet.settings.logstashInstructions.generateApiKeyError', { - defaultMessage: 'Impossible to generate an api key', - }), - }); - } finally { - setIsLoading(false); - } - }, [notifications.toasts]); - - return useMemo( - () => ({ - isLoading, - generateApiKey, - apiKey, - }), - [isLoading, generateApiKey, apiKey] - ); -} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.tsx new file mode 100644 index 0000000000000..78e8b930b45aa --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/logstash_instructions/hooks.tsx @@ -0,0 +1,88 @@ +/* + * 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, { useState, useMemo, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiCode } from '@elastic/eui'; +import { toMountPoint } from '@kbn/react-kibana-mount'; + +import { + LOGSTASH_API_KEY_CLUSTER_PERMISSIONS, + LOGSTASH_API_KEY_INDICES, + LOGSTASH_API_KEY_INDICES_PRIVILEGES, +} from '../../../../../../../common/constants'; +import { sendPostLogstashApiKeys, useStartServices } from '../../../../hooks'; + +export function useLogstashApiKey() { + const [isLoading, setIsLoading] = useState(false); + const [apiKey, setApiKey] = useState(); + const startServices = useStartServices(); + const { notifications } = startServices; + const generateApiKey = useCallback(async () => { + try { + setIsLoading(true); + + const res = await sendPostLogstashApiKeys(); + if (res.error) { + throw res.error; + } + + setApiKey(res.data?.api_key); + } catch (err) { + if (err.statusCode === 403) { + notifications.toasts.addDanger( + { + title: i18n.translate('xpack.fleet.settings.logstashInstructions.generateApiKeyError', { + defaultMessage: 'Cannot generate an API key', + }), + text: toMountPoint( + {LOGSTASH_API_KEY_CLUSTER_PERMISSIONS.join(', ')} + ), + indexPermissions: ( + {LOGSTASH_API_KEY_INDICES_PRIVILEGES.join(', ')} + ), + indexes: LOGSTASH_API_KEY_INDICES.map((index) => ( + + {index} +
+
+ )), + br:
, + }} + />, + startServices + ), + }, + {} + ); + } else { + notifications.toasts.addError(err, { + title: i18n.translate('xpack.fleet.settings.logstashInstructions.generateApiKeyError', { + defaultMessage: 'Cannot generate an API key', + }), + }); + } + } finally { + setIsLoading(false); + } + }, [notifications.toasts, startServices]); + + return useMemo( + () => ({ + isLoading, + generateApiKey, + apiKey, + }), + [isLoading, generateApiKey, apiKey] + ); +} diff --git a/x-pack/plugins/fleet/server/services/api_keys/logstash_api_keys.ts b/x-pack/plugins/fleet/server/services/api_keys/logstash_api_keys.ts index 66888223b02d1..cf6a68f5c0271 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/logstash_api_keys.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/logstash_api_keys.ts @@ -7,6 +7,12 @@ import type { ElasticsearchClient } from '@kbn/core/server'; +import { + LOGSTASH_API_KEY_CLUSTER_PERMISSIONS, + LOGSTASH_API_KEY_INDICES, + LOGSTASH_API_KEY_INDICES_PRIVILEGES, +} from '../../../common/constants'; + /** * Check if an esClient has enought permission to create a valid API key for logstash * @@ -14,20 +20,11 @@ import type { ElasticsearchClient } from '@kbn/core/server'; */ export async function canCreateLogstashApiKey(esClient: ElasticsearchClient) { const res = await esClient.security.hasPrivileges({ - cluster: ['monitor', 'manage_own_api_key'], + cluster: LOGSTASH_API_KEY_CLUSTER_PERMISSIONS, index: [ { - names: [ - 'logs-*-*', - 'metrics-*-*', - 'traces-*-*', - 'synthetics-*-*', - '.logs-endpoint.diagnostic.collection-*', - '.logs-endpoint.action.responses-*', - 'profiling-*', - '.profiling-*', - ], - privileges: ['auto_configure', 'create_doc'], + names: LOGSTASH_API_KEY_INDICES, + privileges: LOGSTASH_API_KEY_INDICES_PRIVILEGES, }, ], });