From ce93a1f8712c10b82e4e385661f34cad11c8ab4d Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 22 Aug 2023 09:12:20 +0100 Subject: [PATCH] [Fleet] Add ability to set a proxy for agent binary source (#164168) ## Summary Closes #162862 Add a proxy selector for agent download sources. Selecting a proxy will set the agent.download.proxy_url field on the agent policy (this can be checked in the "view full agent policy" flyout). I have marked this functionality as beta as we currently can only use the URL of the proxy, not the certificates or headers. Editing a proxy should automatically update all associated policies which use download sources with that proxy. Deleting a proxy should remove the proxy from all associated policies. Screenshot 2023-08-17 at 14 41 58 Verifying the field is set... Screenshot 2023-08-17 at 14 43 38 ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../types/rest_spec/download_sources.ts | 1 + .../download_source_flyout/index.test.tsx | 2 +- .../download_source_flyout/index.tsx | 64 ++++++++++++++++++- .../use_download_source_flyout_form.tsx | 5 ++ .../settings_page/fleet_proxies_section.tsx | 2 +- .../fleet/sections/settings/index.tsx | 6 +- 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts index bb66908b3bddd..0313753ebae13 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts @@ -40,6 +40,7 @@ export interface PostDownloadSourceRequest { name: string; host: string; is_default?: boolean; + proxy_id?: string | null; }; } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx index 1c7b1a28d560f..56a0aeb9b33f8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx @@ -16,7 +16,7 @@ function renderFlyout(downloadSource?: DownloadSource) { const renderer = createFleetTestRendererMock(); const comp = renderer.render( - {}} /> + {}} proxies={[]} /> ); return { comp }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx index 2e539494952b0..292bb63e3c54c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { + EuiComboBox, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, @@ -23,10 +24,11 @@ import { EuiLink, EuiSwitch, EuiSpacer, + EuiBetaBadge, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import type { DownloadSource } from '../../../../types'; +import type { DownloadSource, FleetProxy } from '../../../../types'; import { FLYOUT_MAX_WIDTH } from '../../constants'; import { useBreadcrumbs, useStartServices } from '../../../../hooks'; @@ -35,17 +37,22 @@ import { useDowloadSourceFlyoutForm } from './use_download_source_flyout_form'; export interface EditDownloadSourceFlyoutProps { downloadSource?: DownloadSource; onClose: () => void; + proxies: FleetProxy[]; } export const EditDownloadSourceFlyout: React.FunctionComponent = ({ onClose, downloadSource, + proxies, }) => { useBreadcrumbs('settings'); const form = useDowloadSourceFlyoutForm(onClose, downloadSource); const inputs = form.inputs; const { docLinks } = useStartServices(); - + const proxiesOptions = useMemo( + () => proxies.map((proxy) => ({ value: proxy.id, label: proxy.name })), + [proxies] + ); return ( @@ -130,6 +137,57 @@ export const EditDownloadSourceFlyout: React.FunctionComponent + + ), + }} + /> + } + helpText={ + + } + > + inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')} + selectedOptions={ + inputs.proxyIdInput.value !== '' + ? proxiesOptions.filter((option) => option.value === inputs.proxyIdInput.value) + : [] + } + options={proxiesOptions} + singleSelection={{ asPlainText: true }} + isDisabled={inputs.proxyIdInput.props.disabled} + isClearable={true} + placeholder={i18n.translate( + 'xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdPlaceholder', + { + defaultMessage: 'Select proxy', + } + )} + /> + void, downloadSource const hostInput = useInput(downloadSource?.host ?? '', validateHost); + const proxyIdInput = useInput(downloadSource?.proxy_id ?? '', () => undefined); + const inputs = { nameInput, hostInput, defaultDownloadSourceInput, + proxyIdInput, }; const hasChanged = Object.values(inputs).some((input) => input.hasChanged); @@ -61,6 +64,7 @@ export function useDowloadSourceFlyoutForm(onSuccess: () => void, downloadSource name: nameInput.value.trim(), host: hostInput.value.trim(), is_default: defaultDownloadSourceInput.value, + proxy_id: proxyIdInput.value || null, }; if (downloadSource) { @@ -100,6 +104,7 @@ export function useDowloadSourceFlyoutForm(onSuccess: () => void, downloadSource nameInput.value, notifications.toasts, onSuccess, + proxyIdInput.value, validate, ]); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx index 302736cffdaea..c4fbd758aca63 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx @@ -52,7 +52,7 @@ export const FleetProxiesSection: React.FunctionComponent diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx index bec49a6961809..34989d2920e73 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx @@ -166,7 +166,10 @@ export const SettingsApp = withConfirmModalProvider(() => { - + @@ -183,6 +186,7 @@ export const SettingsApp = withConfirmModalProvider(() => { );