From aa7ac6b199d30a543f67f268f31ceec8d81624f5 Mon Sep 17 00:00:00 2001 From: neptunian Date: Fri, 21 Aug 2020 18:18:07 -0400 Subject: [PATCH 01/17] let the user specify multiple kibana urls --- .../ingest_manager/common/types/index.ts | 2 +- .../common/types/models/settings.ts | 2 +- .../enrollment_instructions/manual/index.tsx | 2 +- .../components/settings_flyout.tsx | 18 ++++++++++++------ .../managed_instructions.tsx | 5 +++-- x-pack/plugins/ingest_manager/server/index.ts | 7 ++++++- .../server/routes/install_script/index.ts | 6 +++--- .../server/services/install_script/index.ts | 2 +- .../install_script/install_templates/types.ts | 2 +- .../ingest_manager/server/services/setup.ts | 2 +- .../server/types/rest_spec/settings.ts | 2 +- 11 files changed, 31 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/types/index.ts b/x-pack/plugins/ingest_manager/common/types/index.ts index cafd0f03f66e2..d62f4fbb023dc 100644 --- a/x-pack/plugins/ingest_manager/common/types/index.ts +++ b/x-pack/plugins/ingest_manager/common/types/index.ts @@ -15,7 +15,7 @@ export interface IngestManagerConfigType { pollingRequestTimeout: number; maxConcurrentConnections: number; kibana: { - host?: string; + host?: string[] | string; ca_sha256?: string; }; elasticsearch: { diff --git a/x-pack/plugins/ingest_manager/common/types/models/settings.ts b/x-pack/plugins/ingest_manager/common/types/models/settings.ts index 98d99911f1b3f..49afde5b27be5 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/settings.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/settings.ts @@ -8,7 +8,7 @@ import { SavedObjectAttributes } from 'src/core/public'; interface BaseSettings { agent_auto_upgrade?: boolean; package_auto_upgrade?: boolean; - kibana_url?: string; + kibana_url?: string[]; kibana_ca_sha256?: string; has_seen_add_data_notice?: boolean; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 550c282460531..392b222b1f657 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EnrollmentAPIKey } from '../../../types'; interface Props { - kibanaUrl: string; + kibanaUrl: string[]; apiKey: EnrollmentAPIKey; kibanaCASha256?: string; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index 9a9557f77c40c..6dedfc7e5e244 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -18,13 +18,12 @@ import { EuiFlyoutFooter, EuiForm, EuiFormRow, - EuiFieldText, EuiRadioGroup, EuiComboBox, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText } from '@elastic/eui'; -import { useInput, useComboInput, useCore, useGetSettings, sendPutSettings } from '../hooks'; +import { useComboInput, useCore, useGetSettings, sendPutSettings } from '../hooks'; import { useGetOutputs, sendPutOutput } from '../hooks/use_request/outputs'; const URL_REGEX = /^(https?):\/\/[^\s$.?#].[^\s]*$/gm; @@ -36,14 +35,21 @@ interface Props { function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { const [isLoading, setIsloading] = React.useState(false); const { notifications } = useCore(); - const kibanaUrlInput = useInput('', (value) => { - if (!value.match(URL_REGEX)) { + const kibanaUrlInput = useComboInput([], (value) => { + if (value.some((v) => !v.match(URL_REGEX))) { return [ i18n.translate('xpack.ingestManager.settings.kibanaUrlError', { defaultMessage: 'Invalid URL', }), ]; } + if (value.length === 0) { + return [ + i18n.translate('xpack.ingestManager.settings.kibanaUrlEmptyError', { + defaultMessage: 'At least one URL is required', + }), + ]; + } }); const elasticsearchUrlInput = useComboInput([], (value) => { if (value.some((v) => !v.match(URL_REGEX))) { @@ -118,7 +124,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { useEffect(() => { if (settings) { inputs.kibanaUrl.setValue( - settings.kibana_url || `${window.location.origin}${core.http.basePath.get()}` + settings.kibana_url || [`${window.location.origin}${core.http.basePath.get()}`] ); } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -222,7 +228,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { })} {...inputs.kibanaUrl.formRowProps} > - + diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx index b02893057c9c3..42dae61f739b2 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx @@ -34,8 +34,9 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic const settings = useGetSettings(); const apiKey = useGetOneEnrollmentAPIKey(selectedAPIKeyId); - const kibanaUrl = - settings.data?.item?.kibana_url ?? `${window.location.origin}${core.http.basePath.get()}`; + const kibanaUrl = settings.data?.item?.kibana_url ?? [ + `${window.location.origin}${core.http.basePath.get()}`, + ]; const kibanaCASha256 = settings.data?.item?.kibana_ca_sha256; const steps: EuiContainedStepProps[] = [ diff --git a/x-pack/plugins/ingest_manager/server/index.ts b/x-pack/plugins/ingest_manager/server/index.ts index 962cddb2e411e..f7b923aebb48b 100644 --- a/x-pack/plugins/ingest_manager/server/index.ts +++ b/x-pack/plugins/ingest_manager/server/index.ts @@ -32,7 +32,12 @@ export const config = { pollingRequestTimeout: schema.number({ defaultValue: 60000 }), maxConcurrentConnections: schema.number({ defaultValue: 0 }), kibana: schema.object({ - host: schema.maybe(schema.string()), + host: schema.maybe( + schema.oneOf([ + schema.uri({ scheme: ['http', 'https'] }), + schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { minSize: 1 }), + ]) + ), ca_sha256: schema.maybe(schema.string()), }), elasticsearch: schema.object({ diff --git a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts index c2a5d77a39eb1..68f52fb43ae66 100644 --- a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts @@ -38,14 +38,14 @@ export const registerRoutes = ({ const http = appContextService.getHttpSetup(); const serverInfo = http.getServerInfo(); const basePath = http.basePath; - const kibanaUrl = - (await settingsService.getSettings(soClient)).kibana_url || + const kibanaUrl = (await settingsService.getSettings(soClient)).kibana_url || [ url.format({ protocol: serverInfo.protocol, hostname: serverInfo.hostname, port: serverInfo.port, pathname: basePath.serverBasePath, - }); + }), + ]; const script = getScript(request.params.osType, kibanaUrl); diff --git a/x-pack/plugins/ingest_manager/server/services/install_script/index.ts b/x-pack/plugins/ingest_manager/server/services/install_script/index.ts index 02386531f5d61..8acf09efd29b8 100644 --- a/x-pack/plugins/ingest_manager/server/services/install_script/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/install_script/index.ts @@ -8,7 +8,7 @@ import { appContextService } from '../app_context'; import { macosInstallTemplate } from './install_templates/macos'; import { linuxInstallTemplate } from './install_templates/linux'; -export function getScript(osType: 'macos' | 'linux', kibanaUrl: string): string { +export function getScript(osType: 'macos' | 'linux', kibanaUrl: string[]): string { const variables = { kibanaUrl, kibanaVersion: appContextService.getKibanaVersion() }; switch (osType) { diff --git a/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts b/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts index 65d57f8ac7dbf..a901194ae2c1d 100644 --- a/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts +++ b/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts @@ -5,6 +5,6 @@ */ export type InstallTemplateFunction = (variables: { - kibanaUrl: string; + kibanaUrl: string[]; kibanaVersion: string; }) => string; diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index fd5d94a71d672..24ef1f09c524e 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -76,7 +76,7 @@ async function createSetupSideEffects( return settingsService.saveSettings(soClient, { agent_auto_upgrade: true, package_auto_upgrade: true, - kibana_url: cloudUrl || flagsUrl || defaultUrl, + kibana_url: [cloudUrl || flagsUrl || defaultUrl].flat(), }); } diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts index baee9f79d9317..a00b23e5631bc 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts @@ -11,7 +11,7 @@ export const PutSettingsRequestSchema = { body: schema.object({ agent_auto_upgrade: schema.maybe(schema.boolean()), package_auto_upgrade: schema.maybe(schema.boolean()), - kibana_url: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), + kibana_url: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), kibana_ca_sha256: schema.maybe(schema.string()), has_seen_add_data_notice: schema.maybe(schema.boolean()), }), From 11382f169182fa53201391e9582ba0ccbc0d563d Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 25 Aug 2020 13:57:30 -0400 Subject: [PATCH 02/17] add validation to kibana urls so paths and protocols cannot differ --- .../ingest_manager/common/services/index.ts | 1 + .../services/is_diff_path_protocol.test.ts | 36 +++++++++++++++++++ .../common/services/is_diff_path_protocol.ts | 24 +++++++++++++ .../components/settings_flyout.tsx | 14 ++++++-- .../server/types/rest_spec/settings.ts | 11 +++++- 5 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts create mode 100644 x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.ts diff --git a/x-pack/plugins/ingest_manager/common/services/index.ts b/x-pack/plugins/ingest_manager/common/services/index.ts index ad739bf9ff844..46a1c65872d1b 100644 --- a/x-pack/plugins/ingest_manager/common/services/index.ts +++ b/x-pack/plugins/ingest_manager/common/services/index.ts @@ -11,3 +11,4 @@ export { fullAgentPolicyToYaml } from './full_agent_policy_to_yaml'; export { isPackageLimited, doesAgentPolicyAlreadyIncludePackage } from './limited_package'; export { decodeCloudId } from './decode_cloud_id'; export { isValidNamespace } from './is_valid_namespace'; +export { isDiffPathProtocol } from './is_diff_path_protocol'; diff --git a/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts new file mode 100644 index 0000000000000..50aed21c47d18 --- /dev/null +++ b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { isDiffPathProtocol } from './is_diff_path_protocol'; + +describe('Ingest Manager - isDiffPathProtocol', () => { + it('returns true for different paths', () => { + expect( + isDiffPathProtocol([ + 'http://localhost:8888/abc', + 'http://localhost:8888/abc', + 'http://localhost:8888/efg', + ]) + ).toBe(true); + }); + it('returns true for different protocols', () => { + expect( + isDiffPathProtocol([ + 'http://localhost:8888/abc', + 'https://localhost:8888/abc', + 'http://localhost:8888/abc', + ]) + ).toBe(true); + }); + it('returns false for same paths and protocols and different host or port', () => { + expect( + isDiffPathProtocol([ + 'http://localhost:8888/abc', + 'http://localhost2:8888/abc', + 'http://localhost:8883/abc', + ]) + ).toBe(false); + }); +}); diff --git a/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.ts b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.ts new file mode 100644 index 0000000000000..666e886d745b1 --- /dev/null +++ b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// validates an array of urls have the same path and protocol +export function isDiffPathProtocol(kibanaUrls: string[]) { + const urlCompare = new URL(kibanaUrls[0]); + const compareProtocol = urlCompare.protocol; + const comparePathname = urlCompare.pathname; + return kibanaUrls.some((v) => { + const url = new URL(v); + const protocol = url.protocol; + const pathname = url.pathname; + return compareProtocol !== protocol || comparePathname !== pathname; + }); +} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index 6dedfc7e5e244..6799be0c411d5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -25,6 +25,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText } from '@elastic/eui'; import { useComboInput, useCore, useGetSettings, sendPutSettings } from '../hooks'; import { useGetOutputs, sendPutOutput } from '../hooks/use_request/outputs'; +import { isDiffPathProtocol } from '../../../../common/'; const URL_REGEX = /^(https?):\/\/[^\s$.?#].[^\s]*$/gm; @@ -36,6 +37,13 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { const [isLoading, setIsloading] = React.useState(false); const { notifications } = useCore(); const kibanaUrlInput = useComboInput([], (value) => { + if (value.length === 0) { + return [ + i18n.translate('xpack.ingestManager.settings.kibanaUrlEmptyError', { + defaultMessage: 'At least one URL is required', + }), + ]; + } if (value.some((v) => !v.match(URL_REGEX))) { return [ i18n.translate('xpack.ingestManager.settings.kibanaUrlError', { @@ -43,10 +51,10 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { }), ]; } - if (value.length === 0) { + if (isDiffPathProtocol(value)) { return [ - i18n.translate('xpack.ingestManager.settings.kibanaUrlEmptyError', { - defaultMessage: 'At least one URL is required', + i18n.translate('xpack.ingestManager.settings.kibanaUrlError', { + defaultMessage: 'URL protocol and path must be the same', }), ]; } diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts index a00b23e5631bc..c1d4ac708c0fe 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { schema } from '@kbn/config-schema'; +import { isDiffPathProtocol } from '../../../common'; export const GetSettingsRequestSchema = {}; @@ -11,7 +12,15 @@ export const PutSettingsRequestSchema = { body: schema.object({ agent_auto_upgrade: schema.maybe(schema.boolean()), package_auto_upgrade: schema.maybe(schema.boolean()), - kibana_url: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), + kibana_url: schema.maybe( + schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { + validate: (value) => { + if (isDiffPathProtocol(value)) { + return 'URL protocol and path must be the same'; + } + }, + }) + ), kibana_ca_sha256: schema.maybe(schema.string()), has_seen_add_data_notice: schema.maybe(schema.boolean()), }), From b81c7ba200f3fc741cad1fac4c92db56312b6df5 Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 25 Aug 2020 14:15:15 -0400 Subject: [PATCH 03/17] update i18n message --- .../common/services/is_diff_path_protocol.test.ts | 3 +++ .../ingest_manager/components/settings_flyout.tsx | 4 ++-- .../plugins/ingest_manager/server/types/rest_spec/settings.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts index 50aed21c47d18..c488d552d7676 100644 --- a/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/is_diff_path_protocol.test.ts @@ -33,4 +33,7 @@ describe('Ingest Manager - isDiffPathProtocol', () => { ]) ).toBe(false); }); + it('returns false for one url', () => { + expect(isDiffPathProtocol(['http://localhost:8888/abc'])).toBe(false); + }); }); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index 6799be0c411d5..e4bca6449f7ab 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -53,8 +53,8 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { } if (isDiffPathProtocol(value)) { return [ - i18n.translate('xpack.ingestManager.settings.kibanaUrlError', { - defaultMessage: 'URL protocol and path must be the same', + i18n.translate('xpack.ingestManager.settings.kibanaUrlDifferentPathOrProtocolError', { + defaultMessage: 'Protocol and path must be the same for each URL', }), ]; } diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts index c1d4ac708c0fe..64e47f3438e13 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts @@ -16,7 +16,7 @@ export const PutSettingsRequestSchema = { schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { validate: (value) => { if (isDiffPathProtocol(value)) { - return 'URL protocol and path must be the same'; + return 'Protocol and path must be the same for each URL'; } }, }) From b11aaabd9c0ba1a7025c9abd1cc14bfbc98752ca Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 25 Aug 2020 14:53:57 -0400 Subject: [PATCH 04/17] only send the first url to the instructions --- .../components/enrollment_instructions/manual/index.tsx | 2 +- .../agent_enrollment_flyout/managed_instructions.tsx | 8 +++++--- .../ingest_manager/server/routes/install_script/index.ts | 2 +- .../server/services/install_script/index.ts | 2 +- .../services/install_script/install_templates/types.ts | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 392b222b1f657..550c282460531 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EnrollmentAPIKey } from '../../../types'; interface Props { - kibanaUrl: string[]; + kibanaUrl: string; apiKey: EnrollmentAPIKey; kibanaCASha256?: string; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx index 42dae61f739b2..7a73a55f397b3 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx @@ -34,9 +34,11 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic const settings = useGetSettings(); const apiKey = useGetOneEnrollmentAPIKey(selectedAPIKeyId); - const kibanaUrl = settings.data?.item?.kibana_url ?? [ - `${window.location.origin}${core.http.basePath.get()}`, - ]; + const kibanaUrls = settings.data?.item?.kibana_url; + const kibanaUrl = kibanaUrls + ? kibanaUrls[0] + : `${window.location.origin}${core.http.basePath.get()}`; + const kibanaCASha256 = settings.data?.item?.kibana_ca_sha256; const steps: EuiContainedStepProps[] = [ diff --git a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts index 68f52fb43ae66..8d635256076d8 100644 --- a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts @@ -47,7 +47,7 @@ export const registerRoutes = ({ }), ]; - const script = getScript(request.params.osType, kibanaUrl); + const script = getScript(request.params.osType, kibanaUrl[0]); return response.ok({ body: script }); } diff --git a/x-pack/plugins/ingest_manager/server/services/install_script/index.ts b/x-pack/plugins/ingest_manager/server/services/install_script/index.ts index 8acf09efd29b8..02386531f5d61 100644 --- a/x-pack/plugins/ingest_manager/server/services/install_script/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/install_script/index.ts @@ -8,7 +8,7 @@ import { appContextService } from '../app_context'; import { macosInstallTemplate } from './install_templates/macos'; import { linuxInstallTemplate } from './install_templates/linux'; -export function getScript(osType: 'macos' | 'linux', kibanaUrl: string[]): string { +export function getScript(osType: 'macos' | 'linux', kibanaUrl: string): string { const variables = { kibanaUrl, kibanaVersion: appContextService.getKibanaVersion() }; switch (osType) { diff --git a/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts b/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts index a901194ae2c1d..65d57f8ac7dbf 100644 --- a/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts +++ b/x-pack/plugins/ingest_manager/server/services/install_script/install_templates/types.ts @@ -5,6 +5,6 @@ */ export type InstallTemplateFunction = (variables: { - kibanaUrl: string[]; + kibanaUrl: string; kibanaVersion: string; }) => string; From c71e883952052b25b5dee6983781ddb1dd7cd590 Mon Sep 17 00:00:00 2001 From: neptunian Date: Thu, 27 Aug 2020 14:28:33 -0400 Subject: [PATCH 05/17] udpate all agent configs' revision when settings is updated --- .../common/types/models/agent_policy.ts | 5 ++ .../server/routes/settings/index.ts | 3 +- .../server/services/agent_policy.ts | 22 +++++++- .../apis/index.js | 3 ++ .../apis/settings/index.js | 11 ++++ .../apis/settings/update.ts | 53 +++++++++++++++++++ 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 x-pack/test/ingest_manager_api_integration/apis/settings/index.js create mode 100644 x-pack/test/ingest_manager_api_integration/apis/settings/update.ts diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts b/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts index c626c85d3fb24..5589dd6eb90bf 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts @@ -60,6 +60,11 @@ export interface FullAgentPolicy { [key: string]: any; }; }; + fleet: { + kibana: { + hosts: string[]; + }; + }; inputs: FullAgentPolicyInput[]; revision?: number; agent?: { diff --git a/x-pack/plugins/ingest_manager/server/routes/settings/index.ts b/x-pack/plugins/ingest_manager/server/routes/settings/index.ts index 56e666056e8d0..c717c55abcc9b 100644 --- a/x-pack/plugins/ingest_manager/server/routes/settings/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/settings/index.ts @@ -8,7 +8,7 @@ import { TypeOf } from '@kbn/config-schema'; import { PLUGIN_ID, SETTINGS_API_ROUTES } from '../../constants'; import { PutSettingsRequestSchema, GetSettingsRequestSchema } from '../../types'; -import { settingsService } from '../../services'; +import { settingsService, agentPolicyService } from '../../services'; export const getSettingsHandler: RequestHandler = async (context, request, response) => { const soClient = context.core.savedObjects.client; @@ -42,6 +42,7 @@ export const putSettingsHandler: RequestHandler< const soClient = context.core.savedObjects.client; try { const settings = await settingsService.saveSettings(soClient, request.body); + await agentPolicyService.bumpAllAgentPolicies(soClient); const body = { success: true, item: settings, diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 21bc7b021e83a..451996e4e09e2 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { uniq } from 'lodash'; -import { SavedObjectsClientContract } from 'src/core/server'; +import { SavedObjectsClientContract, SavedObjectsBulkUpdateResponse } from 'src/core/server'; import { AuthenticatedUser } from '../../../security/server'; import { DEFAULT_AGENT_POLICY, @@ -25,6 +25,7 @@ import { listAgents } from './agents'; import { packagePolicyService } from './package_policy'; import { outputService } from './output'; import { agentPolicyUpdateEventHandler } from './agent_policy_update'; +import { getSettings } from './settings'; const SAVED_OBJECT_TYPE = AGENT_POLICY_SAVED_OBJECT_TYPE; @@ -260,6 +261,19 @@ class AgentPolicyService { ): Promise { return this._update(soClient, id, {}, options?.user); } + public async bumpAllAgentPolicies( + soClient: SavedObjectsClientContract + ): Promise>> { + const currentPolicies = await soClient.find({ + type: SAVED_OBJECT_TYPE, + }); + const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { + const attributes = policy.attributes; + attributes.revision = attributes.revision + 1; + return policy; + }); + return soClient.bulkUpdate(bumpedPolicies); + } public async assignPackagePolicies( soClient: SavedObjectsClientContract, @@ -388,9 +402,15 @@ class AgentPolicyService { throw new Error('Default output is not setup'); } const defaultOutput = await outputService.get(soClient, defaultOutputId); + const settings = await getSettings(soClient); const fullAgentPolicy: FullAgentPolicy = { id: agentPolicy.id, + fleet: { + kibana: { + hosts: settings.kibana_url || [], + }, + }, outputs: { // TEMPORARY as we only support a default output ...[defaultOutput].reduce( diff --git a/x-pack/test/ingest_manager_api_integration/apis/index.js b/x-pack/test/ingest_manager_api_integration/apis/index.js index fac8a26fd6aec..7c1ebef337baa 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/index.js @@ -22,5 +22,8 @@ export default function ({ loadTestFile }) { // Agent policies loadTestFile(require.resolve('./agent_policy/index')); + + // Settings + loadTestFile(require.resolve('./settings/index')); }); } diff --git a/x-pack/test/ingest_manager_api_integration/apis/settings/index.js b/x-pack/test/ingest_manager_api_integration/apis/settings/index.js new file mode 100644 index 0000000000000..99346fcabeff4 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/settings/index.js @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export default function loadTests({ loadTestFile }) { + describe('Settings Endpoints', () => { + loadTestFile(require.resolve('./update')); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts b/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts new file mode 100644 index 0000000000000..7d185da169fcc --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); + + describe('Settings - update', async function () { + skipIfNoDockerRegistry(providerContext); + + it("should bump all agent policy's revision", async function () { + const { body: testPolicy1PostRes } = await supertest + .post(`/api/ingest_manager/agent_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'test', + description: '', + namespace: 'default', + }); + const { body: testPolicy2PostRes } = await supertest + .post(`/api/ingest_manager/agent_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'test2', + description: '', + namespace: 'default', + }); + await supertest + .put(`/api/ingest_manager/settings`) + .set('kbn-xsrf', 'xxxx') + .send({ kibana_url: ['http://localhost:1232/abc', 'http://localhost:1232/abc'] }); + + const getTestPolicy1Res = await kibanaServer.savedObjects.get({ + type: 'ingest-agent-policies', + id: testPolicy1PostRes.item.id, + }); + const getTestPolicy2Res = await kibanaServer.savedObjects.get({ + type: 'ingest-agent-policies', + id: testPolicy2PostRes.item.id, + }); + expect(getTestPolicy1Res.attributes.revision).equal(2); + expect(getTestPolicy2Res.attributes.revision).equal(2); + }); + }); +} From 7f9f138c2a0a184091fc004799368a6b7a270d99 Mon Sep 17 00:00:00 2001 From: neptunian Date: Thu, 27 Aug 2020 15:25:32 -0400 Subject: [PATCH 06/17] fix jest test --- .../server/services/agent_policy.test.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts index dc2a89c661ac3..d877d826289e3 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts @@ -19,6 +19,22 @@ function getSavedObjectMock(agentPolicyAttributes: any) { attributes: agentPolicyAttributes, }; }); + mock.find.mockImplementation(async (options) => { + return { + saved_objects: [ + { + id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', + attributes: {}, + type: 'ingest_manager_settings', + score: 1, + references: [], + }, + ], + total: 1, + page: 1, + per_page: 1, + }; + }); return mock; } @@ -43,7 +59,7 @@ jest.mock('./output', () => { describe('agent policy', () => { describe('getFullAgentPolicy', () => { - it('should return a policy without monitoring if not monitoring is not enabled', async () => { + it('should return a policy without monitoring if monitoring is not enabled', async () => { const soClient = getSavedObjectMock({ revision: 1, }); From 4eb6a858495274d009d656e935642688d7eb6ebd Mon Sep 17 00:00:00 2001 From: neptunian Date: Fri, 28 Aug 2020 09:28:37 -0400 Subject: [PATCH 07/17] update endpoint full agent policy test --- .../apps/endpoint/policy_details.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index 3e04a507d3810..11c1838cb9f3e 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -5,6 +5,7 @@ */ import expect from '@kbn/expect'; +import Url from 'url'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PolicyTestResourceInfo } from '../../services/endpoint_policy'; @@ -18,6 +19,15 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ]); const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); + const config = getService('config'); + const kbnTestServer = config.get('servers.kibana'); + const { protocol, hostname, port } = config.get('servers.kibana'); + + const kibanaUrl = Url.format({ + protocol, + hostname, + port, + }); describe('When on the Endpoint Policy Details Page', function () { this.tags(['ciGroup7']); @@ -186,6 +196,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { type: 'elasticsearch', }, }, + fleet: { + kibana: { + hosts: [kibanaUrl], + }, + }, revision: 3, agent: { monitoring: { From 279bde0ce125865d8aa88c18c7f2604329c73f77 Mon Sep 17 00:00:00 2001 From: neptunian Date: Fri, 28 Aug 2020 13:54:00 -0400 Subject: [PATCH 08/17] fix type --- .../security_solution_endpoint/apps/endpoint/policy_details.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index 11c1838cb9f3e..86c61e33ec9c2 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -21,7 +21,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const policyTestResources = getService('policyTestResources'); const config = getService('config'); const kbnTestServer = config.get('servers.kibana'); - const { protocol, hostname, port } = config.get('servers.kibana'); + const { protocol, hostname, port } = kbnTestServer; const kibanaUrl = Url.format({ protocol, From 9e1fbd152d1775d2be1e05028af755abc7b74c38 Mon Sep 17 00:00:00 2001 From: neptunian Date: Mon, 31 Aug 2020 14:58:34 -0400 Subject: [PATCH 09/17] dont add settings if standalone mode --- .../common/types/models/agent_policy.ts | 2 +- .../server/services/agent_policy.ts | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts b/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts index 5589dd6eb90bf..263e10e9d34b1 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent_policy.ts @@ -60,7 +60,7 @@ export interface FullAgentPolicy { [key: string]: any; }; }; - fleet: { + fleet?: { kibana: { hosts: string[]; }; diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 451996e4e09e2..6c1cf79311475 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -384,6 +384,7 @@ class AgentPolicyService { options?: { standalone: boolean } ): Promise { let agentPolicy; + const standalone = options?.standalone; try { agentPolicy = await this.get(soClient, id); @@ -402,15 +403,9 @@ class AgentPolicyService { throw new Error('Default output is not setup'); } const defaultOutput = await outputService.get(soClient, defaultOutputId); - const settings = await getSettings(soClient); const fullAgentPolicy: FullAgentPolicy = { id: agentPolicy.id, - fleet: { - kibana: { - hosts: settings.kibana_url || [], - }, - }, outputs: { // TEMPORARY as we only support a default output ...[defaultOutput].reduce( @@ -455,6 +450,21 @@ class AgentPolicyService { }), }; + // only add settings if not in standalone + if (!standalone) { + let settings; + try { + settings = await getSettings(soClient); + } catch (error) { + throw new Error('Default settings is not setup'); + } + fullAgentPolicy.fleet = { + kibana: { + hosts: settings.kibana_url || [], + }, + }; + } + return fullAgentPolicy; } } From 6745e6854667a935942fc35759f1c8e388f103d0 Mon Sep 17 00:00:00 2001 From: neptunian Date: Mon, 31 Aug 2020 14:59:46 -0400 Subject: [PATCH 10/17] fix ui not handling errors from /{agentPolicyId}/full endpoint --- .../components/agent_policy_yaml_flyout.tsx | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx index 919bb49f69aae..01cd0c9a32715 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx @@ -18,6 +18,7 @@ import { EuiFlyoutFooter, EuiButtonEmpty, EuiButton, + EuiCallOut, } from '@elastic/eui'; import { useGetOneAgentPolicyFull, useGetOneAgentPolicy, useCore } from '../../../hooks'; import { Loading } from '../../../components'; @@ -32,17 +33,28 @@ const FlyoutBody = styled(EuiFlyoutBody)` export const AgentPolicyYamlFlyout = memo<{ policyId: string; onClose: () => void }>( ({ policyId, onClose }) => { const core = useCore(); - const { isLoading: isLoadingYaml, data: yamlData } = useGetOneAgentPolicyFull(policyId); + const { isLoading: isLoadingYaml, data: yamlData, error } = useGetOneAgentPolicyFull(policyId); const { data: agentPolicyData } = useGetOneAgentPolicy(policyId); - - const body = - isLoadingYaml && !yamlData ? ( - - ) : ( - - {fullAgentPolicyToYaml(yamlData!.item)} - - ); + const body = isLoadingYaml ? ( + + ) : error ? ( + + } + color="danger" + iconType="alert" + > + {error.message} + + ) : ( + + {fullAgentPolicyToYaml(yamlData!.item)} + + ); const downloadLink = core.http.basePath.prepend( agentPolicyRouteService.getInfoFullDownloadPath(policyId) From 15916407ccf0bfa9ea19fb3e17357a60da4e6a2f Mon Sep 17 00:00:00 2001 From: neptunian Date: Mon, 31 Aug 2020 15:39:54 -0400 Subject: [PATCH 11/17] fix formatted message id --- .../agent_policy/components/agent_policy_yaml_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx index 01cd0c9a32715..5d485a6e21086 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_yaml_flyout.tsx @@ -41,7 +41,7 @@ export const AgentPolicyYamlFlyout = memo<{ policyId: string; onClose: () => voi } From 69e76f44bcc5646697fc5c528ad295b8db1d61fd Mon Sep 17 00:00:00 2001 From: neptunian Date: Mon, 31 Aug 2020 15:48:12 -0400 Subject: [PATCH 12/17] only return needed fields --- x-pack/plugins/ingest_manager/server/services/agent_policy.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 6c1cf79311475..36e6cd0857b11 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -266,6 +266,7 @@ class AgentPolicyService { ): Promise>> { const currentPolicies = await soClient.find({ type: SAVED_OBJECT_TYPE, + fields: ['revision'], }); const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { const attributes = policy.attributes; From 1e47f9563a33fab85397eb30f55a9413973f6cf5 Mon Sep 17 00:00:00 2001 From: neptunian Date: Mon, 31 Aug 2020 16:22:16 -0400 Subject: [PATCH 13/17] fill in updated_by and updated_at attributes of the ingest-agent-policies when revision is bumped --- .../ingest_manager/server/routes/settings/index.ts | 7 +++++-- .../ingest_manager/server/services/agent_policy.ts | 11 ++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/routes/settings/index.ts b/x-pack/plugins/ingest_manager/server/routes/settings/index.ts index c717c55abcc9b..aabb85dadabc2 100644 --- a/x-pack/plugins/ingest_manager/server/routes/settings/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/settings/index.ts @@ -8,7 +8,7 @@ import { TypeOf } from '@kbn/config-schema'; import { PLUGIN_ID, SETTINGS_API_ROUTES } from '../../constants'; import { PutSettingsRequestSchema, GetSettingsRequestSchema } from '../../types'; -import { settingsService, agentPolicyService } from '../../services'; +import { settingsService, agentPolicyService, appContextService } from '../../services'; export const getSettingsHandler: RequestHandler = async (context, request, response) => { const soClient = context.core.savedObjects.client; @@ -40,9 +40,12 @@ export const putSettingsHandler: RequestHandler< TypeOf > = async (context, request, response) => { const soClient = context.core.savedObjects.client; + const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); try { const settings = await settingsService.saveSettings(soClient, request.body); - await agentPolicyService.bumpAllAgentPolicies(soClient); + await agentPolicyService.bumpAllAgentPolicies(soClient, { + user: user || undefined, + }); const body = { success: true, item: settings, diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 36e6cd0857b11..345bffe811055 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -262,15 +262,20 @@ class AgentPolicyService { return this._update(soClient, id, {}, options?.user); } public async bumpAllAgentPolicies( - soClient: SavedObjectsClientContract + soClient: SavedObjectsClientContract, + options?: { user?: AuthenticatedUser } ): Promise>> { const currentPolicies = await soClient.find({ type: SAVED_OBJECT_TYPE, fields: ['revision'], }); const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { - const attributes = policy.attributes; - attributes.revision = attributes.revision + 1; + policy.attributes = { + ...policy.attributes, + revision: policy.attributes.revision + 1, + updated_at: new Date().toISOString(), + updated_by: options?.user ? options.user.username : 'system', + }; return policy; }); return soClient.bulkUpdate(bumpedPolicies); From f157c439d41ff6f3a239a9a3e735b1d92c9f1e0e Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 1 Sep 2020 12:48:06 -0400 Subject: [PATCH 14/17] throw error if kibana_urls not set and update tests --- .../server/services/agent_policy.test.ts | 19 ++++++++++++++++++- .../server/services/agent_policy.ts | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts index d877d826289e3..142de1e4b718f 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts @@ -24,7 +24,9 @@ function getSavedObjectMock(agentPolicyAttributes: any) { saved_objects: [ { id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', - attributes: {}, + attributes: { + kibana_urls: ['http://localhost:5603'] + }, type: 'ingest_manager_settings', score: 1, references: [], @@ -77,6 +79,11 @@ describe('agent policy', () => { }, inputs: [], revision: 1, + fleet: { + kibana:{ + hosts: ['http://localhost:5603'] + } + }, agent: { monitoring: { enabled: false, @@ -106,6 +113,11 @@ describe('agent policy', () => { }, inputs: [], revision: 1, + fleet: { + kibana:{ + hosts: ['http://localhost:5603'] + } + }, agent: { monitoring: { use_output: 'default', @@ -136,6 +148,11 @@ describe('agent policy', () => { }, inputs: [], revision: 1, + fleet: { + kibana:{ + hosts: ['http://localhost:5603'] + } + }, agent: { monitoring: { use_output: 'default', diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 345bffe811055..7b9b265a84d7b 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -464,9 +464,10 @@ class AgentPolicyService { } catch (error) { throw new Error('Default settings is not setup'); } + if (!settings.kibana_urls) throw new Error('kibana_urls is missing') fullAgentPolicy.fleet = { kibana: { - hosts: settings.kibana_url || [], + hosts: settings.kibana_urls, }, }; } From b644e08bc01adf393b7d0d8ade25083ad05498ff Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 1 Sep 2020 13:02:20 -0400 Subject: [PATCH 15/17] change ingest_manager_settings SO attribute kibana_url: string to kibana_urls: string[] and add migration --- .../common/types/models/settings.ts | 2 +- .../enrollment_instructions/manual/index.tsx | 6 ++--- .../components/settings_flyout.tsx | 16 +++++++------- .../managed_instructions.tsx | 8 +++---- .../server/routes/install_script/index.ts | 4 ++-- .../server/saved_objects/index.ts | 6 ++++- .../saved_objects/migrations/to_v7_10_0.ts | 22 ++++++++++++++++++- .../server/services/agent_policy.test.ts | 20 ++++++++--------- .../server/services/agent_policy.ts | 2 +- .../ingest_manager/server/services/setup.ts | 2 +- .../server/types/rest_spec/settings.ts | 2 +- .../apis/settings/update.ts | 2 +- 12 files changed, 58 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/types/models/settings.ts b/x-pack/plugins/ingest_manager/common/types/models/settings.ts index 49afde5b27be5..4433adf567442 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/settings.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/settings.ts @@ -8,7 +8,7 @@ import { SavedObjectAttributes } from 'src/core/public'; interface BaseSettings { agent_auto_upgrade?: boolean; package_auto_upgrade?: boolean; - kibana_url?: string[]; + kibana_urls?: string[]; kibana_ca_sha256?: string; has_seen_add_data_notice?: boolean; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 550c282460531..5d6ae4aecc0f5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EnrollmentAPIKey } from '../../../types'; interface Props { - kibanaUrl: string; + kibanaUrls: string; apiKey: EnrollmentAPIKey; kibanaCASha256?: string; } @@ -22,11 +22,11 @@ const CommandCode = styled.pre({ }); export const ManualInstructions: React.FunctionComponent = ({ - kibanaUrl, + kibanaUrls, apiKey, kibanaCASha256, }) => { - const enrollArgs = `${kibanaUrl} ${apiKey.api_key}${ + const enrollArgs = `${kibanaUrls} ${apiKey.api_key}${ kibanaCASha256 ? ` --ca_sha256=${kibanaCASha256}` : '' }`; const macOsLinuxTarCommand = `./elastic-agent enroll ${enrollArgs} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index e4bca6449f7ab..8bd3512813ad1 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -36,7 +36,7 @@ interface Props { function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { const [isLoading, setIsloading] = React.useState(false); const { notifications } = useCore(); - const kibanaUrlInput = useComboInput([], (value) => { + const kibanaUrlsInput = useComboInput([], (value) => { if (value.length === 0) { return [ i18n.translate('xpack.ingestManager.settings.kibanaUrlEmptyError', { @@ -72,7 +72,7 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { return { isLoading, onSubmit: async () => { - if (!kibanaUrlInput.validate() || !elasticsearchUrlInput.validate()) { + if (!kibanaUrlsInput.validate() || !elasticsearchUrlInput.validate()) { return; } @@ -88,7 +88,7 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { throw outputResponse.error; } const settingsResponse = await sendPutSettings({ - kibana_url: kibanaUrlInput.value, + kibana_urls: kibanaUrlsInput.value, }); if (settingsResponse.error) { throw settingsResponse.error; @@ -108,7 +108,7 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { } }, inputs: { - kibanaUrl: kibanaUrlInput, + kibanaUrls: kibanaUrlsInput, elasticsearchUrl: elasticsearchUrlInput, }, }; @@ -131,8 +131,8 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { useEffect(() => { if (settings) { - inputs.kibanaUrl.setValue( - settings.kibana_url || [`${window.location.origin}${core.http.basePath.get()}`] + inputs.kibanaUrls.setValue( + settings.kibana_urls || [`${window.location.origin}${core.http.basePath.get()}`] ); } // eslint-disable-next-line react-hooks/exhaustive-deps @@ -234,9 +234,9 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { label={i18n.translate('xpack.ingestManager.settings.kibanaUrlLabel', { defaultMessage: 'Kibana URL', })} - {...inputs.kibanaUrl.formRowProps} + {...inputs.kibanaUrls.formRowProps} > - + diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx index 7a73a55f397b3..1debd57541b41 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx @@ -34,9 +34,9 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic const settings = useGetSettings(); const apiKey = useGetOneEnrollmentAPIKey(selectedAPIKeyId); - const kibanaUrls = settings.data?.item?.kibana_url; - const kibanaUrl = kibanaUrls - ? kibanaUrls[0] + const kibanaUrlsSettings = settings.data?.item?.kibana_urls; + const kibanaUrls = kibanaUrlsSettings + ? kibanaUrlsSettings[0] : `${window.location.origin}${core.http.basePath.get()}`; const kibanaCASha256 = settings.data?.item?.kibana_ca_sha256; @@ -51,7 +51,7 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic children: apiKey.data && ( ), diff --git a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts index 8d635256076d8..c767d3e80d2b7 100644 --- a/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/install_script/index.ts @@ -38,7 +38,7 @@ export const registerRoutes = ({ const http = appContextService.getHttpSetup(); const serverInfo = http.getServerInfo(); const basePath = http.basePath; - const kibanaUrl = (await settingsService.getSettings(soClient)).kibana_url || [ + const kibanaUrls = (await settingsService.getSettings(soClient)).kibana_urls || [ url.format({ protocol: serverInfo.protocol, hostname: serverInfo.hostname, @@ -47,7 +47,7 @@ export const registerRoutes = ({ }), ]; - const script = getScript(request.params.osType, kibanaUrl[0]); + const script = getScript(request.params.osType, kibanaUrls[0]); return response.ok({ body: script }); } diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts index 1bbe3b71bf919..aff8e607622d4 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts @@ -23,6 +23,7 @@ import { migrateAgentPolicyToV7100, migrateEnrollmentApiKeysToV7100, migratePackagePolicyToV7100, + migrateSettingsToV7100, } from './migrations/to_v7_10_0'; /* @@ -43,11 +44,14 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { properties: { agent_auto_upgrade: { type: 'keyword' }, package_auto_upgrade: { type: 'keyword' }, - kibana_url: { type: 'keyword' }, + kibana_urls: { type: 'keyword' }, kibana_ca_sha256: { type: 'keyword' }, has_seen_add_data_notice: { type: 'boolean', index: false }, }, }, + migrations: { + '7.10.0': migrateSettingsToV7100, + }, }, [AGENT_SAVED_OBJECT_TYPE]: { name: AGENT_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts index b60903dbd2bd0..5e36ce46c099b 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts @@ -5,7 +5,14 @@ */ import { SavedObjectMigrationFn } from 'kibana/server'; -import { Agent, AgentEvent, AgentPolicy, PackagePolicy, EnrollmentAPIKey } from '../../types'; +import { + Agent, + AgentEvent, + AgentPolicy, + PackagePolicy, + EnrollmentAPIKey, + Settings, +} from '../../types'; export const migrateAgentToV7100: SavedObjectMigrationFn< Exclude & { @@ -72,3 +79,16 @@ export const migratePackagePolicyToV7100: SavedObjectMigrationFn< return packagePolicyDoc; }; + +export const migrateSettingsToV7100: SavedObjectMigrationFn< + Exclude & { + kibana_url: string; + }, + Settings +> = (settingsDoc) => { + settingsDoc.attributes.kibana_urls = [settingsDoc.attributes.kibana_url]; + // @ts-expect-error + delete settingsDoc.attributes.kibana_url; + + return settingsDoc; +}; diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts index 142de1e4b718f..d9dffa03b2290 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.test.ts @@ -25,7 +25,7 @@ function getSavedObjectMock(agentPolicyAttributes: any) { { id: '93f74c0-e876-11ea-b7d3-8b2acec6f75c', attributes: { - kibana_urls: ['http://localhost:5603'] + kibana_urls: ['http://localhost:5603'], }, type: 'ingest_manager_settings', score: 1, @@ -80,9 +80,9 @@ describe('agent policy', () => { inputs: [], revision: 1, fleet: { - kibana:{ - hosts: ['http://localhost:5603'] - } + kibana: { + hosts: ['http://localhost:5603'], + }, }, agent: { monitoring: { @@ -114,9 +114,9 @@ describe('agent policy', () => { inputs: [], revision: 1, fleet: { - kibana:{ - hosts: ['http://localhost:5603'] - } + kibana: { + hosts: ['http://localhost:5603'], + }, }, agent: { monitoring: { @@ -149,9 +149,9 @@ describe('agent policy', () => { inputs: [], revision: 1, fleet: { - kibana:{ - hosts: ['http://localhost:5603'] - } + kibana: { + hosts: ['http://localhost:5603'], + }, }, agent: { monitoring: { diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 7b9b265a84d7b..2c97bba0cac45 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -464,7 +464,7 @@ class AgentPolicyService { } catch (error) { throw new Error('Default settings is not setup'); } - if (!settings.kibana_urls) throw new Error('kibana_urls is missing') + if (!settings.kibana_urls) throw new Error('kibana_urls is missing'); fullAgentPolicy.fleet = { kibana: { hosts: settings.kibana_urls, diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index 24ef1f09c524e..ca8c38a048b1e 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -76,7 +76,7 @@ async function createSetupSideEffects( return settingsService.saveSettings(soClient, { agent_auto_upgrade: true, package_auto_upgrade: true, - kibana_url: [cloudUrl || flagsUrl || defaultUrl].flat(), + kibana_urls: [cloudUrl || flagsUrl || defaultUrl].flat(), }); } diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts index 64e47f3438e13..35718491c9224 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/settings.ts @@ -12,7 +12,7 @@ export const PutSettingsRequestSchema = { body: schema.object({ agent_auto_upgrade: schema.maybe(schema.boolean()), package_auto_upgrade: schema.maybe(schema.boolean()), - kibana_url: schema.maybe( + kibana_urls: schema.maybe( schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { validate: (value) => { if (isDiffPathProtocol(value)) { diff --git a/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts b/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts index 7d185da169fcc..86292b535db2d 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/settings/update.ts @@ -36,7 +36,7 @@ export default function (providerContext: FtrProviderContext) { await supertest .put(`/api/ingest_manager/settings`) .set('kbn-xsrf', 'xxxx') - .send({ kibana_url: ['http://localhost:1232/abc', 'http://localhost:1232/abc'] }); + .send({ kibana_urls: ['http://localhost:1232/abc', 'http://localhost:1232/abc'] }); const getTestPolicy1Res = await kibanaServer.savedObjects.get({ type: 'ingest-agent-policies', From bb7eb0712a6a5e59ebed050279d8f18fd8dc4b03 Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 1 Sep 2020 14:02:15 -0400 Subject: [PATCH 16/17] leave instructions single kibana url --- .../components/enrollment_instructions/manual/index.tsx | 6 +++--- .../agent_enrollment_flyout/managed_instructions.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 5d6ae4aecc0f5..550c282460531 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EnrollmentAPIKey } from '../../../types'; interface Props { - kibanaUrls: string; + kibanaUrl: string; apiKey: EnrollmentAPIKey; kibanaCASha256?: string; } @@ -22,11 +22,11 @@ const CommandCode = styled.pre({ }); export const ManualInstructions: React.FunctionComponent = ({ - kibanaUrls, + kibanaUrl, apiKey, kibanaCASha256, }) => { - const enrollArgs = `${kibanaUrls} ${apiKey.api_key}${ + const enrollArgs = `${kibanaUrl} ${apiKey.api_key}${ kibanaCASha256 ? ` --ca_sha256=${kibanaCASha256}` : '' }`; const macOsLinuxTarCommand = `./elastic-agent enroll ${enrollArgs} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx index 1debd57541b41..9307229cdc258 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx @@ -35,7 +35,7 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic const apiKey = useGetOneEnrollmentAPIKey(selectedAPIKeyId); const kibanaUrlsSettings = settings.data?.item?.kibana_urls; - const kibanaUrls = kibanaUrlsSettings + const kibanaUrl = kibanaUrlsSettings ? kibanaUrlsSettings[0] : `${window.location.origin}${core.http.basePath.get()}`; @@ -51,7 +51,7 @@ export const ManagedInstructions: React.FunctionComponent = ({ agentPolic children: apiKey.data && ( ), From 3577435f4d8fa1b925eb64b4db8e80e65a674463 Mon Sep 17 00:00:00 2001 From: neptunian Date: Tue, 1 Sep 2020 15:23:48 -0400 Subject: [PATCH 17/17] make kibana_url and other attributes created during setup required, fix types --- .../common/types/models/settings.ts | 8 ++-- .../components/settings_flyout.tsx | 5 +-- .../server/services/settings.ts | 44 ++++++++++++++++--- .../ingest_manager/server/services/setup.ts | 26 ++--------- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/types/models/settings.ts b/x-pack/plugins/ingest_manager/common/types/models/settings.ts index 4433adf567442..f554f4b392ad6 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/settings.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/settings.ts @@ -5,10 +5,10 @@ */ import { SavedObjectAttributes } from 'src/core/public'; -interface BaseSettings { - agent_auto_upgrade?: boolean; - package_auto_upgrade?: boolean; - kibana_urls?: string[]; +export interface BaseSettings { + agent_auto_upgrade: boolean; + package_auto_upgrade: boolean; + kibana_urls: string[]; kibana_ca_sha256?: string; has_seen_add_data_notice?: boolean; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index 8bd3512813ad1..e0d843ad773b8 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -115,7 +115,6 @@ function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { } export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { - const core = useCore(); const settingsRequest = useGetSettings(); const settings = settingsRequest?.data?.item; const outputsRequest = useGetOutputs(); @@ -131,9 +130,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { useEffect(() => { if (settings) { - inputs.kibanaUrls.setValue( - settings.kibana_urls || [`${window.location.origin}${core.http.basePath.get()}`] - ); + inputs.kibanaUrls.setValue(settings.kibana_urls); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [settings]); diff --git a/x-pack/plugins/ingest_manager/server/services/settings.ts b/x-pack/plugins/ingest_manager/server/services/settings.ts index f1c09746d9abd..25223fbc08535 100644 --- a/x-pack/plugins/ingest_manager/server/services/settings.ts +++ b/x-pack/plugins/ingest_manager/server/services/settings.ts @@ -5,7 +5,15 @@ */ import Boom from 'boom'; import { SavedObjectsClientContract } from 'kibana/server'; -import { GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, SettingsSOAttributes, Settings } from '../../common'; +import url from 'url'; +import { + GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + SettingsSOAttributes, + Settings, + decodeCloudId, + BaseSettings, +} from '../../common'; +import { appContextService } from './app_context'; export async function getSettings(soClient: SavedObjectsClientContract): Promise { const res = await soClient.find({ @@ -25,7 +33,7 @@ export async function getSettings(soClient: SavedObjectsClientContract): Promise export async function saveSettings( soClient: SavedObjectsClientContract, newData: Partial> -): Promise { +): Promise & Pick> { try { const settings = await getSettings(soClient); @@ -41,10 +49,11 @@ export async function saveSettings( }; } catch (e) { if (e.isBoom && e.output.statusCode === 404) { - const res = await soClient.create( - GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, - newData - ); + const defaultSettings = createDefaultSettings(); + const res = await soClient.create(GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, { + ...defaultSettings, + ...newData, + }); return { id: res.id, @@ -55,3 +64,26 @@ export async function saveSettings( throw e; } } + +export function createDefaultSettings(): BaseSettings { + const http = appContextService.getHttpSetup(); + const serverInfo = http.getServerInfo(); + const basePath = http.basePath; + + const cloud = appContextService.getCloud(); + const cloudId = cloud?.isCloudEnabled && cloud.cloudId; + const cloudUrl = cloudId && decodeCloudId(cloudId)?.kibanaUrl; + const flagsUrl = appContextService.getConfig()?.fleet?.kibana?.host; + const defaultUrl = url.format({ + protocol: serverInfo.protocol, + hostname: serverInfo.hostname, + port: serverInfo.port, + pathname: basePath.serverBasePath, + }); + + return { + agent_auto_upgrade: true, + package_auto_upgrade: true, + kibana_urls: [cloudUrl || flagsUrl || defaultUrl].flat(), + }; +} diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index ca8c38a048b1e..ec3a05a4fa390 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import url from 'url'; import uuid from 'uuid'; import { SavedObjectsClientContract } from 'src/core/server'; import { CallESAsCurrentUser } from '../types'; @@ -22,14 +21,13 @@ import { Installation, Output, DEFAULT_AGENT_POLICIES_PACKAGES, - decodeCloudId, } from '../../common'; import { getPackageInfo } from './epm/packages'; import { packagePolicyService } from './package_policy'; import { generateEnrollmentAPIKey } from './api_keys'; import { settingsService } from '.'; -import { appContextService } from './app_context'; import { awaitIfPending } from './setup_utils'; +import { createDefaultSettings } from './settings'; const FLEET_ENROLL_USERNAME = 'fleet_enroll'; const FLEET_ENROLL_ROLE = 'fleet_enroll'; @@ -58,26 +56,8 @@ async function createSetupSideEffects( ensureDefaultIndices(callCluster), settingsService.getSettings(soClient).catch((e: any) => { if (e.isBoom && e.output.statusCode === 404) { - const http = appContextService.getHttpSetup(); - const serverInfo = http.getServerInfo(); - const basePath = http.basePath; - - const cloud = appContextService.getCloud(); - const cloudId = cloud?.isCloudEnabled && cloud.cloudId; - const cloudUrl = cloudId && decodeCloudId(cloudId)?.kibanaUrl; - const flagsUrl = appContextService.getConfig()?.fleet?.kibana?.host; - const defaultUrl = url.format({ - protocol: serverInfo.protocol, - hostname: serverInfo.hostname, - port: serverInfo.port, - pathname: basePath.serverBasePath, - }); - - return settingsService.saveSettings(soClient, { - agent_auto_upgrade: true, - package_auto_upgrade: true, - kibana_urls: [cloudUrl || flagsUrl || defaultUrl].flat(), - }); + const defaultSettings = createDefaultSettings(); + return settingsService.saveSettings(soClient, defaultSettings); } return Promise.reject(e);