diff --git a/packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts b/packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts index 3c1dc224a21d7..94905494b0ee0 100644 --- a/packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts +++ b/packages/core/saved-objects/core-saved-objects-api-server/src/saved_objects_repository.ts @@ -306,9 +306,17 @@ export interface ISavedObjectsRepository { /** * Updates all objects containing a reference to the given {type, id} tuple to remove the said reference. * - * @remarks Will throw a conflict error if the `update_by_query` operation returns any failure. In that case - * some references might have been removed, and some were not. It is the caller's responsibility - * to handle and fix this situation if it was to happen. + * @remarks + * Will throw a conflict error if the `update_by_query` operation returns any failure. In that case some + * references might have been removed, and some were not. It is the caller's responsibility to handle and fix + * this situation if it was to happen. + * + * Intended use is to provide clean up of any references to an object which is being deleted (e.g. deleting + * a tag). See discussion here: https://github.com/elastic/kibana/issues/135259#issuecomment-1482515139 + * + * When security is enabled, authorization for this method is based only on authorization to delete the object + * represented by the {type, id} tuple. Therefore it is recommended only to call this method for the intended + * use case. * * @param {string} type - the type of the object to remove references to * @param {string} id - the ID of the object to remove references to diff --git a/packages/core/saved-objects/core-saved-objects-server/src/extensions/security.ts b/packages/core/saved-objects/core-saved-objects-server/src/extensions/security.ts index 68637be38b6f2..58bbb91ec7de1 100644 --- a/packages/core/saved-objects/core-saved-objects-server/src/extensions/security.ts +++ b/packages/core/saved-objects/core-saved-objects-server/src/extensions/security.ts @@ -407,7 +407,12 @@ export interface ISavedObjectsSecurityExtension { ) => Promise>; /** - * Performs authorization for the REMOVE_REFERENCES security action + * Performs authorization for the REMOVE_REFERENCES security action. Checks for authorization + * to delete the object to which references are to be removed. In reality, the operation is an + * UPDATE to all objects that reference the given object, but the intended use for the + * removeReferencesTo method is to clean up any references to an object which is being deleted + * (e.g. deleting a tag). + * See discussion here: https://github.com/elastic/kibana/issues/135259#issuecomment-1482515139 * @param params the namespace and object to authorize * @returns CheckAuthorizationResult - the resulting authorization level and authorization map */ diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.test.ts index b345e821be3fe..a4cb6a26d3767 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.test.ts @@ -167,6 +167,37 @@ describe('createConcreteWriteIndex', () => { expect(logger.error).toHaveBeenCalledWith(`Error creating concrete write index - fail`); }); + it(`should retry getting index on transient ES error`, async () => { + clusterClient.indices.getAlias.mockImplementation(async () => ({})); + const error = new Error(`fail`) as EsError; + error.meta = { + body: { + error: { + type: 'resource_already_exists_exception', + }, + }, + }; + clusterClient.indices.create.mockRejectedValueOnce(error); + clusterClient.indices.get + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockImplementationOnce(async () => ({ + '.internal.alerts-test.alerts-default-000001': { + aliases: { '.alerts-test.alerts-default': { is_write_index: true } }, + }, + })); + + await createConcreteWriteIndex({ + logger, + esClient: clusterClient, + indexPatterns: IndexPatterns, + totalFieldsLimit: 2500, + }); + + expect(clusterClient.indices.get).toHaveBeenCalledTimes(3); + expect(logger.error).toHaveBeenCalledWith(`Error creating concrete write index - fail`); + }); + it(`should log and throw error if ES throws resource_already_exists_exception error and existing index is not the write index`, async () => { clusterClient.indices.getAlias.mockImplementation(async () => ({})); const error = new Error(`fail`) as EsError; @@ -265,6 +296,42 @@ describe('createConcreteWriteIndex', () => { expect(clusterClient.indices.putMapping).toHaveBeenCalledTimes(2); }); + it(`should retry simulateIndexTemplate on transient ES errors`, async () => { + clusterClient.indices.getAlias.mockImplementation(async () => GetAliasResponse); + clusterClient.indices.simulateIndexTemplate + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockImplementation(async () => SimulateTemplateResponse); + + await createConcreteWriteIndex({ + logger, + esClient: clusterClient, + indexPatterns: IndexPatterns, + totalFieldsLimit: 2500, + }); + + expect(clusterClient.indices.simulateIndexTemplate).toHaveBeenCalledTimes(4); + }); + + it(`should retry getting alias on transient ES errors`, async () => { + clusterClient.indices.getAlias + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockImplementation(async () => GetAliasResponse); + clusterClient.indices.simulateIndexTemplate.mockImplementation( + async () => SimulateTemplateResponse + ); + + await createConcreteWriteIndex({ + logger, + esClient: clusterClient, + indexPatterns: IndexPatterns, + totalFieldsLimit: 2500, + }); + + expect(clusterClient.indices.getAlias).toHaveBeenCalledTimes(3); + }); + it(`should retry settings update on transient ES errors`, async () => { clusterClient.indices.getAlias.mockImplementation(async () => GetAliasResponse); clusterClient.indices.simulateIndexTemplate.mockImplementation( diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.ts index df32e021602cf..31aface312913 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_concrete_write_index.ts @@ -68,9 +68,10 @@ const updateUnderlyingMapping = async ({ const { index, alias } = concreteIndexInfo; let simulatedIndexMapping: IndicesSimulateIndexTemplateResponse; try { - simulatedIndexMapping = await esClient.indices.simulateIndexTemplate({ - name: index, - }); + simulatedIndexMapping = await retryTransientEsErrors( + () => esClient.indices.simulateIndexTemplate({ name: index }), + { logger } + ); } catch (err) { logger.error( `Ignored PUT mappings for alias ${alias}; error generating simulated mappings: ${err.message}` @@ -149,10 +150,14 @@ export const createConcreteWriteIndex = async ({ try { // Specify both the index pattern for the backing indices and their aliases // The alias prevents the request from finding other namespaces that could match the -* pattern - const response = await esClient.indices.getAlias({ - index: indexPatterns.pattern, - name: indexPatterns.basePattern, - }); + const response = await retryTransientEsErrors( + () => + esClient.indices.getAlias({ + index: indexPatterns.pattern, + name: indexPatterns.basePattern, + }), + { logger } + ); concreteIndices = Object.entries(response).flatMap(([index, { aliases }]) => Object.entries(aliases).map(([aliasName, aliasProperties]) => ({ @@ -213,9 +218,7 @@ export const createConcreteWriteIndex = async ({ }, }, }), - { - logger, - } + { logger } ); } catch (error) { logger.error(`Error creating concrete write index - ${error.message}`); @@ -223,9 +226,10 @@ export const createConcreteWriteIndex = async ({ // something else created it so suppress the error. If it's not the write // index, that's bad, throw an error. if (error?.meta?.body?.error?.type === 'resource_already_exists_exception') { - const existingIndices = await esClient.indices.get({ - index: indexPatterns.name, - }); + const existingIndices = await retryTransientEsErrors( + () => esClient.indices.get({ index: indexPatterns.name }), + { logger } + ); if (!existingIndices[indexPatterns.name]?.aliases?.[indexPatterns.alias]?.is_write_index) { throw Error( `Attempted to create index: ${indexPatterns.name} as the write index for alias: ${indexPatterns.alias}, but the index already exists and is not the write index for the alias` diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts index 6eda12a6898e8..1083807a29c9f 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.test.ts @@ -188,4 +188,82 @@ describe('createOrUpdateComponentTemplate', () => { }, }); }); + + it(`should retry getIndexTemplate and putIndexTemplate on transient ES errors`, async () => { + clusterClient.cluster.putComponentTemplate.mockRejectedValueOnce( + new EsErrors.ResponseError( + elasticsearchClientMock.createApiResponse({ + statusCode: 400, + body: { + error: { + root_cause: [ + { + type: 'illegal_argument_exception', + reason: + 'updating component template [.alerts-ecs-mappings] results in invalid composable template [.alerts-security.alerts-default-index-template] after templates are merged', + }, + ], + type: 'illegal_argument_exception', + reason: + 'updating component template [.alerts-ecs-mappings] results in invalid composable template [.alerts-security.alerts-default-index-template] after templates are merged', + caused_by: { + type: 'illegal_argument_exception', + reason: + 'composable template [.alerts-security.alerts-default-index-template] template after composition with component templates [.alerts-ecs-mappings, .alerts-security.alerts-mappings, .alerts-technical-mappings] is invalid', + caused_by: { + type: 'illegal_argument_exception', + reason: + 'invalid composite mappings for [.alerts-security.alerts-default-index-template]', + caused_by: { + type: 'illegal_argument_exception', + reason: 'Limit of total fields [1900] has been exceeded', + }, + }, + }, + }, + }, + }) + ) + ); + const existingIndexTemplate = { + name: 'test-template', + index_template: { + index_patterns: ['test*'], + composed_of: ['test-mappings'], + template: { + settings: { + auto_expand_replicas: '0-1', + hidden: true, + 'index.lifecycle': { + name: '.alerts-ilm-policy', + rollover_alias: `.alerts-empty-default`, + }, + 'index.mapping.total_fields.limit': 1800, + }, + mappings: { + dynamic: false, + }, + }, + }, + }; + clusterClient.indices.getIndexTemplate + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockResolvedValueOnce({ + index_templates: [existingIndexTemplate], + }); + clusterClient.indices.putIndexTemplate + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockResolvedValue({ acknowledged: true }); + await createOrUpdateComponentTemplate({ + logger, + esClient: clusterClient, + template: ComponentTemplate, + totalFieldsLimit: 2500, + }); + + expect(clusterClient.indices.getIndexTemplate).toHaveBeenCalledTimes(3); + expect(clusterClient.indices.putIndexTemplate).toHaveBeenCalledTimes(3); + }); }); diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts index e9d2ca73ff3fb..97cdef833adbc 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_component_template.ts @@ -23,10 +23,14 @@ interface CreateOrUpdateComponentTemplateOpts { const getIndexTemplatesUsingComponentTemplate = async ( esClient: ElasticsearchClient, componentTemplateName: string, - totalFieldsLimit: number + totalFieldsLimit: number, + logger: Logger ) => { // Get all index templates and filter down to just the ones referencing this component template - const { index_templates: indexTemplates } = await esClient.indices.getIndexTemplate(); + const { index_templates: indexTemplates } = await retryTransientEsErrors( + () => esClient.indices.getIndexTemplate(), + { logger } + ); const indexTemplatesUsingComponentTemplate = (indexTemplates ?? []).filter( (indexTemplate: IndicesGetIndexTemplateIndexTemplateItem) => indexTemplate.index_template.composed_of.includes(componentTemplateName) @@ -34,19 +38,23 @@ const getIndexTemplatesUsingComponentTemplate = async ( await asyncForEach( indexTemplatesUsingComponentTemplate, async (template: IndicesGetIndexTemplateIndexTemplateItem) => { - await esClient.indices.putIndexTemplate({ - name: template.name, - body: { - ...template.index_template, - template: { - ...template.index_template.template, - settings: { - ...template.index_template.template?.settings, - 'index.mapping.total_fields.limit': totalFieldsLimit, + await retryTransientEsErrors( + () => + esClient.indices.putIndexTemplate({ + name: template.name, + body: { + ...template.index_template, + template: { + ...template.index_template.template, + settings: { + ...template.index_template.template?.settings, + 'index.mapping.total_fields.limit': totalFieldsLimit, + }, + }, }, - }, - }, - }); + }), + { logger } + ); } ); }; @@ -54,10 +62,11 @@ const getIndexTemplatesUsingComponentTemplate = async ( const createOrUpdateComponentTemplateHelper = async ( esClient: ElasticsearchClient, template: ClusterPutComponentTemplateRequest, - totalFieldsLimit: number + totalFieldsLimit: number, + logger: Logger ) => { try { - await esClient.cluster.putComponentTemplate(template); + await retryTransientEsErrors(() => esClient.cluster.putComponentTemplate(template), { logger }); } catch (error) { const reason = error?.meta?.body?.error?.caused_by?.caused_by?.caused_by?.reason; if (reason && reason.match(/Limit of total fields \[\d+\] has been exceeded/) != null) { @@ -68,10 +77,17 @@ const createOrUpdateComponentTemplateHelper = async ( // number of new ECS fields pushes the composed mapping above the limit, this error will // occur. We have to update the field limit inside the index template now otherwise we // can never update the component template - await getIndexTemplatesUsingComponentTemplate(esClient, template.name, totalFieldsLimit); + await getIndexTemplatesUsingComponentTemplate( + esClient, + template.name, + totalFieldsLimit, + logger + ); // Try to update the component template again - await esClient.cluster.putComponentTemplate(template); + await retryTransientEsErrors(() => esClient.cluster.putComponentTemplate(template), { + logger, + }); } else { throw error; } @@ -87,10 +103,7 @@ export const createOrUpdateComponentTemplate = async ({ logger.info(`Installing component template ${template.name}`); try { - await retryTransientEsErrors( - () => createOrUpdateComponentTemplateHelper(esClient, template, totalFieldsLimit), - { logger } - ); + await createOrUpdateComponentTemplateHelper(esClient, template, totalFieldsLimit, logger); } catch (err) { logger.error(`Error installing component template ${template.name} - ${err.message}`); throw err; diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts index c095274b539b9..d4ce203a0d0e3 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts @@ -137,6 +137,21 @@ describe('createOrUpdateIndexTemplate', () => { expect(clusterClient.indices.putIndexTemplate).toHaveBeenCalledTimes(3); }); + it(`should retry simulateTemplate on transient ES errors`, async () => { + clusterClient.indices.simulateTemplate + .mockRejectedValueOnce(new EsErrors.ConnectionError('foo')) + .mockRejectedValueOnce(new EsErrors.TimeoutError('timeout')) + .mockImplementation(async () => SimulateTemplateResponse); + clusterClient.indices.putIndexTemplate.mockResolvedValue({ acknowledged: true }); + await createOrUpdateIndexTemplate({ + logger, + esClient: clusterClient, + template: IndexTemplate, + }); + + expect(clusterClient.indices.simulateTemplate).toHaveBeenCalledTimes(3); + }); + it(`should log and throw error if max retries exceeded`, async () => { clusterClient.indices.simulateTemplate.mockImplementation(async () => SimulateTemplateResponse); clusterClient.indices.putIndexTemplate.mockRejectedValue(new EsErrors.ConnectionError('foo')); diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts index 0c5c221403186..a17fad2d875ed 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts @@ -100,7 +100,10 @@ export const createOrUpdateIndexTemplate = async ({ let mappings: MappingTypeMapping = {}; try { // Simulate the index template to proactively identify any issues with the mapping - const simulateResponse = await esClient.indices.simulateTemplate(template); + const simulateResponse = await retryTransientEsErrors( + () => esClient.indices.simulateTemplate(template), + { logger } + ); mappings = simulateResponse.template.mappings; } catch (err) { logger.error( diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx index 65cbba050e8ec..2bdf1e4c82eb7 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/fields/script_recorder_fields.tsx @@ -63,7 +63,7 @@ export function ScriptRecorderFields({ onChange, script, fileName, isEditable }: iconSide="right" > @@ -78,7 +78,7 @@ export function ScriptRecorderFields({ onChange, script, fileName, isEditable }: color="danger" > diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx index 884a81020cedf..74ead8c6906d5 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.test.tsx @@ -23,7 +23,7 @@ import { defaultBrowserAdvancedFields as defaultConfig, defaultBrowserSimpleFields, } from '../contexts'; -import { validate as centralValidation } from '../validation'; +import { validate as centralValidation } from '../../monitor_management/validation'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; const defaultValidation = centralValidation[DataStream.BROWSER]; @@ -89,29 +89,14 @@ describe('', () => { }); }); - it('only displayed filter options when zip url is truthy', () => { - const { queryByText, getByText, rerender } = render(); + it('does not display filter options (zip url has been deprecated)', () => { + const { queryByText } = render(); expect( queryByText( /Use these options to apply the selected monitor settings to a subset of the tests in your suite./ ) ).not.toBeInTheDocument(); - - rerender( - - ); - - expect( - getByText( - /Use these options to apply the selected monitor settings to a subset of the tests in your suite./ - ) - ).toBeInTheDocument(); }); it('renders upstream fields', () => { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx index 64409608f7a4d..8fe90c800f309 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/advanced_fields.tsx @@ -7,18 +7,11 @@ import React, { memo, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiAccordion, - EuiSelect, - EuiFieldText, - EuiCheckbox, - EuiFormRow, - EuiSpacer, -} from '@elastic/eui'; +import { EuiAccordion, EuiSelect, EuiCheckbox, EuiFormRow, EuiSpacer } from '@elastic/eui'; import { ComboBox } from '../combo_box'; import { DescribedFormGroupWithWrap } from '../common/described_form_group_with_wrap'; -import { useBrowserAdvancedFieldsContext, useBrowserSimpleFieldsContext } from '../contexts'; +import { useBrowserAdvancedFieldsContext } from '../contexts'; import { ConfigKey, Validation, ScreenshotOption } from '../types'; @@ -35,7 +28,6 @@ interface Props { export const BrowserAdvancedFields = memo( ({ validate, children, minColumnWidth, onFieldBlur }) => { const { fields, setFields } = useBrowserAdvancedFieldsContext(); - const { fields: simpleFields } = useBrowserSimpleFieldsContext(); const handleInputChange = useCallback( ({ value, configKey }: { value: unknown; configKey: ConfigKey }) => { @@ -51,78 +43,6 @@ export const BrowserAdvancedFields = memo( data-test-subj="syntheticsBrowserAdvancedFieldsAccordion" > - {simpleFields[ConfigKey.SOURCE_ZIP_URL] && ( - - - - } - description={ - - } - > - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ - value: event.target.value, - configKey: ConfigKey.JOURNEY_FILTERS_MATCH, - }) - } - onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_MATCH)} - data-test-subj="syntheticsBrowserJourneyFiltersMatch" - /> - - - } - labelAppend={} - helpText={ - - } - > - - handleInputChange({ value, configKey: ConfigKey.JOURNEY_FILTERS_TAGS }) - } - onBlur={() => onFieldBlur?.(ConfigKey.JOURNEY_FILTERS_TAGS)} - data-test-subj="syntheticsBrowserJourneyFiltersTags" - /> - - - )} { - const makeThrottlingConfig = (value: string) => ({ - [ConfigKey.THROTTLING_CONFIG]: { value }, - }); - - describe('throttlingToParameterNormalizer', () => { - it('can extract download values', () => { - const fields = makeThrottlingConfig('10d/5u/2.5l'); - - expect(getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED)(fields)).toEqual('10'); - }); - - it('can extract upload values', () => { - const fields = makeThrottlingConfig('10d/5u/2.5l'); - - expect(getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED)(fields)).toEqual('5'); - }); - - it('can extract latency values', () => { - const fields = makeThrottlingConfig('10d/5u/2.5l'); - - expect(getThrottlingParamNormalizer(ConfigKey.LATENCY)(fields)).toEqual('2.5'); - }); - - it('returns default values when throttling is disabled', () => { - const fields = makeThrottlingConfig('false'); - - expect(getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED)(fields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.DOWNLOAD_SPEED] - ); - expect(getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED)(fields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.UPLOAD_SPEED] - ); - expect(getThrottlingParamNormalizer(ConfigKey.LATENCY)(fields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.LATENCY] - ); - }); - - it("returns default values when the desired suffix doesn't exist", () => { - const noUploadFields = makeThrottlingConfig('10d/2.5l'); - expect(getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED)(noUploadFields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.UPLOAD_SPEED] - ); - - const noDownloadFields = makeThrottlingConfig('10u/2.5l'); - expect(getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED)(noDownloadFields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.DOWNLOAD_SPEED] - ); - - const noLatencyFields = makeThrottlingConfig('10d/5u'); - expect(getThrottlingParamNormalizer(ConfigKey.LATENCY)(noLatencyFields)).toEqual( - defaultBrowserAdvancedFields[ConfigKey.LATENCY] - ); - }); - }); - - describe('isThrottlingEnabledNormalizer', () => { - it('returns true for any value that is not "false"', () => { - expect(isThrottlingEnabledNormalizer(makeThrottlingConfig('10d/2l'))).toEqual(true); - expect(isThrottlingEnabledNormalizer(makeThrottlingConfig('test'))).toEqual(true); - }); - - it('returns false when throttling config is the string "false"', () => { - expect(isThrottlingEnabledNormalizer(makeThrottlingConfig('false'))).toEqual(false); - }); - }); -}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts deleted file mode 100644 index d1d9917f19c3a..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/normalizers.ts +++ /dev/null @@ -1,115 +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 { - BrowserFields, - ConfigKey, - ThrottlingSuffix, - ThrottlingConfigKey, - configKeyToThrottlingSuffix, -} from '../types'; -import { - Normalizer, - commonNormalizers, - getNormalizer, - getJsonToJavascriptNormalizer, -} from '../common/normalizers'; -import { tlsNormalizers } from '../tls/normalizers'; - -import { defaultBrowserSimpleFields, defaultBrowserAdvancedFields } from '../contexts'; - -export type BrowserNormalizerMap = Record; - -const defaultBrowserFields = { - ...defaultBrowserSimpleFields, - ...defaultBrowserAdvancedFields, -}; - -export const getBrowserNormalizer = (key: ConfigKey) => { - return getNormalizer(key, defaultBrowserFields); -}; - -export const getBrowserJsonToJavascriptNormalizer = (key: ConfigKey) => { - return getJsonToJavascriptNormalizer(key, defaultBrowserFields); -}; - -export function throttlingToParameterNormalizer( - suffix: ThrottlingSuffix, - throttlingConfigValue?: string -): unknown { - if (!throttlingConfigValue || throttlingConfigValue === 'false') return null; - return ( - throttlingConfigValue - .split('/') - .filter((p) => p.endsWith(suffix))[0] - ?.slice(0, -1) ?? null - ); -} - -export const isThrottlingEnabledNormalizer: Normalizer = function isThrottlingEnabledNormalizer( - fields -) { - const throttlingEnabled = fields?.[ConfigKey.THROTTLING_CONFIG]?.value; - - // If we have any value that's not an explicit "false" it means throttling is "on" - return throttlingEnabled !== 'false'; -}; - -export function getThrottlingParamNormalizer(key: ThrottlingConfigKey): Normalizer { - const paramSuffix = configKeyToThrottlingSuffix[key]; - return (fields) => - throttlingToParameterNormalizer(paramSuffix, fields?.[ConfigKey.THROTTLING_CONFIG]?.value) ?? - defaultBrowserFields[key]; -} - -export const browserNormalizers: BrowserNormalizerMap = { - [ConfigKey.METADATA]: getBrowserJsonToJavascriptNormalizer(ConfigKey.METADATA), - [ConfigKey.URLS]: getBrowserNormalizer(ConfigKey.URLS), - [ConfigKey.PORT]: getBrowserNormalizer(ConfigKey.PORT), - [ConfigKey.SOURCE_ZIP_URL]: getBrowserNormalizer(ConfigKey.SOURCE_ZIP_URL), - [ConfigKey.SOURCE_ZIP_USERNAME]: getBrowserNormalizer(ConfigKey.SOURCE_ZIP_USERNAME), - [ConfigKey.SOURCE_ZIP_PASSWORD]: getBrowserNormalizer(ConfigKey.SOURCE_ZIP_PASSWORD), - [ConfigKey.SOURCE_ZIP_FOLDER]: getBrowserNormalizer(ConfigKey.SOURCE_ZIP_FOLDER), - [ConfigKey.SOURCE_PROJECT_CONTENT]: getBrowserNormalizer(ConfigKey.SOURCE_PROJECT_CONTENT), - [ConfigKey.SOURCE_INLINE]: getBrowserJsonToJavascriptNormalizer(ConfigKey.SOURCE_INLINE), - [ConfigKey.SOURCE_ZIP_PROXY_URL]: getBrowserNormalizer(ConfigKey.SOURCE_ZIP_PROXY_URL), - [ConfigKey.PARAMS]: getBrowserNormalizer(ConfigKey.PARAMS), - [ConfigKey.SCREENSHOTS]: getBrowserNormalizer(ConfigKey.SCREENSHOTS), - [ConfigKey.SYNTHETICS_ARGS]: getBrowserJsonToJavascriptNormalizer(ConfigKey.SYNTHETICS_ARGS), - [ConfigKey.IS_THROTTLING_ENABLED]: isThrottlingEnabledNormalizer, - [ConfigKey.DOWNLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.DOWNLOAD_SPEED), - [ConfigKey.UPLOAD_SPEED]: getThrottlingParamNormalizer(ConfigKey.UPLOAD_SPEED), - [ConfigKey.LATENCY]: getThrottlingParamNormalizer(ConfigKey.LATENCY), - [ConfigKey.THROTTLING_CONFIG]: getBrowserNormalizer(ConfigKey.THROTTLING_CONFIG), - [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: getBrowserJsonToJavascriptNormalizer( - ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES - ), - [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: getBrowserJsonToJavascriptNormalizer( - ConfigKey.ZIP_URL_TLS_CERTIFICATE - ), - [ConfigKey.ZIP_URL_TLS_KEY]: getBrowserJsonToJavascriptNormalizer(ConfigKey.ZIP_URL_TLS_KEY), - [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: getBrowserNormalizer( - ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE - ), - [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: getBrowserNormalizer( - ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE - ), - [ConfigKey.ZIP_URL_TLS_VERSION]: getBrowserJsonToJavascriptNormalizer( - ConfigKey.ZIP_URL_TLS_VERSION - ), - [ConfigKey.JOURNEY_FILTERS_MATCH]: getBrowserJsonToJavascriptNormalizer( - ConfigKey.JOURNEY_FILTERS_MATCH - ), - [ConfigKey.JOURNEY_FILTERS_TAGS]: getBrowserJsonToJavascriptNormalizer( - ConfigKey.JOURNEY_FILTERS_TAGS - ), - [ConfigKey.IGNORE_HTTPS_ERRORS]: getBrowserNormalizer(ConfigKey.IGNORE_HTTPS_ERRORS), - [ConfigKey.PLAYWRIGHT_OPTIONS]: getBrowserNormalizer(ConfigKey.PLAYWRIGHT_OPTIONS), - [ConfigKey.TEXT_ASSERTION]: getBrowserNormalizer(ConfigKey.TEXT_ASSERTION), - ...commonNormalizers, - ...tlsNormalizers, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx index 9765e83e914e6..7fb2f8382ae34 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/script_recorder_fields.tsx @@ -50,7 +50,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { target="_blank" > @@ -76,7 +76,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { iconSide="right" > @@ -91,7 +91,7 @@ export function ScriptRecorderFields({ onChange, script, fileName }: Props) { color="danger" > diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx index 25ed39569bc8b..5c8516d56ddf9 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/simple_fields.tsx @@ -29,24 +29,9 @@ export const BrowserSimpleFields = memo(({ validate, onFieldBlur }) => { [setFields] ); const onChangeSourceField = useCallback( - ({ - zipUrl, - folder, - username, - password, - inlineScript, - params, - proxyUrl, - isGeneratedScript, - fileName, - }) => { + ({ inlineScript, params, isGeneratedScript, fileName }) => { setFields((prevFields) => ({ ...prevFields, - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_ZIP_PROXY_URL]: proxyUrl, - [ConfigKey.SOURCE_ZIP_FOLDER]: folder, - [ConfigKey.SOURCE_ZIP_USERNAME]: username, - [ConfigKey.SOURCE_ZIP_PASSWORD]: password, [ConfigKey.SOURCE_INLINE]: inlineScript, [ConfigKey.PARAMS]: params, [ConfigKey.METADATA]: { @@ -110,11 +95,6 @@ export const BrowserSimpleFields = memo(({ validate, onFieldBlur }) => { onFieldBlur={onFieldBlur} defaultConfig={useMemo( () => ({ - zipUrl: defaultValues[ConfigKey.SOURCE_ZIP_URL], - proxyUrl: defaultValues[ConfigKey.SOURCE_ZIP_PROXY_URL], - folder: defaultValues[ConfigKey.SOURCE_ZIP_FOLDER], - username: defaultValues[ConfigKey.SOURCE_ZIP_USERNAME], - password: defaultValues[ConfigKey.SOURCE_ZIP_PASSWORD], inlineScript: defaultValues[ConfigKey.SOURCE_INLINE], params: defaultValues[ConfigKey.PARAMS], isGeneratedScript: diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx index 34706d4d17cbc..2199ac4b0296b 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.test.tsx @@ -7,11 +7,10 @@ import 'jest-canvas-mock'; import React from 'react'; -import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { ConfigKey } from '../../../../../common/runtime_types'; +import { fireEvent, screen } from '@testing-library/react'; import { render } from '../../../lib/helper/rtl_helpers'; import { IPolicyConfigContextProvider } from '../contexts/policy_config_context'; -import { SourceField, Props, defaultValues } from './source_field'; +import { SourceField, Props } from './source_field'; import { BrowserSimpleFieldsContextProvider, PolicyConfigContextProvider } from '../contexts'; jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ @@ -31,14 +30,14 @@ jest.mock('@kbn/kibana-react-plugin/public', () => { ...original, // Mocking CodeEditor, which uses React Monaco under the hood CodeEditor: (props: any) => ( - { - props.onChange(e.jsonContent); - }} - /> + <> + + ), }; }); @@ -48,11 +47,10 @@ const onBlur = jest.fn(); describe('', () => { const WrappedComponent = ({ - isZipUrlSourceEnabled, defaultConfig, }: Omit & Partial) => { return ( - + @@ -64,34 +62,6 @@ describe('', () => { jest.clearAllMocks(); }); - it('calls onChange', async () => { - render(); - const zipUrl = 'test.zip'; - - const zip = screen.getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - - const zipUrlField = screen.getByTestId('syntheticsBrowserZipUrl'); - fireEvent.change(zipUrlField, { target: { value: zipUrl } }); - - await waitFor(() => { - expect(onChange).toBeCalledWith({ ...defaultValues, zipUrl }); - }); - }); - - it('calls onBlur', () => { - render(); - - const zip = screen.getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - - const zipUrlField = screen.getByTestId('syntheticsBrowserZipUrl'); - fireEvent.click(zipUrlField); - fireEvent.blur(zipUrlField); - - expect(onBlur).toBeCalledWith(ConfigKey.SOURCE_ZIP_URL); - }); - it('selects inline script by default', () => { render(); @@ -100,15 +70,9 @@ describe('', () => { ).toBeInTheDocument(); }); - it('shows zip source type by default', async () => { + it('does not show ZipUrl source type', async () => { render(); - expect(screen.getByTestId('syntheticsSourceTab__zipUrl')).toBeInTheDocument(); - }); - - it('does not show ZipUrl source type when isZipUrlSourceEnabled = false', async () => { - render(); - expect(screen.queryByTestId('syntheticsSourceTab__zipUrl')).not.toBeInTheDocument(); }); @@ -124,19 +88,5 @@ describe('', () => { fireEvent.click(recorder); expect(getByText('Parameters')).toBeInTheDocument(); - - const zip = getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - - expect(getByText('Parameters')).toBeInTheDocument(); - }); - - it('shows deprecated for zip url', () => { - const { getByText, getByTestId } = render(); - - const zip = getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - - expect(getByText('Zip URL is deprecated')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx index be3fe1a4d8d16..5a6cfef79bdd5 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/source_field.tsx @@ -10,38 +10,24 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { EuiCode, - EuiCallOut, - EuiLink, EuiTabbedContent, - EuiTabbedContentTab, EuiFormRow, - EuiFieldText, - EuiFieldPassword, EuiSpacer, EuiBetaBadge, EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; -import { usePolicyConfigContext } from '../contexts'; import { OptionalLabel } from '../optional_label'; import { CodeEditor } from '../code_editor'; import { ScriptRecorderFields } from './script_recorder_fields'; -import { ZipUrlTLSFields } from './zip_url_tls_fields'; import { ConfigKey, MonacoEditorLangId, Validation } from '../types'; -import { getDocLinks } from '../../../../kibana_services'; enum SourceType { INLINE = 'syntheticsBrowserInlineConfig', SCRIPT_RECORDER = 'syntheticsBrowserScriptRecorderConfig', - ZIP = 'syntheticsBrowserZipURLConfig', } interface SourceConfig { - zipUrl: string; - proxyUrl: string; - folder: string; - username: string; - password: string; inlineScript: string; params: string; isGeneratedScript?: boolean; @@ -56,11 +42,6 @@ export interface Props { } export const defaultValues = { - zipUrl: '', - proxyUrl: '', - folder: '', - username: '', - password: '', inlineScript: '', params: '', isGeneratedScript: false, @@ -81,7 +62,6 @@ export const SourceField = ({ defaultConfig = defaultValues, validate, }: Props) => { - const { isZipUrlSourceEnabled } = usePolicyConfigContext(); const [sourceType, setSourceType] = useState(getDefaultTab(defaultConfig)); const [config, setConfig] = useState(defaultConfig); @@ -94,18 +74,6 @@ export const SourceField = ({ [ConfigKey.SOURCE_INLINE]: config.inlineScript, }) ?? false; - const isZipUrlInvalid = - validate?.[ConfigKey.SOURCE_ZIP_URL]?.({ - [ConfigKey.SOURCE_ZIP_URL]: config.zipUrl, - }) ?? false; - - const zipUrlLabel = ( - - ); - const params = ( ); - const zipUrlSourceTabId = 'syntheticsBrowserZipURLConfig'; - const allTabs = [ + const tabs = [ { id: 'syntheticsBrowserInlineConfig', name: ( @@ -240,176 +207,8 @@ export const SourceField = ({ ), }, - { - id: zipUrlSourceTabId, - name: zipUrlLabel, - 'data-test-subj': `syntheticsSourceTab__zipUrl`, - content: ( - <> - - - } - size="s" - color="warning" - > - - - - ), - }} - /> - - - - } - helpText={ - - } - > - - setConfig((prevConfig) => ({ ...prevConfig, zipUrl: value })) - } - onBlur={() => onFieldBlur(ConfigKey.SOURCE_ZIP_URL)} - value={config.zipUrl} - data-test-subj="syntheticsBrowserZipUrl" - /> - - - - } - labelAppend={} - helpText={ - - } - > - - setConfig((prevConfig) => ({ ...prevConfig, proxyUrl: value })) - } - onBlur={() => onFieldBlur(ConfigKey.SOURCE_ZIP_PROXY_URL)} - value={config.proxyUrl} - data-test-subj="syntheticsBrowserZipUrlProxy" - /> - - - } - labelAppend={} - helpText={ - - } - > - - setConfig((prevConfig) => ({ ...prevConfig, folder: value })) - } - onBlur={() => onFieldBlur(ConfigKey.SOURCE_ZIP_FOLDER)} - value={config.folder} - data-test-subj="syntheticsBrowserZipUrlFolder" - /> - - {params} - - } - labelAppend={} - helpText={ - - } - > - - setConfig((prevConfig) => ({ ...prevConfig, username: value })) - } - onBlur={() => onFieldBlur(ConfigKey.SOURCE_ZIP_USERNAME)} - value={config.username} - data-test-subj="syntheticsBrowserZipUrlUsername" - /> - - - } - labelAppend={} - helpText={ - - } - > - - setConfig((prevConfig) => ({ ...prevConfig, password: value })) - } - onBlur={() => onFieldBlur(ConfigKey.SOURCE_ZIP_PASSWORD)} - value={config.password} - data-test-subj="syntheticsBrowserZipUrlPassword" - /> - - - ), - }, ]; - const tabs = isZipUrlSourceEnabled - ? allTabs - : allTabs.filter((tab: EuiTabbedContentTab) => tab.id !== zipUrlSourceTabId); - return ( ({ - ...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'), - htmlIdGenerator: () => () => `id-${Math.random()}`, -})); - -describe('', () => { - const WrappedComponent = ({ isEnabled = true }: { isEnabled?: boolean }) => { - return ( - - - - - - ); - }; - it('renders ZipUrlTLSFields', () => { - const { getByLabelText, getByText } = render(); - - const toggle = getByText('Enable TLS configuration for Zip URL'); - - fireEvent.click(toggle); - - expect(getByText('Certificate settings')).toBeInTheDocument(); - expect(getByText('Supported TLS protocols')).toBeInTheDocument(); - expect(getByLabelText('Client certificate')).toBeInTheDocument(); - expect(getByLabelText('Client key')).toBeInTheDocument(); - expect(getByLabelText('Certificate authorities')).toBeInTheDocument(); - expect(getByLabelText('Verification mode')).toBeInTheDocument(); - }); - - it('updates fields', async () => { - const { getByLabelText } = render(); - - const clientCertificate = getByLabelText('Client certificate') as HTMLInputElement; - const clientKey = getByLabelText('Client key') as HTMLInputElement; - const clientKeyPassphrase = getByLabelText('Client key passphrase') as HTMLInputElement; - const certificateAuthorities = getByLabelText('Certificate authorities') as HTMLInputElement; - const verificationMode = getByLabelText('Verification mode') as HTMLInputElement; - - const newValues = { - [ConfigKey.TLS_CERTIFICATE]: 'sampleClientCertificate', - [ConfigKey.TLS_KEY]: 'sampleClientKey', - [ConfigKey.TLS_KEY_PASSPHRASE]: 'sampleClientKeyPassphrase', - [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: 'sampleCertificateAuthorities', - [ConfigKey.TLS_VERIFICATION_MODE]: VerificationMode.NONE, - }; - - fireEvent.change(clientCertificate, { - target: { value: newValues[ConfigKey.TLS_CERTIFICATE] }, - }); - fireEvent.change(clientKey, { target: { value: newValues[ConfigKey.TLS_KEY] } }); - fireEvent.change(clientKeyPassphrase, { - target: { value: newValues[ConfigKey.TLS_KEY_PASSPHRASE] }, - }); - fireEvent.change(certificateAuthorities, { - target: { value: newValues[ConfigKey.TLS_CERTIFICATE_AUTHORITIES] }, - }); - fireEvent.change(verificationMode, { - target: { value: newValues[ConfigKey.TLS_VERIFICATION_MODE] }, - }); - - expect(clientCertificate.value).toEqual(newValues[ConfigKey.TLS_CERTIFICATE]); - expect(clientKey.value).toEqual(newValues[ConfigKey.TLS_KEY]); - expect(certificateAuthorities.value).toEqual(newValues[ConfigKey.TLS_CERTIFICATE_AUTHORITIES]); - expect(verificationMode.value).toEqual(newValues[ConfigKey.TLS_VERIFICATION_MODE]); - }); - - it('shows warning when verification mode is set to none', () => { - const { getByLabelText, getByText } = render(); - - const verificationMode = getByLabelText('Verification mode') as HTMLInputElement; - - fireEvent.change(verificationMode, { - target: { value: VerificationMode.NONE }, - }); - - expect(getByText('Disabling TLS')).toBeInTheDocument(); - }); - - it('does not show fields when isEnabled is false', async () => { - const { queryByLabelText } = render(); - - expect(queryByLabelText('Client certificate')).not.toBeInTheDocument(); - expect(queryByLabelText('Client key')).not.toBeInTheDocument(); - expect(queryByLabelText('Client key passphrase')).not.toBeInTheDocument(); - expect(queryByLabelText('Certificate authorities')).not.toBeInTheDocument(); - expect(queryByLabelText('verification mode')).not.toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx deleted file mode 100644 index 21f2a548413c1..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/browser/zip_url_tls_fields.tsx +++ /dev/null @@ -1,98 +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 React, { useCallback, useEffect } from 'react'; - -import { EuiSwitch, EuiFormRow } from '@elastic/eui'; - -import { FormattedMessage } from '@kbn/i18n-react'; - -import { TLSOptions, TLSConfig } from '../common/tls_options'; -import { - useBrowserSimpleFieldsContext, - usePolicyConfigContext, - defaultTLSFields, -} from '../contexts'; - -import { ConfigKey } from '../types'; - -export const ZipUrlTLSFields = () => { - const { defaultValues, setFields } = useBrowserSimpleFieldsContext(); - const { isZipUrlTLSEnabled, setIsZipUrlTLSEnabled } = usePolicyConfigContext(); - - const handleOnChange = useCallback( - (tlsConfig: TLSConfig) => { - setFields((prevFields) => ({ - ...prevFields, - [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: tlsConfig.certificateAuthorities, - [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: tlsConfig.certificate, - [ConfigKey.ZIP_URL_TLS_KEY]: tlsConfig.key, - [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: tlsConfig.keyPassphrase, - [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: tlsConfig.verificationMode, - [ConfigKey.ZIP_URL_TLS_VERSION]: tlsConfig.version, - })); - }, - [setFields] - ); - - useEffect(() => { - if (!isZipUrlTLSEnabled) { - setFields((prevFields) => ({ - ...prevFields, - [ConfigKey.ZIP_URL_TLS_CERTIFICATE_AUTHORITIES]: undefined, - [ConfigKey.ZIP_URL_TLS_CERTIFICATE]: undefined, - [ConfigKey.ZIP_URL_TLS_KEY]: undefined, - [ConfigKey.ZIP_URL_TLS_KEY_PASSPHRASE]: undefined, - [ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]: undefined, - [ConfigKey.ZIP_URL_TLS_VERSION]: undefined, - })); - } - }, [setFields, isZipUrlTLSEnabled]); - - return ( - - <> - - } - onChange={(event) => setIsZipUrlTLSEnabled(event.target.checked)} - /> - {isZipUrlTLSEnabled ? ( - - ) : null} - - - ); -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx index d089dacfaedb5..cf91e60c6da2d 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/contexts/policy_config_context.tsx @@ -23,16 +23,12 @@ interface IPolicyConfigContext { setName: React.Dispatch>; setLocations: React.Dispatch>; setIsTLSEnabled: React.Dispatch>; - setIsZipUrlTLSEnabled: React.Dispatch>; setNamespace: React.Dispatch>; monitorType: DataStream; defaultMonitorType: DataStream; isTLSEnabled?: boolean; - isZipUrlTLSEnabled?: boolean; - isZipUrlSourceEnabled?: boolean; runsOnService?: boolean; defaultIsTLSEnabled?: boolean; - defaultIsZipUrlTLSEnabled?: boolean; isEditable?: boolean; defaultName?: string; name?: string; @@ -50,12 +46,10 @@ export interface IPolicyConfigContextProvider { defaultMonitorType?: DataStream; runsOnService?: boolean; defaultIsTLSEnabled?: boolean; - defaultIsZipUrlTLSEnabled?: boolean; defaultName?: string; defaultLocations?: MonitorServiceLocations; defaultNamespace?: string; isEditable?: boolean; - isZipUrlSourceEnabled?: boolean; allowedScheduleUnits?: ScheduleUnit[]; throttling?: ThrottlingOptions; sourceType?: SourceType; @@ -76,11 +70,6 @@ export const defaultContext: IPolicyConfigContext = { setIsTLSEnabled: (_isTLSEnabled: React.SetStateAction) => { throw new Error('setIsTLSEnabled was not initialized, set it when you invoke the context'); }, - setIsZipUrlTLSEnabled: (_isZipUrlTLSEnabled: React.SetStateAction) => { - throw new Error( - 'setIsZipUrlTLSEnabled was not initialized, set it when you invoke the context' - ); - }, setNamespace: (_namespace: React.SetStateAction) => { throw new Error('setNamespace was not initialized, set it when you invoke the context'); }, @@ -88,11 +77,9 @@ export const defaultContext: IPolicyConfigContext = { defaultMonitorType: initialMonitorTypeValue, // immutable, runsOnService: false, defaultIsTLSEnabled: false, - defaultIsZipUrlTLSEnabled: false, defaultName: '', defaultLocations: [], isEditable: false, - isZipUrlSourceEnabled: true, allowedScheduleUnits: [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS], defaultNamespace: DEFAULT_NAMESPACE_STRING, throttling: DEFAULT_THROTTLING, @@ -106,13 +93,11 @@ export function PolicyConfigContextProvider({ throttling = DEFAULT_THROTTLING, defaultMonitorType = initialMonitorTypeValue, defaultIsTLSEnabled = false, - defaultIsZipUrlTLSEnabled = false, defaultName = '', defaultLocations = [], defaultNamespace = DEFAULT_NAMESPACE_STRING, isEditable = false, runsOnService = false, - isZipUrlSourceEnabled = true, allowedScheduleUnits = [ScheduleUnit.MINUTES, ScheduleUnit.SECONDS], sourceType, }: IPolicyConfigContextProvider) { @@ -120,7 +105,6 @@ export function PolicyConfigContextProvider({ const [name, setName] = useState(defaultName); const [locations, setLocations] = useState(defaultLocations); const [isTLSEnabled, setIsTLSEnabled] = useState(defaultIsTLSEnabled); - const [isZipUrlTLSEnabled, setIsZipUrlTLSEnabled] = useState(defaultIsZipUrlTLSEnabled); const [namespace, setNamespace] = useState(defaultNamespace); const isAddMonitorRoute = useRouteMatch(MONITOR_ADD_ROUTE); @@ -138,11 +122,8 @@ export function PolicyConfigContextProvider({ defaultMonitorType, runsOnService, isTLSEnabled, - isZipUrlTLSEnabled, setIsTLSEnabled, - setIsZipUrlTLSEnabled, defaultIsTLSEnabled, - defaultIsZipUrlTLSEnabled, isEditable, defaultName, name, @@ -150,7 +131,6 @@ export function PolicyConfigContextProvider({ defaultLocations, locations, setLocations, - isZipUrlSourceEnabled, allowedScheduleUnits, namespace, setNamespace, @@ -162,10 +142,7 @@ export function PolicyConfigContextProvider({ defaultMonitorType, runsOnService, isTLSEnabled, - isZipUrlSourceEnabled, - isZipUrlTLSEnabled, defaultIsTLSEnabled, - defaultIsZipUrlTLSEnabled, isEditable, name, defaultName, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx index 00f6ca347bf0a..6531024bea28f 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/custom_fields.test.tsx @@ -19,7 +19,7 @@ import { } from './contexts'; import { CustomFields } from './custom_fields'; import { ConfigKey, DataStream, ScheduleUnit } from './types'; -import { validate as centralValidation } from './validation'; +import { validate as centralValidation } from '../monitor_management/validation'; import { defaultConfig } from './synthetics_policy_create_extension'; // ensures that fields appropriately match to their label @@ -201,7 +201,7 @@ describe('', () => { }); it('handles switching monitor type', () => { - const { getByText, queryByText, getByLabelText, queryByLabelText, getAllByLabelText } = render( + const { getByText, queryByText, getByLabelText, queryByLabelText } = render( ); const monitorType = getByLabelText('Monitor Type') as HTMLInputElement; @@ -251,20 +251,10 @@ describe('', () => { screen.getByText('Runs Synthetic test scripts that are defined inline.') ).toBeInTheDocument(); - const zip = screen.getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - - getAllByLabelText('Zip URL').forEach((node: any) => { - expect(node).toBeInTheDocument(); - }); expect( getByText(/To create a "Browser" monitor, please ensure you are using the/) ).toBeInTheDocument(); - // expect tls options to be available for browser - expect(queryByLabelText('Proxy Zip URL')).toBeInTheDocument(); - expect(queryByText(/Enable TLS configuration for Zip URL/)).toBeInTheDocument(); - // ensure at least one browser advanced option is present advancedOptionsButton = getByText('Advanced Browser options'); fireEvent.click(advancedOptionsButton); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/normalizers.ts deleted file mode 100644 index 60aa607aebe61..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/helpers/normalizers.ts +++ /dev/null @@ -1,42 +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 { DataStream } from '../types'; - -import { httpNormalizers, HTTPNormalizerMap } from '../http/normalizers'; -import { tcpNormalizers, TCPNormalizerMap } from '../tcp/normalizers'; -import { icmpNormalizers, ICMPNormalizerMap } from '../icmp/normalizers'; -import { browserNormalizers, BrowserNormalizerMap } from '../browser/normalizers'; -import { commonNormalizers, CommonNormalizerMap } from '../common/normalizers'; - -type Normalizers = HTTPNormalizerMap & - ICMPNormalizerMap & - TCPNormalizerMap & - BrowserNormalizerMap & - CommonNormalizerMap; - -interface NormalizerMap { - [DataStream.HTTP]: HTTPNormalizerMap; - [DataStream.ICMP]: ICMPNormalizerMap; - [DataStream.TCP]: TCPNormalizerMap; - [DataStream.BROWSER]: BrowserNormalizerMap; -} - -export const normalizersMap: NormalizerMap = { - [DataStream.HTTP]: httpNormalizers, - [DataStream.ICMP]: icmpNormalizers, - [DataStream.TCP]: tcpNormalizers, - [DataStream.BROWSER]: browserNormalizers, -}; - -export const normalizers: Normalizers = { - ...httpNormalizers, - ...icmpNormalizers, - ...tcpNormalizers, - ...browserNormalizers, - ...commonNormalizers, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts index 9f43cbb238a79..e0c7eb860f214 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_policy.ts @@ -33,7 +33,6 @@ export const defaultConfig: PolicyConfig = DEFAULT_FIELDS; export const usePolicy = (fleetPolicyName: string = '') => { const { isTLSEnabled, - isZipUrlTLSEnabled, name: monitorName, // the monitor name can come from two different places, either from fleet or from uptime locations, namespace, @@ -50,9 +49,8 @@ export const usePolicy = (fleetPolicyName: string = '') => { const metadata = useMemo( () => ({ is_tls_enabled: isTLSEnabled, - is_zip_url_tls_enabled: isZipUrlTLSEnabled, }), - [isTLSEnabled, isZipUrlTLSEnabled] + [isTLSEnabled] ); /* TODO add locations to policy config for synthetics service */ diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.test.tsx deleted file mode 100644 index f285c70ea57e7..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.test.tsx +++ /dev/null @@ -1,680 +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 { renderHook } from '@testing-library/react-hooks'; -import { useUpdatePolicy } from './use_update_policy'; -import { NewPackagePolicy } from '@kbn/fleet-plugin/public'; -import { validate } from '../validation'; -import { - ConfigKey, - MonitorFields, - DataStream, - TLSVersion, - CommonFields, - ScheduleUnit, - ICMPFields, - TCPFields, - TLSFields, - HTTPFields, - BrowserFields, -} from '../types'; -import { defaultConfig } from '../synthetics_policy_create_extension'; - -describe('useUpdatePolicy', () => { - const newPolicy: NewPackagePolicy = { - name: '', - description: '', - namespace: 'default', - policy_id: 'ae774160-8e49-11eb-aba5-99269d21ba6e', - enabled: true, - inputs: [ - { - type: 'synthetics/http', - enabled: true, - streams: [ - { - enabled: true, - data_stream: { - type: 'synthetics', - dataset: 'http', - }, - vars: { - type: { - value: 'http', - type: 'text', - }, - name: { - value: '', - type: 'text', - }, - schedule: { - value: '"@every 3m"', - type: 'text', - }, - urls: { - value: '', - type: 'text', - }, - 'service.name': { - value: '', - type: 'text', - }, - timeout: { - value: '16s', - type: 'text', - }, - max_redirects: { - value: 0, - type: 'integer', - }, - proxy_url: { - value: '', - type: 'text', - }, - tags: { - value: '[]', - type: 'yaml', - }, - 'response.include_headers': { - value: true, - type: 'bool', - }, - 'response.include_body': { - value: 'on_error', - type: 'text', - }, - 'check.request.method': { - value: 'GET', - type: 'text', - }, - 'check.request.headers': { - value: '{}', - type: 'yaml', - }, - 'check.request.body': { - value: '""', - type: 'yaml', - }, - 'check.response.status': { - value: '[]', - type: 'yaml', - }, - 'check.response.headers': { - value: '{}', - type: 'yaml', - }, - 'check.response.body.positive': { - value: null, - type: 'yaml', - }, - 'check.response.body.negative': { - value: null, - type: 'yaml', - }, - 'ssl.certificate_authorities': { - value: '', - type: 'yaml', - }, - 'ssl.certificate': { - value: '', - type: 'yaml', - }, - 'ssl.key': { - value: '', - type: 'yaml', - }, - 'ssl.key_passphrase': { - type: 'text', - }, - 'ssl.verification_mode': { - value: 'full', - type: 'text', - }, - 'ssl.supported_protocols': { - value: '', - type: 'yaml', - }, - }, - }, - ], - }, - { - type: 'synthetics/tcp', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'tcp', - }, - vars: { - type: { - value: 'tcp', - type: 'text', - }, - name: { - type: 'text', - }, - schedule: { - value: '10s', - type: 'text', - }, - hosts: { - type: 'text', - }, - 'service.name': { - type: 'text', - }, - timeout: { - type: 'integer', - }, - max_redirects: { - type: 'integer', - }, - proxy_url: { - type: 'text', - }, - proxy_use_local_resolver: { - value: false, - type: 'bool', - }, - tags: { - type: 'yaml', - }, - 'check.send': { - type: 'text', - }, - 'check.receive': { - type: 'yaml', - }, - 'ssl.certificate_authorities': { - type: 'yaml', - }, - 'ssl.certificate': { - type: 'yaml', - }, - 'ssl.key': { - type: 'yaml', - }, - 'ssl.key_passphrase': { - type: 'text', - }, - 'ssl.verification_mode': { - type: 'text', - }, - }, - }, - ], - }, - { - type: 'synthetics/icmp', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'icmp', - }, - vars: { - type: { - value: 'icmp', - type: 'text', - }, - name: { - type: 'text', - }, - schedule: { - value: '10s', - type: 'text', - }, - wait: { - value: '1s', - type: 'text', - }, - hosts: { - type: 'text', - }, - 'service.name': { - type: 'text', - }, - timeout: { - type: 'integer', - }, - max_redirects: { - type: 'integer', - }, - tags: { - type: 'yaml', - }, - }, - }, - ], - }, - { - type: 'synthetics/browser', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'browser', - }, - vars: { - type: { - value: 'browser', - type: 'text', - }, - name: { - value: 'Sample name', - type: 'text', - }, - schedule: { - value: '10s', - type: 'text', - }, - 'source.zip_url.url': { - type: 'text', - }, - 'source.zip_url.username': { - type: 'text', - }, - 'source.zip_url.password': { - type: 'password', - }, - 'source.zip_url.folder': { - type: 'text', - }, - 'source.inline.script': { - type: 'yaml', - }, - 'service.name': { - type: 'text', - }, - screenshots: { - type: 'text', - }, - synthetics_args: { - type: 'yaml', - }, - timeout: { - type: 'text', - }, - tags: { - type: 'yaml', - }, - 'throttling.download_speed': { - type: 'text', - value: '""', - }, - 'throttling.upload_speed': { - type: 'text', - value: '""', - }, - 'throttling.latency': { - type: 'text', - value: '""', - }, - 'throttling.config': { - type: 'text', - value: '""', - }, - }, - }, - ], - }, - ], - package: { - name: 'synthetics', - title: 'Elastic Synthetics', - version: '0.66.0', - }, - }; - - const defaultCommonFields: Partial = { - [ConfigKey.APM_SERVICE_NAME]: 'APM Service name', - [ConfigKey.TAGS]: ['some', 'tags'], - [ConfigKey.SCHEDULE]: { - number: '5', - unit: ScheduleUnit.MINUTES, - }, - [ConfigKey.TIMEOUT]: '17', - }; - - const defaultTLSFields: Partial = { - [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: 'ca', - [ConfigKey.TLS_CERTIFICATE]: 'cert', - [ConfigKey.TLS_KEY]: 'key', - [ConfigKey.TLS_KEY_PASSPHRASE]: 'password', - }; - - it('handles http data stream', async () => { - const onChange = jest.fn(); - const initialProps = { - defaultConfig: defaultConfig[DataStream.HTTP], - config: defaultConfig[DataStream.HTTP], - newPolicy, - onChange, - validate, - monitorType: DataStream.HTTP, - }; - const { result, rerender, waitFor } = renderHook((props) => useUpdatePolicy(props), { - initialProps, - }); - - expect(result.current.config).toMatchObject({ ...defaultConfig[DataStream.HTTP] }); - - const config: HTTPFields = { - ...defaultConfig[DataStream.HTTP], - ...defaultCommonFields, - ...defaultTLSFields, - [ConfigKey.URLS]: 'url', - [ConfigKey.PROXY_URL]: 'proxyUrl', - }; - - // expect only http to be enabled - expect(result.current.updatedPolicy.inputs[0].enabled).toBe(true); - expect(result.current.updatedPolicy.inputs[1].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[2].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[3].enabled).toBe(false); - - rerender({ - ...initialProps, - config, - }); - - await waitFor(() => { - const vars = result.current.updatedPolicy.inputs[0]?.streams[0]?.vars; - - expect(vars?.[ConfigKey.MONITOR_TYPE].value).toEqual(config[ConfigKey.MONITOR_TYPE]); - expect(vars?.[ConfigKey.URLS].value).toEqual(config[ConfigKey.URLS]); - expect(vars?.[ConfigKey.SCHEDULE].value).toEqual( - JSON.stringify( - `@every ${config[ConfigKey.SCHEDULE].number}${config[ConfigKey.SCHEDULE].unit}` - ) - ); - expect(vars?.[ConfigKey.PROXY_URL].value).toEqual(config[ConfigKey.PROXY_URL]); - expect(vars?.[ConfigKey.APM_SERVICE_NAME].value).toEqual(config[ConfigKey.APM_SERVICE_NAME]); - expect(vars?.[ConfigKey.TIMEOUT].value).toEqual(`${config[ConfigKey.TIMEOUT]}s`); - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_POSITIVE].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_STATUS_CHECK].value).toEqual(null); - expect(vars?.[ConfigKey.REQUEST_HEADERS_CHECK].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_HEADERS_CHECK].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_BODY_INDEX].value).toEqual( - config[ConfigKey.RESPONSE_BODY_INDEX] - ); - expect(vars?.[ConfigKey.RESPONSE_HEADERS_INDEX].value).toEqual( - config[ConfigKey.RESPONSE_HEADERS_INDEX] - ); - }); - }); - - it('stringifies array values and returns null for empty array values', async () => { - const onChange = jest.fn(); - const initialProps = { - defaultConfig: defaultConfig[DataStream.HTTP], - config: defaultConfig[DataStream.HTTP], - newPolicy, - onChange, - validate, - monitorType: DataStream.HTTP, - }; - const { rerender, result, waitFor } = renderHook((props) => useUpdatePolicy(props), { - initialProps, - }); - - rerender({ - ...initialProps, - config: { - ...defaultConfig[DataStream.HTTP], - [ConfigKey.METADATA]: { - is_tls_enabled: true, - }, - [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: ['test'], - [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: ['test'], - [ConfigKey.RESPONSE_STATUS_CHECK]: ['test'], - [ConfigKey.TAGS]: ['test'], - [ConfigKey.TLS_VERSION]: [TLSVersion.ONE_ONE], - }, - }); - - await waitFor(() => { - // expect only http to be enabled - expect(result.current.updatedPolicy.inputs[0].enabled).toBe(true); - expect(result.current.updatedPolicy.inputs[1].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[2].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[3].enabled).toBe(false); - - const vars = result.current.updatedPolicy.inputs[0]?.streams[0]?.vars; - - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_POSITIVE].value).toEqual('["test"]'); - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE].value).toEqual('["test"]'); - expect(vars?.[ConfigKey.RESPONSE_STATUS_CHECK].value).toEqual('["test"]'); - expect(vars?.[ConfigKey.TAGS].value).toEqual('["test"]'); - expect(vars?.[ConfigKey.TLS_VERSION].value).toEqual('["TLSv1.1"]'); - }); - - rerender({ - ...initialProps, - config: { - ...defaultConfig[DataStream.HTTP], - [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: [], - [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: [], - [ConfigKey.RESPONSE_STATUS_CHECK]: [], - [ConfigKey.TAGS]: [], - [ConfigKey.TLS_VERSION]: [], - }, - }); - - await waitFor(() => { - const vars = result.current.updatedPolicy.inputs[0]?.streams[0]?.vars; - - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_POSITIVE].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE].value).toEqual(null); - expect(vars?.[ConfigKey.RESPONSE_STATUS_CHECK].value).toEqual(null); - expect(vars?.[ConfigKey.TAGS].value).toEqual(null); - expect(vars?.[ConfigKey.TLS_VERSION].value).toEqual(null); - }); - }); - - it('handles tcp data stream', async () => { - const onChange = jest.fn(); - const initialProps = { - defaultConfig: defaultConfig[DataStream.TCP], - config: defaultConfig[DataStream.TCP], - newPolicy, - onChange, - validate, - monitorType: DataStream.TCP, - }; - const { result, rerender, waitFor } = renderHook((props) => useUpdatePolicy(props), { - initialProps, - }); - - // expect only tcp to be enabled - expect(result.current.updatedPolicy.inputs[0].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[1].enabled).toBe(true); - expect(result.current.updatedPolicy.inputs[2].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[3].enabled).toBe(false); - - const config: TCPFields = { - ...defaultConfig[DataStream.TCP], - ...defaultCommonFields, - ...defaultTLSFields, - [ConfigKey.HOSTS]: 'sampleHost', - [ConfigKey.PROXY_URL]: 'proxyUrl', - [ConfigKey.PROXY_USE_LOCAL_RESOLVER]: true, - [ConfigKey.RESPONSE_RECEIVE_CHECK]: 'response', - [ConfigKey.REQUEST_SEND_CHECK]: 'request', - }; - - rerender({ - ...initialProps, - config, - }); - - await waitFor(() => { - const vars = result.current.updatedPolicy.inputs[1]?.streams[0]?.vars; - - expect(onChange).toBeCalledWith({ - isValid: false, - updatedPolicy: result.current.updatedPolicy, - }); - - expect(vars?.[ConfigKey.MONITOR_TYPE].value).toEqual(config[ConfigKey.MONITOR_TYPE]); - expect(vars?.[ConfigKey.HOSTS].value).toEqual(config[ConfigKey.HOSTS]); - expect(vars?.[ConfigKey.SCHEDULE].value).toEqual( - JSON.stringify( - `@every ${config[ConfigKey.SCHEDULE].number}${config[ConfigKey.SCHEDULE].unit}` - ) - ); - expect(vars?.[ConfigKey.PROXY_URL].value).toEqual(config[ConfigKey.PROXY_URL]); - expect(vars?.[ConfigKey.APM_SERVICE_NAME].value).toEqual(config[ConfigKey.APM_SERVICE_NAME]); - expect(vars?.[ConfigKey.TIMEOUT].value).toEqual(`${config[ConfigKey.TIMEOUT]}s`); - expect(vars?.[ConfigKey.PROXY_USE_LOCAL_RESOLVER].value).toEqual( - config[ConfigKey.PROXY_USE_LOCAL_RESOLVER] - ); - expect(vars?.[ConfigKey.RESPONSE_RECEIVE_CHECK].value).toEqual( - config[ConfigKey.RESPONSE_RECEIVE_CHECK] - ); - expect(vars?.[ConfigKey.REQUEST_SEND_CHECK].value).toEqual( - config[ConfigKey.REQUEST_SEND_CHECK] - ); - }); - }); - - it('handles icmp data stream', async () => { - const onChange = jest.fn(); - const initialProps = { - defaultConfig: defaultConfig[DataStream.ICMP], - config: defaultConfig[DataStream.ICMP], - newPolicy, - onChange, - validate, - monitorType: DataStream.ICMP, - }; - const { rerender, result, waitFor } = renderHook((props) => useUpdatePolicy(props), { - initialProps, - }); - const config: ICMPFields = { - ...defaultConfig[DataStream.ICMP], - ...defaultCommonFields, - [ConfigKey.WAIT]: '2', - [ConfigKey.HOSTS]: 'sampleHost', - }; - - // expect only icmp to be enabled - expect(result.current.updatedPolicy.inputs[0].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[1].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[2].enabled).toBe(true); - expect(result.current.updatedPolicy.inputs[3].enabled).toBe(false); - - // only call onChange when the policy is changed - rerender({ - ...initialProps, - config, - }); - - await waitFor(() => { - const vars = result.current.updatedPolicy.inputs[2]?.streams[0]?.vars; - - expect(vars?.[ConfigKey.MONITOR_TYPE].value).toEqual(config[ConfigKey.MONITOR_TYPE]); - expect(vars?.[ConfigKey.HOSTS].value).toEqual(config[ConfigKey.HOSTS]); - expect(vars?.[ConfigKey.SCHEDULE].value).toEqual( - JSON.stringify( - `@every ${config[ConfigKey.SCHEDULE].number}${config[ConfigKey.SCHEDULE].unit}` - ) - ); - expect(vars?.[ConfigKey.APM_SERVICE_NAME].value).toEqual(config[ConfigKey.APM_SERVICE_NAME]); - expect(vars?.[ConfigKey.TIMEOUT].value).toEqual(`${config[ConfigKey.TIMEOUT]}s`); - expect(vars?.[ConfigKey.WAIT].value).toEqual(`${config[ConfigKey.WAIT]}s`); - - expect(onChange).toBeCalledWith({ - isValid: false, - updatedPolicy: result.current.updatedPolicy, - }); - }); - }); - - it('handles browser data stream', async () => { - const onChange = jest.fn(); - const initialProps = { - defaultConfig: defaultConfig[DataStream.BROWSER] as Partial, - config: defaultConfig[DataStream.BROWSER] as Partial, - newPolicy, - onChange, - validate, - monitorType: DataStream.BROWSER, - }; - - const { result, rerender, waitFor } = renderHook((props) => useUpdatePolicy(props), { - initialProps, - }); - - // expect only browser to be enabled - expect(result.current.updatedPolicy.inputs[0].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[1].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[2].enabled).toBe(false); - expect(result.current.updatedPolicy.inputs[3].enabled).toBe(true); - - const config: BrowserFields = { - ...defaultConfig[DataStream.BROWSER], - ...defaultCommonFields, - [ConfigKey.SOURCE_INLINE]: 'inlineScript', - [ConfigKey.SOURCE_ZIP_URL]: 'zipFolder', - [ConfigKey.SOURCE_ZIP_FOLDER]: 'zipFolder', - [ConfigKey.SOURCE_ZIP_USERNAME]: 'username', - [ConfigKey.SOURCE_ZIP_PASSWORD]: 'password', - [ConfigKey.SCREENSHOTS]: 'off', - [ConfigKey.SYNTHETICS_ARGS]: ['args'], - [ConfigKey.DOWNLOAD_SPEED]: '13', - [ConfigKey.UPLOAD_SPEED]: '3', - [ConfigKey.LATENCY]: '7', - }; - - rerender({ - ...initialProps, - config: config as Partial, - }); - - await waitFor(() => { - const vars = result.current.updatedPolicy.inputs[3]?.streams[0]?.vars; - - expect(vars?.[ConfigKey.SOURCE_ZIP_FOLDER].value).toEqual( - config[ConfigKey.SOURCE_ZIP_FOLDER] - ); - expect(vars?.[ConfigKey.SOURCE_ZIP_PASSWORD].value).toEqual( - config[ConfigKey.SOURCE_ZIP_PASSWORD] - ); - expect(vars?.[ConfigKey.SOURCE_ZIP_URL].value).toEqual(config[ConfigKey.SOURCE_ZIP_URL]); - expect(vars?.[ConfigKey.SOURCE_INLINE].value).toEqual( - JSON.stringify(config[ConfigKey.SOURCE_INLINE]) - ); - expect(vars?.[ConfigKey.SOURCE_ZIP_PASSWORD].value).toEqual( - config[ConfigKey.SOURCE_ZIP_PASSWORD] - ); - expect(vars?.[ConfigKey.SCREENSHOTS].value).toEqual(config[ConfigKey.SCREENSHOTS]); - expect(vars?.[ConfigKey.SYNTHETICS_ARGS].value).toEqual( - JSON.stringify(config[ConfigKey.SYNTHETICS_ARGS]) - ); - expect(vars?.[ConfigKey.APM_SERVICE_NAME].value).toEqual(config[ConfigKey.APM_SERVICE_NAME]); - expect(vars?.[ConfigKey.TIMEOUT].value).toEqual(`${config[ConfigKey.TIMEOUT]}s`); - expect(vars?.[ConfigKey.THROTTLING_CONFIG].value).toEqual( - `${config[ConfigKey.DOWNLOAD_SPEED]}d/${config[ConfigKey.UPLOAD_SPEED]}u/${ - config[ConfigKey.LATENCY] - }l` - ); - - expect(onChange).toBeCalledWith({ - isValid: false, - updatedPolicy: result.current.updatedPolicy, - }); - }); - }); -}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.ts deleted file mode 100644 index 199b811790169..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/hooks/use_update_policy.ts +++ /dev/null @@ -1,67 +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 { useEffect, useRef, useState } from 'react'; -import { NewPackagePolicy } from '@kbn/fleet-plugin/public'; -import { formatSyntheticsPolicy } from '../../../../../common/formatters/format_synthetics_policy'; -import { ConfigKey, DataStream, Validation, MonitorFields } from '../types'; - -interface Props { - monitorType: DataStream; - defaultConfig: Partial; - config: Partial; - newPolicy: NewPackagePolicy; - onChange: (opts: { - /** is current form state is valid */ - isValid: boolean; - /** The updated Integration Policy to be merged back and included in the API call */ - updatedPolicy: NewPackagePolicy; - }) => void; - validate: Record; -} - -export const useUpdatePolicy = ({ - monitorType, - defaultConfig, - config, - newPolicy, - onChange, - validate, -}: Props) => { - const [updatedPolicy, setUpdatedPolicy] = useState(newPolicy); - // Update the integration policy with our custom fields - const currentConfig = useRef>(defaultConfig); - - useEffect(() => { - const configKeys = Object.keys(config) as ConfigKey[]; - const validationKeys = Object.keys(validate[monitorType]) as ConfigKey[]; - const configDidUpdate = configKeys.some((key) => config[key] !== currentConfig.current[key]); - const isValid = - !!newPolicy.name && !validationKeys.find((key) => validate[monitorType]?.[key]?.(config)); - - const { formattedPolicy, dataStream, currentInput } = formatSyntheticsPolicy( - newPolicy, - monitorType, - config, - true - ); - - // prevent an infinite loop of updating the policy - if (currentInput && dataStream && configDidUpdate) { - currentConfig.current = config; - setUpdatedPolicy(formattedPolicy); - onChange({ - isValid, - updatedPolicy: formattedPolicy, - }); - } - }, [config, currentConfig, newPolicy, onChange, validate, monitorType]); - - return { - config, - updatedPolicy, - }; -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx index c6d2d90467595..18937d5dc512f 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/advanced_fields.test.tsx @@ -19,7 +19,7 @@ import { HTTPMethod, Validation, } from '../types'; -import { validate as centralValidation } from '../validation'; +import { validate as centralValidation } from '../../monitor_management/validation'; import { HTTPAdvancedFields } from './advanced_fields'; jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/normalizers.ts deleted file mode 100644 index a783639f1ab18..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/http/normalizers.ts +++ /dev/null @@ -1,88 +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 { parseJsonIfString } from '../helpers/parsers'; -import { HTTPFields, ConfigKey, ContentType, contentTypesToMode } from '../types'; -import { - Normalizer, - commonNormalizers, - getNormalizer, - getJsonToJavascriptNormalizer, -} from '../common/normalizers'; -import { tlsNormalizers } from '../tls/normalizers'; -import { defaultHTTPSimpleFields, defaultHTTPAdvancedFields } from '../contexts'; - -export type HTTPNormalizerMap = Record; - -const defaultHTTPValues = { - ...defaultHTTPSimpleFields, - ...defaultHTTPAdvancedFields, -}; - -export const getHTTPNormalizer = (key: ConfigKey) => { - return getNormalizer(key, defaultHTTPValues); -}; - -export const getHTTPJsonToJavascriptNormalizer = (key: ConfigKey) => { - return getJsonToJavascriptNormalizer(key, defaultHTTPValues); -}; - -export const httpNormalizers: HTTPNormalizerMap = { - [ConfigKey.METADATA]: getHTTPJsonToJavascriptNormalizer(ConfigKey.METADATA), - [ConfigKey.URLS]: getHTTPNormalizer(ConfigKey.URLS), - [ConfigKey.PORT]: getHTTPNormalizer(ConfigKey.PORT), - [ConfigKey.MAX_REDIRECTS]: getHTTPNormalizer(ConfigKey.MAX_REDIRECTS), - [ConfigKey.USERNAME]: getHTTPNormalizer(ConfigKey.USERNAME), - [ConfigKey.PASSWORD]: getHTTPNormalizer(ConfigKey.PASSWORD), - [ConfigKey.PROXY_URL]: getHTTPNormalizer(ConfigKey.PROXY_URL), - [ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE]: getHTTPJsonToJavascriptNormalizer( - ConfigKey.RESPONSE_BODY_CHECK_NEGATIVE - ), - [ConfigKey.RESPONSE_BODY_CHECK_POSITIVE]: getHTTPJsonToJavascriptNormalizer( - ConfigKey.RESPONSE_BODY_CHECK_POSITIVE - ), - [ConfigKey.RESPONSE_BODY_INDEX]: getHTTPNormalizer(ConfigKey.RESPONSE_BODY_INDEX), - [ConfigKey.RESPONSE_HEADERS_CHECK]: getHTTPJsonToJavascriptNormalizer( - ConfigKey.RESPONSE_HEADERS_CHECK - ), - [ConfigKey.RESPONSE_HEADERS_INDEX]: getHTTPNormalizer(ConfigKey.RESPONSE_HEADERS_INDEX), - [ConfigKey.RESPONSE_STATUS_CHECK]: getHTTPJsonToJavascriptNormalizer( - ConfigKey.RESPONSE_STATUS_CHECK - ), - [ConfigKey.REQUEST_BODY_CHECK]: (fields) => { - const requestBody = fields?.[ConfigKey.REQUEST_BODY_CHECK]?.value; - const requestHeaders = fields?.[ConfigKey.REQUEST_HEADERS_CHECK]?.value; - if (requestBody) { - const headers = requestHeaders - ? parseJsonIfString(fields?.[ConfigKey.REQUEST_HEADERS_CHECK]?.value) - : defaultHTTPAdvancedFields[ConfigKey.REQUEST_HEADERS_CHECK]; - const requestBodyValue = - requestBody !== null && requestBody !== undefined - ? JSON.parse(requestBody) - : defaultHTTPAdvancedFields[ConfigKey.REQUEST_BODY_CHECK]?.value; - let requestBodyType = defaultHTTPAdvancedFields[ConfigKey.REQUEST_BODY_CHECK]?.type; - Object.keys(headers || []).some((headerKey) => { - if (headerKey === 'Content-Type' && contentTypesToMode[headers[headerKey] as ContentType]) { - requestBodyType = contentTypesToMode[headers[headerKey] as ContentType]; - return true; - } - }); - return { - value: requestBodyValue, - type: requestBodyType, - }; - } else { - return defaultHTTPAdvancedFields[ConfigKey.REQUEST_BODY_CHECK]; - } - }, - [ConfigKey.REQUEST_HEADERS_CHECK]: getHTTPJsonToJavascriptNormalizer( - ConfigKey.REQUEST_HEADERS_CHECK - ), - [ConfigKey.REQUEST_METHOD_CHECK]: getHTTPNormalizer(ConfigKey.REQUEST_METHOD_CHECK), - ...commonNormalizers, - ...tlsNormalizers, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/normalizers.ts deleted file mode 100644 index e954d1f4f66e5..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/icmp/normalizers.ts +++ /dev/null @@ -1,31 +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 { ICMPFields, ConfigKey } from '../types'; -import { - Normalizer, - commonNormalizers, - getNormalizer, - getCronNormalizer, -} from '../common/normalizers'; -import { defaultICMPSimpleFields } from '../contexts'; - -export type ICMPNormalizerMap = Record; - -export const getICMPNormalizer = (key: ConfigKey) => { - return getNormalizer(key, defaultICMPSimpleFields); -}; - -export const getICMPCronToSecondsNormalizer = (key: ConfigKey) => { - return getCronNormalizer(key, defaultICMPSimpleFields); -}; - -export const icmpNormalizers: ICMPNormalizerMap = { - [ConfigKey.HOSTS]: getICMPNormalizer(ConfigKey.HOSTS), - [ConfigKey.WAIT]: getICMPCronToSecondsNormalizer(ConfigKey.WAIT), - ...commonNormalizers, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_edit_policy_extension_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_edit_policy_extension_wrapper.test.tsx new file mode 100644 index 0000000000000..8a9b8c92e3b68 --- /dev/null +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_edit_policy_extension_wrapper.test.tsx @@ -0,0 +1,361 @@ +/* + * 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 'jest-canvas-mock'; + +import React from 'react'; +import { render } from '../../lib/helper/rtl_helpers'; +import { NewPackagePolicy } from '@kbn/fleet-plugin/public'; +import { SyntheticsPolicyEditExtensionWrapper } from './synthetics_policy_edit_extension_wrapper'; + +// ensures that fields appropriately match to their label +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + ...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'), + htmlIdGenerator: () => () => `id-${Math.random()}`, +})); + +// ensures that fields appropriately match to their label +jest.mock('@elastic/eui/lib/services/accessibility', () => ({ + ...jest.requireActual('@elastic/eui/lib/services/accessibility'), + useGeneratedHtmlId: () => `id-${Math.random()}`, +})); + +jest.mock('@kbn/kibana-react-plugin/public', () => { + const original = jest.requireActual('@kbn/kibana-react-plugin/public'); + return { + ...original, + // Mocking CodeEditor, which uses React Monaco under the hood + CodeEditor: (props: any) => ( + { + props.onChange(e.jsonContent); + }} + /> + ), + }; +}); + +const defaultNewPolicy: NewPackagePolicy = { + name: 'samplePolicyName', + description: '', + namespace: 'default', + policy_id: 'ae774160-8e49-11eb-aba5-99269d21ba6e', + enabled: true, + inputs: [ + { + type: 'synthetics/http', + enabled: true, + streams: [ + { + enabled: true, + data_stream: { + type: 'synthetics', + dataset: 'http', + }, + vars: { + __ui: { + value: JSON.stringify({ is_tls_enabled: true }), + type: 'yaml', + }, + type: { + value: 'http', + type: 'text', + }, + name: { + value: 'Sample name', + type: 'text', + }, + schedule: { + value: '"@every 3m"', + type: 'text', + }, + urls: { + value: '', + type: 'text', + }, + 'service.name': { + value: '', + type: 'text', + }, + timeout: { + value: '16s', + type: 'text', + }, + max_redirects: { + value: 0, + type: 'integer', + }, + proxy_url: { + value: '', + type: 'text', + }, + tags: { + value: '[]', + type: 'yaml', + }, + 'response.include_headers': { + value: true, + type: 'bool', + }, + 'response.include_body': { + value: 'on_error', + type: 'text', + }, + 'check.request.method': { + value: 'GET', + type: 'text', + }, + 'check.request.headers': { + value: '{}', + type: 'yaml', + }, + 'check.request.body': { + value: '""', + type: 'yaml', + }, + 'check.response.status': { + value: '[]', + type: 'yaml', + }, + 'check.response.headers': { + value: '{}', + type: 'yaml', + }, + 'check.response.body.positive': { + value: '[]', + type: 'yaml', + }, + 'check.response.body.negative': { + value: '[]', + type: 'yaml', + }, + 'ssl.certificate_authorities': { + value: '', + type: 'yaml', + }, + 'ssl.certificate': { + value: '', + type: 'yaml', + }, + 'ssl.key': { + value: '', + type: 'yaml', + }, + 'ssl.key_passphrase': { + type: 'text', + }, + 'ssl.verification_mode': { + value: 'full', + type: 'text', + }, + }, + }, + ], + }, + { + type: 'synthetics/tcp', + enabled: false, + streams: [ + { + enabled: false, + data_stream: { + type: 'synthetics', + dataset: 'tcp', + }, + vars: { + type: { + value: 'tcp', + type: 'text', + }, + name: { + type: 'text', + }, + schedule: { + value: '"@every 5s"', + type: 'text', + }, + hosts: { + type: 'text', + }, + 'service.name': { + type: 'text', + }, + timeout: { + type: 'text', + }, + max_redirects: { + type: 'integer', + }, + proxy_url: { + type: 'text', + }, + proxy_use_local_resolver: { + value: false, + type: 'bool', + }, + tags: { + type: 'yaml', + }, + 'check.send': { + type: 'text', + }, + 'check.receive': { + value: '', + type: 'yaml', + }, + 'ssl.certificate_authorities': { + type: 'yaml', + }, + 'ssl.certificate': { + type: 'yaml', + }, + 'ssl.key': { + type: 'yaml', + }, + 'ssl.key_passphrase': { + type: 'text', + }, + 'ssl.verification_mode': { + type: 'text', + }, + }, + }, + ], + }, + { + type: 'synthetics/icmp', + enabled: false, + streams: [ + { + enabled: false, + data_stream: { + type: 'synthetics', + dataset: 'icmp', + }, + vars: { + type: { + value: 'icmp', + type: 'text', + }, + name: { + type: 'text', + }, + schedule: { + value: '"@every 5s"', + type: 'text', + }, + wait: { + value: '1s', + type: 'text', + }, + hosts: { + type: 'text', + }, + 'service.name': { + type: 'text', + }, + timeout: { + type: 'text', + }, + max_redirects: { + type: 'integer', + }, + tags: { + type: 'yaml', + }, + }, + }, + ], + }, + { + type: 'synthetics/browser', + enabled: false, + streams: [ + { + enabled: false, + data_stream: { + type: 'synthetics', + dataset: 'browser', + }, + vars: { + type: { + value: 'browser', + type: 'text', + }, + name: { + value: 'Sample name', + type: 'text', + }, + schedule: { + value: '"@every 5s"', + type: 'text', + }, + 'source.zip_url.url': { + type: 'text', + }, + 'source.zip_url.username': { + type: 'text', + }, + 'source.zip_url.password': { + type: 'password', + }, + 'source.zip_url.folder': { + type: 'text', + }, + 'source.inline.script': { + type: 'yaml', + }, + timeout: { + type: 'text', + }, + tags: { + type: 'yaml', + }, + }, + }, + ], + }, + ], + package: { + name: 'synthetics', + title: 'Elastic Synthetics', + version: '0.66.0', + }, +}; + +const defaultCurrentPolicy: any = { + ...defaultNewPolicy, + id: '', + revision: '', + updated_at: '', + updated_by: '', + created_at: '', + created_by: '', +}; + +describe('', () => { + const onChange = jest.fn(); + const WrappedComponent = ({ policy = defaultCurrentPolicy, newPolicy = defaultNewPolicy }) => { + return ( + + ); + }; + + it('shows deprecation notice', async () => { + const { getByText } = render(); + + expect( + getByText('Synthetic Monitoring is now available out of the box in Synthetics') + ).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx index d699fcb203ede..dbd83dac27d05 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension.tsx @@ -20,7 +20,7 @@ export const defaultConfig: PolicyConfig = DEFAULT_FIELDS; * for use in the Ingest app create / edit package policy */ export const SyntheticsPolicyCreateExtension = memo( - ({ newPolicy, onChange }) => { + ({ newPolicy }) => { useTrackPageview({ app: 'fleet', path: 'syntheticsCreate' }); useTrackPageview({ app: 'fleet', path: 'syntheticsCreate', delay: 15000 }); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx index 976c363ef6568..0f055fe1fea15 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_create_extension_wrapper.tsx @@ -8,7 +8,6 @@ import React, { memo } from 'react'; import { PackagePolicyCreateExtensionComponentProps } from '@kbn/fleet-plugin/public'; import { SyntheticsPolicyCreateExtension } from './synthetics_policy_create_extension'; -import { SyntheticsProviders } from './contexts'; /** * Exports Synthetics-specific package policy instructions @@ -16,10 +15,6 @@ import { SyntheticsProviders } from './contexts'; */ export const SyntheticsPolicyCreateExtensionWrapper = memo(({ newPolicy, onChange }) => { - return ( - - - - ); + return ; }); SyntheticsPolicyCreateExtensionWrapper.displayName = 'SyntheticsPolicyCreateExtensionWrapper'; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension.tsx deleted file mode 100644 index 771ac6ed8c88f..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension.tsx +++ /dev/null @@ -1,48 +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 React, { memo } from 'react'; -import { PackagePolicyEditExtensionComponentProps } from '@kbn/fleet-plugin/public'; -import { useTrackPageview } from '@kbn/observability-plugin/public'; -import { usePolicyConfigContext } from './contexts'; -import { MonitorFields, PolicyConfig } from './types'; -import { CustomFields } from './custom_fields'; -import { useUpdatePolicy } from './hooks/use_update_policy'; -import { usePolicy } from './hooks/use_policy'; -import { validate } from './validation'; - -interface SyntheticsPolicyEditExtensionProps { - newPolicy: PackagePolicyEditExtensionComponentProps['newPolicy']; - onChange: PackagePolicyEditExtensionComponentProps['onChange']; - defaultConfig: Partial; -} - -/** - * Exports Synthetics-specific package policy instructions - * for use in the Fleet app create / edit package policy - */ -export const SyntheticsPolicyEditExtension = memo( - ({ newPolicy, onChange, defaultConfig }) => { - useTrackPageview({ app: 'fleet', path: 'syntheticsEdit' }); - useTrackPageview({ app: 'fleet', path: 'syntheticsEdit', delay: 15000 }); - - const { monitorType } = usePolicyConfigContext(); - const policyConfig: PolicyConfig = usePolicy(newPolicy.name); - - useUpdatePolicy({ - defaultConfig, - config: policyConfig[monitorType] as Partial, - newPolicy, - onChange, - validate, - monitorType, - }); - - return ; - } -); -SyntheticsPolicyEditExtension.displayName = 'SyntheticsPolicyEditExtension'; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx deleted file mode 100644 index a1bc5f57f5911..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.test.tsx +++ /dev/null @@ -1,1178 +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 'jest-canvas-mock'; - -import React from 'react'; -import { fireEvent, waitFor } from '@testing-library/react'; -import { render } from '../../lib/helper/rtl_helpers'; -import { NewPackagePolicy } from '@kbn/fleet-plugin/public'; -import { SyntheticsPolicyEditExtensionWrapper } from './synthetics_policy_edit_extension_wrapper'; -import { ConfigKey, DataStream, ScheduleUnit } from './types'; -import { defaultConfig } from './synthetics_policy_create_extension'; - -// ensures that fields appropriately match to their label -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ - ...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'), - htmlIdGenerator: () => () => `id-${Math.random()}`, -})); - -// ensures that fields appropriately match to their label -jest.mock('@elastic/eui/lib/services/accessibility', () => ({ - ...jest.requireActual('@elastic/eui/lib/services/accessibility'), - useGeneratedHtmlId: () => `id-${Math.random()}`, -})); - -jest.mock('@kbn/kibana-react-plugin/public', () => { - const original = jest.requireActual('@kbn/kibana-react-plugin/public'); - return { - ...original, - // Mocking CodeEditor, which uses React Monaco under the hood - CodeEditor: (props: any) => ( - { - props.onChange(e.jsonContent); - }} - /> - ), - }; -}); - -const defaultNewPolicy: NewPackagePolicy = { - name: 'samplePolicyName', - description: '', - namespace: 'default', - policy_id: 'ae774160-8e49-11eb-aba5-99269d21ba6e', - enabled: true, - inputs: [ - { - type: 'synthetics/http', - enabled: true, - streams: [ - { - enabled: true, - data_stream: { - type: 'synthetics', - dataset: 'http', - }, - vars: { - __ui: { - value: JSON.stringify({ is_tls_enabled: true }), - type: 'yaml', - }, - type: { - value: 'http', - type: 'text', - }, - name: { - value: 'Sample name', - type: 'text', - }, - schedule: { - value: '"@every 3m"', - type: 'text', - }, - urls: { - value: '', - type: 'text', - }, - 'service.name': { - value: '', - type: 'text', - }, - timeout: { - value: '16s', - type: 'text', - }, - max_redirects: { - value: 0, - type: 'integer', - }, - proxy_url: { - value: '', - type: 'text', - }, - tags: { - value: '[]', - type: 'yaml', - }, - 'response.include_headers': { - value: true, - type: 'bool', - }, - 'response.include_body': { - value: 'on_error', - type: 'text', - }, - 'check.request.method': { - value: 'GET', - type: 'text', - }, - 'check.request.headers': { - value: '{}', - type: 'yaml', - }, - 'check.request.body': { - value: '""', - type: 'yaml', - }, - 'check.response.status': { - value: '[]', - type: 'yaml', - }, - 'check.response.headers': { - value: '{}', - type: 'yaml', - }, - 'check.response.body.positive': { - value: '[]', - type: 'yaml', - }, - 'check.response.body.negative': { - value: '[]', - type: 'yaml', - }, - 'ssl.certificate_authorities': { - value: '', - type: 'yaml', - }, - 'ssl.certificate': { - value: '', - type: 'yaml', - }, - 'ssl.key': { - value: '', - type: 'yaml', - }, - 'ssl.key_passphrase': { - type: 'text', - }, - 'ssl.verification_mode': { - value: 'full', - type: 'text', - }, - }, - }, - ], - }, - { - type: 'synthetics/tcp', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'tcp', - }, - vars: { - type: { - value: 'tcp', - type: 'text', - }, - name: { - type: 'text', - }, - schedule: { - value: '"@every 5s"', - type: 'text', - }, - hosts: { - type: 'text', - }, - 'service.name': { - type: 'text', - }, - timeout: { - type: 'text', - }, - max_redirects: { - type: 'integer', - }, - proxy_url: { - type: 'text', - }, - proxy_use_local_resolver: { - value: false, - type: 'bool', - }, - tags: { - type: 'yaml', - }, - 'check.send': { - type: 'text', - }, - 'check.receive': { - value: '', - type: 'yaml', - }, - 'ssl.certificate_authorities': { - type: 'yaml', - }, - 'ssl.certificate': { - type: 'yaml', - }, - 'ssl.key': { - type: 'yaml', - }, - 'ssl.key_passphrase': { - type: 'text', - }, - 'ssl.verification_mode': { - type: 'text', - }, - }, - }, - ], - }, - { - type: 'synthetics/icmp', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'icmp', - }, - vars: { - type: { - value: 'icmp', - type: 'text', - }, - name: { - type: 'text', - }, - schedule: { - value: '"@every 5s"', - type: 'text', - }, - wait: { - value: '1s', - type: 'text', - }, - hosts: { - type: 'text', - }, - 'service.name': { - type: 'text', - }, - timeout: { - type: 'text', - }, - max_redirects: { - type: 'integer', - }, - tags: { - type: 'yaml', - }, - }, - }, - ], - }, - { - type: 'synthetics/browser', - enabled: false, - streams: [ - { - enabled: false, - data_stream: { - type: 'synthetics', - dataset: 'browser', - }, - vars: { - type: { - value: 'browser', - type: 'text', - }, - name: { - value: 'Sample name', - type: 'text', - }, - schedule: { - value: '"@every 5s"', - type: 'text', - }, - 'source.zip_url.url': { - type: 'text', - }, - 'source.zip_url.username': { - type: 'text', - }, - 'source.zip_url.password': { - type: 'password', - }, - 'source.zip_url.folder': { - type: 'text', - }, - 'source.inline.script': { - type: 'yaml', - }, - timeout: { - type: 'text', - }, - tags: { - type: 'yaml', - }, - }, - }, - ], - }, - ], - package: { - name: 'synthetics', - title: 'Elastic Synthetics', - version: '0.66.0', - }, -}; - -const defaultCurrentPolicy: any = { - ...defaultNewPolicy, - id: '', - revision: '', - updated_at: '', - updated_by: '', - created_at: '', - created_by: '', -}; - -const defaultHTTPConfig = defaultConfig[DataStream.HTTP]; -const defaultICMPConfig = defaultConfig[DataStream.ICMP]; -const defaultTCPConfig = defaultConfig[DataStream.TCP]; -const defaultBrowserConfig = defaultConfig[DataStream.BROWSER]; - -describe('', () => { - const onChange = jest.fn(); - const WrappedComponent = ({ policy = defaultCurrentPolicy, newPolicy = defaultNewPolicy }) => { - return ( - - ); - }; - - beforeEach(() => { - onChange.mockClear(); - }); - - it('renders SyntheticsPolicyEditExtension', async () => { - const { getByText, getByLabelText, queryByLabelText } = render(); - const url = getByLabelText('URL') as HTMLInputElement; - const proxyUrl = getByLabelText('Proxy URL') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - const maxRedirects = getByLabelText('Max redirects') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - const verificationMode = getByLabelText('Verification mode') as HTMLInputElement; - const enableTLSConfig = getByLabelText('Enable TLS configuration') as HTMLInputElement; - expect(url).toBeInTheDocument(); - expect(url.value).toEqual(defaultHTTPConfig[ConfigKey.URLS]); - expect(proxyUrl).toBeInTheDocument(); - expect(proxyUrl.value).toEqual(defaultHTTPConfig[ConfigKey.PROXY_URL]); - expect(monitorIntervalNumber).toBeInTheDocument(); - expect(monitorIntervalNumber.value).toEqual(defaultHTTPConfig[ConfigKey.SCHEDULE].number); - expect(monitorIntervalUnit).toBeInTheDocument(); - expect(monitorIntervalUnit.value).toEqual(defaultHTTPConfig[ConfigKey.SCHEDULE].unit); - expect(apmServiceName).toBeInTheDocument(); - expect(apmServiceName.value).toEqual(defaultHTTPConfig[ConfigKey.APM_SERVICE_NAME]); - expect(maxRedirects).toBeInTheDocument(); - expect(maxRedirects.value).toEqual(`${defaultHTTPConfig[ConfigKey.MAX_REDIRECTS]}`); - expect(timeout).toBeInTheDocument(); - expect(timeout.value).toEqual(`${defaultHTTPConfig[ConfigKey.TIMEOUT]}`); - // expect TLS settings to be in the document when at least one tls key is populated - expect(enableTLSConfig.getAttribute('aria-checked')).toEqual('true'); - expect(verificationMode).toBeInTheDocument(); - expect(verificationMode.value).toEqual(`${defaultHTTPConfig[ConfigKey.TLS_VERIFICATION_MODE]}`); - - // ensure other monitor type options are not in the DOM - expect(queryByLabelText('Host')).not.toBeInTheDocument(); - expect(queryByLabelText('Wait in seconds')).not.toBeInTheDocument(); - - // ensure at least one http advanced option is present - const advancedOptionsButton = getByText('Advanced HTTP options'); - fireEvent.click(advancedOptionsButton); - await waitFor(() => { - expect(getByLabelText('Request method')).toBeInTheDocument(); - }); - }); - - it('does not allow user to edit monitor type', async () => { - const { queryByLabelText } = render(); - - expect(queryByLabelText('Monitor type')).not.toBeInTheDocument(); - }); - - it('handles updating fields', async () => { - const { getByLabelText } = render(); - const url = getByLabelText('URL') as HTMLInputElement; - const proxyUrl = getByLabelText('Proxy URL') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - const maxRedirects = getByLabelText('Max redirects') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - - fireEvent.change(url, { target: { value: 'http://elastic.co' } }); - fireEvent.change(proxyUrl, { target: { value: 'http://proxy.co' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '1' } }); - fireEvent.change(monitorIntervalUnit, { target: { value: ScheduleUnit.MINUTES } }); - fireEvent.change(apmServiceName, { target: { value: 'APM Service' } }); - fireEvent.change(maxRedirects, { target: { value: '2' } }); - fireEvent.change(timeout, { target: { value: '3' } }); - - expect(url.value).toEqual('http://elastic.co'); - expect(proxyUrl.value).toEqual('http://proxy.co'); - expect(monitorIntervalNumber.value).toEqual('1'); - expect(monitorIntervalUnit.value).toEqual(ScheduleUnit.MINUTES); - expect(apmServiceName.value).toEqual('APM Service'); - expect(maxRedirects.value).toEqual('2'); - expect(timeout.value).toEqual('3'); - - await waitFor(() => { - expect(onChange).toBeCalledWith({ - isValid: true, - updatedPolicy: { - ...defaultNewPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - streams: [ - { - ...defaultNewPolicy.inputs[0].streams[0], - vars: { - ...defaultNewPolicy.inputs[0].streams[0].vars, - urls: { - value: 'http://elastic.co', - type: 'text', - }, - proxy_url: { - value: 'http://proxy.co', - type: 'text', - }, - schedule: { - value: '"@every 1m"', - type: 'text', - }, - 'service.name': { - value: 'APM Service', - type: 'text', - }, - max_redirects: { - value: '2', - type: 'integer', - }, - timeout: { - value: '3s', - type: 'text', - }, - }, - }, - ], - }, - defaultNewPolicy.inputs[1], - defaultNewPolicy.inputs[2], - defaultNewPolicy.inputs[3], - ], - }, - }); - }); - }); - - it('handles calling onChange', async () => { - const { getByLabelText } = render(); - const url = getByLabelText('URL') as HTMLInputElement; - - fireEvent.change(url, { target: { value: 'http://elastic.co' } }); - - await waitFor(() => { - expect(onChange).toBeCalledWith({ - isValid: true, - updatedPolicy: { - ...defaultNewPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - streams: [ - { - ...defaultNewPolicy.inputs[0].streams[0], - vars: { - ...defaultNewPolicy.inputs[0].streams[0].vars, - urls: { - value: 'http://elastic.co', - type: 'text', - }, - }, - }, - ], - }, - defaultNewPolicy.inputs[1], - defaultNewPolicy.inputs[2], - defaultNewPolicy.inputs[3], - ], - }, - }); - }); - }); - - it('handles http validation', async () => { - const { getByText, getByLabelText, queryByText } = render(); - - const url = getByLabelText('URL') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const maxRedirects = getByLabelText('Max redirects') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - - // create errors - fireEvent.change(url, { target: { value: '' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '-1' } }); - fireEvent.change(maxRedirects, { target: { value: '-1' } }); - fireEvent.change(timeout, { target: { value: '-1' } }); - - const urlError = getByText('URL is required'); - const monitorIntervalError = getByText('Monitor frequency is required'); - const maxRedirectsError = getByText('Max redirects must be 0 or greater'); - const timeoutError = getByText('Timeout must be greater than or equal to 0'); - - expect(urlError).toBeInTheDocument(); - expect(monitorIntervalError).toBeInTheDocument(); - expect(maxRedirectsError).toBeInTheDocument(); - expect(timeoutError).toBeInTheDocument(); - - // expect onChange to be called with isValid false - await waitFor(() => { - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: false, - }) - ); - }); - - // resolve errors - fireEvent.change(url, { target: { value: 'http://elastic.co' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '1' } }); - fireEvent.change(maxRedirects, { target: { value: '1' } }); - fireEvent.change(timeout, { target: { value: '1' } }); - - // expect onChange to be called with isValid true - await waitFor(() => { - expect(queryByText('URL is required')).not.toBeInTheDocument(); - expect(queryByText('Monitor frequency is required')).not.toBeInTheDocument(); - expect(queryByText('Max redirects must be 0 or greater')).not.toBeInTheDocument(); - expect(queryByText('Timeout must be greater than or equal to 0')).not.toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: true, - }) - ); - }); - }); - - it('shows tls fields when metadata.is_tls_enabled', async () => { - const currentPolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[0].streams[0], - vars: { - ...defaultNewPolicy.inputs[0].streams[0].vars, - __ui: { - type: 'yaml', - value: JSON.stringify({ - is_tls_enabled: true, - }), - }, - }, - }, - ], - }, - ], - }; - - const { getByLabelText } = render(); - const verificationMode = getByLabelText('Verification mode') as HTMLInputElement; - const enableTLSConfig = getByLabelText('Enable TLS configuration') as HTMLInputElement; - expect(enableTLSConfig.getAttribute('aria-checked')).toEqual('true'); - expect(verificationMode).toBeInTheDocument(); - expect(verificationMode.value).toEqual(`${defaultHTTPConfig[ConfigKey.TLS_VERIFICATION_MODE]}`); - }); - - it('handles browser validation', async () => { - const currentPolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[2], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[3], - enabled: true, - }, - ], - }; - const { getByText, getByLabelText, queryByText, getByRole, getByTestId } = render( - - ); - - const zip = getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - const zipUrl = getByRole('textbox', { name: 'Zip URL' }) as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - - // create errors - fireEvent.change(zipUrl, { target: { value: '' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '-1' } }); - - await waitFor(() => { - const hostError = getByText('Zip URL is required'); - const monitorIntervalError = getByText('Monitor frequency is required'); - - expect(hostError).toBeInTheDocument(); - expect(monitorIntervalError).toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: false, - }) - ); - }); - - await waitFor(() => { - fireEvent.change(zipUrl, { target: { value: 'http://github.com/tests.zip' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '2' } }); - expect(zipUrl.value).toEqual('http://github.com/tests.zip'); - expect(monitorIntervalNumber.value).toEqual('2'); - expect(queryByText('Zip URL is required')).not.toBeInTheDocument(); - expect(queryByText('Monitor frequency is required')).not.toBeInTheDocument(); - expect(queryByText('Timeout must be greater than or equal to 0')).not.toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: true, - }) - ); - }); - - await waitFor(() => { - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: true, - }) - ); - }); - }, 10000); - - it('handles tcp validation', async () => { - const currentPolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: true, - }, - defaultNewPolicy.inputs[2], - defaultNewPolicy.inputs[3], - ], - }; - const { getByText, getByLabelText, queryByText } = render( - - ); - - const host = getByLabelText('Host:Port') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - - // create errors - fireEvent.change(host, { target: { value: 'localhost' } }); // host without port - fireEvent.change(monitorIntervalNumber, { target: { value: '-1' } }); - fireEvent.change(timeout, { target: { value: '-1' } }); - - await waitFor(() => { - const hostError = getByText('Host and port are required'); - const monitorIntervalError = getByText('Monitor frequency is required'); - const timeoutError = getByText('Timeout must be greater than or equal to 0'); - - expect(hostError).toBeInTheDocument(); - expect(monitorIntervalError).toBeInTheDocument(); - expect(timeoutError).toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: false, - }) - ); - }); - - // resolve errors - fireEvent.change(host, { target: { value: 'smtp.gmail.com:587' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '1' } }); - fireEvent.change(timeout, { target: { value: '1' } }); - - await waitFor(() => { - expect(queryByText('Host is required')).not.toBeInTheDocument(); - expect(queryByText('Monitor frequency is required')).not.toBeInTheDocument(); - expect(queryByText('Timeout must be greater than or equal to 0')).not.toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: true, - }) - ); - }); - }); - - it('handles icmp validation', async () => { - const currentPolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[2], - enabled: true, - }, - defaultNewPolicy.inputs[3], - ], - }; - const { getByText, getByLabelText, queryByText } = render( - - ); - - const host = getByLabelText('Host') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - const wait = getByLabelText('Wait in seconds') as HTMLInputElement; - - // create errors - fireEvent.change(host, { target: { value: '' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '-1' } }); - fireEvent.change(timeout, { target: { value: '-1' } }); - fireEvent.change(wait, { target: { value: '-1' } }); - - await waitFor(() => { - const hostError = getByText('Host is required'); - const monitorIntervalError = getByText('Monitor frequency is required'); - const timeoutError = getByText('Timeout must be greater than or equal to 0'); - const waitError = getByText('Wait must be 0 or greater'); - - expect(hostError).toBeInTheDocument(); - expect(monitorIntervalError).toBeInTheDocument(); - expect(timeoutError).toBeInTheDocument(); - expect(waitError).toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: false, - }) - ); - }); - - // resolve errors - fireEvent.change(host, { target: { value: '1.1.1.1' } }); - fireEvent.change(monitorIntervalNumber, { target: { value: '1' } }); - fireEvent.change(timeout, { target: { value: '1' } }); - fireEvent.change(wait, { target: { value: '1' } }); - - await waitFor(() => { - expect(queryByText('Host is required')).not.toBeInTheDocument(); - expect(queryByText('Monitor frequency is required')).not.toBeInTheDocument(); - expect(queryByText('Timeout must be greater than or equal to 0')).not.toBeInTheDocument(); - expect(queryByText('Wait must be 0 or greater')).not.toBeInTheDocument(); - expect(onChange).toBeCalledWith( - expect.objectContaining({ - isValid: true, - }) - ); - }); - }); - - it('handles null values for http', async () => { - const httpVars = defaultNewPolicy.inputs[0].streams[0].vars; - const currentPolicy: NewPackagePolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[0].streams[0], - vars: { - ...Object.keys(httpVars || []).reduce< - Record - >((acc, key) => { - acc[key] = { - value: undefined, - type: `${httpVars?.[key].type}`, - }; - return acc; - }, {}), - [ConfigKey.MONITOR_TYPE]: { - value: 'http', - type: 'text', - }, - }, - }, - ], - }, - defaultCurrentPolicy.inputs[1], - defaultCurrentPolicy.inputs[2], - defaultCurrentPolicy.inputs[3], - ], - }; - const { getByText, getByLabelText, queryByLabelText, queryByText } = render( - - ); - const url = getByLabelText('URL') as HTMLInputElement; - const proxyUrl = getByLabelText('Proxy URL') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - const maxRedirects = getByLabelText('Max redirects') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - const enableTLSConfig = getByLabelText('Enable TLS configuration') as HTMLInputElement; - - expect(url).toBeInTheDocument(); - expect(url.value).toEqual(defaultHTTPConfig[ConfigKey.URLS]); - expect(proxyUrl).toBeInTheDocument(); - expect(proxyUrl.value).toEqual(defaultHTTPConfig[ConfigKey.PROXY_URL]); - expect(monitorIntervalNumber).toBeInTheDocument(); - expect(monitorIntervalNumber.value).toEqual(defaultHTTPConfig[ConfigKey.SCHEDULE].number); - expect(monitorIntervalUnit).toBeInTheDocument(); - expect(monitorIntervalUnit.value).toEqual(defaultHTTPConfig[ConfigKey.SCHEDULE].unit); - expect(apmServiceName).toBeInTheDocument(); - expect(apmServiceName.value).toEqual(defaultHTTPConfig[ConfigKey.APM_SERVICE_NAME]); - expect(maxRedirects).toBeInTheDocument(); - expect(maxRedirects.value).toEqual(`${defaultHTTPConfig[ConfigKey.MAX_REDIRECTS]}`); - expect(timeout).toBeInTheDocument(); - expect(timeout.value).toEqual(`${defaultHTTPConfig[ConfigKey.TIMEOUT]}`); - - /* expect TLS settings not to be in the document when and Enable TLS settings not to be checked - * when all TLS values are falsey */ - expect(enableTLSConfig.getAttribute('aria-checked')).toEqual('false'); - expect(queryByText('Verification mode')).not.toBeInTheDocument(); - - // ensure other monitor type options are not in the DOM - expect(queryByLabelText('Host')).not.toBeInTheDocument(); - expect(queryByLabelText('Wait in seconds')).not.toBeInTheDocument(); - - // ensure at least one http advanced option is present - const advancedOptionsButton = getByText('Advanced HTTP options'); - fireEvent.click(advancedOptionsButton); - await waitFor(() => { - const requestMethod = getByLabelText('Request method') as HTMLInputElement; - expect(requestMethod).toBeInTheDocument(); - expect(requestMethod.value).toEqual(`${defaultHTTPConfig[ConfigKey.REQUEST_METHOD_CHECK]}`); - }); - }); - - it('handles null values for tcp', async () => { - const tcpVars = defaultNewPolicy.inputs[1].streams[0].vars; - const currentPolicy: NewPackagePolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[1].streams[0], - vars: { - ...Object.keys(tcpVars || []).reduce< - Record - >((acc, key) => { - acc[key] = { - value: undefined, - type: `${tcpVars?.[key].type}`, - }; - return acc; - }, {}), - [ConfigKey.MONITOR_TYPE]: { - value: DataStream.TCP, - type: 'text', - }, - }, - }, - ], - }, - defaultCurrentPolicy.inputs[2], - ], - }; - const { getByText, getByLabelText, queryByLabelText } = render( - - ); - const host = getByLabelText('Host:Port') as HTMLInputElement; - const proxyUrl = getByLabelText('Proxy URL') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - expect(host).toBeInTheDocument(); - expect(host.value).toEqual(defaultTCPConfig[ConfigKey.HOSTS]); - expect(proxyUrl).toBeInTheDocument(); - expect(proxyUrl.value).toEqual(defaultTCPConfig[ConfigKey.PROXY_URL]); - expect(monitorIntervalNumber).toBeInTheDocument(); - expect(monitorIntervalNumber.value).toEqual(defaultTCPConfig[ConfigKey.SCHEDULE].number); - expect(monitorIntervalUnit).toBeInTheDocument(); - expect(monitorIntervalUnit.value).toEqual(defaultTCPConfig[ConfigKey.SCHEDULE].unit); - expect(apmServiceName).toBeInTheDocument(); - expect(apmServiceName.value).toEqual(defaultTCPConfig[ConfigKey.APM_SERVICE_NAME]); - expect(timeout).toBeInTheDocument(); - expect(timeout.value).toEqual(`${defaultTCPConfig[ConfigKey.TIMEOUT]}`); - - // ensure other monitor type options are not in the DOM - expect(queryByLabelText('Url')).not.toBeInTheDocument(); - expect(queryByLabelText('Wait in seconds')).not.toBeInTheDocument(); - - // ensure at least one tcp advanced option is present - const advancedOptionsButton = getByText('Advanced TCP options'); - fireEvent.click(advancedOptionsButton); - await waitFor(() => { - expect(getByLabelText('Request payload')).toBeInTheDocument(); - }); - }); - - it('handles null values for icmp', async () => { - const icmpVars = defaultNewPolicy.inputs[2].streams[0].vars; - const currentPolicy: NewPackagePolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[2], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[2].streams[0], - vars: { - ...Object.keys(icmpVars || []).reduce< - Record - >((acc, key) => { - acc[key] = { - value: undefined, - type: `${icmpVars?.[key].type}`, - }; - return acc; - }, {}), - [ConfigKey.MONITOR_TYPE]: { - value: DataStream.ICMP, - type: 'text', - }, - }, - }, - ], - }, - ], - }; - const { getByLabelText, queryByLabelText } = render( - - ); - const host = getByLabelText('Host') as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - const timeout = getByLabelText('Timeout in seconds') as HTMLInputElement; - const wait = getByLabelText('Wait in seconds') as HTMLInputElement; - expect(host).toBeInTheDocument(); - expect(host.value).toEqual(defaultICMPConfig[ConfigKey.HOSTS]); - expect(monitorIntervalNumber).toBeInTheDocument(); - expect(monitorIntervalNumber.value).toEqual(defaultICMPConfig[ConfigKey.SCHEDULE].number); - expect(monitorIntervalUnit).toBeInTheDocument(); - expect(monitorIntervalUnit.value).toEqual(defaultICMPConfig[ConfigKey.SCHEDULE].unit); - expect(apmServiceName).toBeInTheDocument(); - expect(apmServiceName.value).toEqual(defaultICMPConfig[ConfigKey.APM_SERVICE_NAME]); - expect(timeout).toBeInTheDocument(); - expect(timeout.value).toEqual(`${defaultICMPConfig[ConfigKey.TIMEOUT]}`); - expect(wait).toBeInTheDocument(); - expect(wait.value).toEqual(`${defaultICMPConfig[ConfigKey.WAIT]}`); - - // ensure other monitor type options are not in the DOM - expect(queryByLabelText('Url')).not.toBeInTheDocument(); - expect(queryByLabelText('Proxy URL')).not.toBeInTheDocument(); - }); - - it('handles null values for browser', async () => { - const browserVars = defaultNewPolicy.inputs[3].streams[0].vars; - const currentPolicy: NewPackagePolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[2], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[3], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[3].streams[0], - vars: { - ...Object.keys(browserVars || []).reduce< - Record - >((acc, key) => { - acc[key] = { - value: undefined, - type: `${browserVars?.[key].type}`, - }; - return acc; - }, {}), - [ConfigKey.MONITOR_TYPE]: { - value: DataStream.BROWSER, - type: 'text', - }, - }, - }, - ], - }, - ], - }; - const { getByLabelText, queryByLabelText, getByRole, getByTestId } = render( - - ); - const zip = getByTestId('syntheticsSourceTab__zipUrl'); - fireEvent.click(zip); - const zipUrl = getByRole('textbox', { name: 'Zip URL' }) as HTMLInputElement; - const monitorIntervalNumber = getByLabelText('Number') as HTMLInputElement; - const monitorIntervalUnit = getByLabelText('Unit') as HTMLInputElement; - const apmServiceName = getByLabelText('APM service name') as HTMLInputElement; - expect(zipUrl).toBeInTheDocument(); - expect(zipUrl.value).toEqual(defaultBrowserConfig[ConfigKey.SOURCE_ZIP_URL]); - expect(monitorIntervalNumber).toBeInTheDocument(); - expect(monitorIntervalNumber.value).toEqual(defaultBrowserConfig[ConfigKey.SCHEDULE].number); - expect(monitorIntervalUnit).toBeInTheDocument(); - expect(monitorIntervalUnit.value).toEqual(defaultBrowserConfig[ConfigKey.SCHEDULE].unit); - expect(apmServiceName).toBeInTheDocument(); - expect(apmServiceName.value).toEqual(defaultBrowserConfig[ConfigKey.APM_SERVICE_NAME]); - - // ensure other monitor type options are not in the DOM - expect(queryByLabelText('Url')).not.toBeInTheDocument(); - expect(queryByLabelText('Proxy URL')).not.toBeInTheDocument(); - expect(queryByLabelText('Host')).not.toBeInTheDocument(); - }); - - it.each([ - [true, 'Testing script'], - [false, 'Inline script'], - ])( - 'browser monitors - auto selects the right tab depending on source metadata', - async (isGeneratedScript, text) => { - const currentPolicy = { - ...defaultCurrentPolicy, - inputs: [ - { - ...defaultNewPolicy.inputs[0], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[1], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[2], - enabled: false, - }, - { - ...defaultNewPolicy.inputs[3], - enabled: true, - streams: [ - { - ...defaultNewPolicy.inputs[3].streams[0], - vars: { - ...defaultNewPolicy.inputs[3].streams[0].vars, - 'source.inline.script': { - type: 'yaml', - value: JSON.stringify('step(() => {})'), - }, - __ui: { - type: 'yaml', - value: JSON.stringify({ - script_source: { - is_generated_script: isGeneratedScript, - }, - }), - }, - }, - }, - ], - }, - ], - }; - - const { getByText } = render(); - - expect(getByText(text)).toBeInTheDocument(); - } - ); - - it('hides tls fields when metadata.is_tls_enabled is false', async () => { - const { getByLabelText, queryByLabelText } = render( - - ); - - const verificationMode = queryByLabelText('Verification mode'); - const enableTLSConfig = getByLabelText('Enable TLS configuration') as HTMLInputElement; - expect(enableTLSConfig.getAttribute('aria-checked')).toEqual('false'); - expect(verificationMode).not.toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx index 00d5e8bd7b940..1f1be99eb5ffd 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/synthetics_policy_edit_extension_wrapper.tsx @@ -5,28 +5,15 @@ * 2.0. */ -import React, { memo, useMemo } from 'react'; +import React, { memo, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButton, EuiCallOut, EuiSpacer } from '@elastic/eui'; -import type { - FleetStartServices, - PackagePolicyEditExtensionComponentProps, -} from '@kbn/fleet-plugin/public'; +import type { FleetStartServices } from '@kbn/fleet-plugin/public'; +import { EuiButton, EuiCallOut } from '@elastic/eui'; +import type { PackagePolicyEditExtensionComponentProps } from '@kbn/fleet-plugin/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useEditMonitorLocator } from '../../../apps/synthetics/hooks'; -import type { PolicyConfig, MonitorFields, TLSFields } from './types'; +import { DeprecateNoticeModal } from './deprecate_notice_modal'; import { ConfigKey, DataStream } from './types'; -import { SyntheticsPolicyEditExtension } from './synthetics_policy_edit_extension'; -import { - PolicyConfigContextProvider, - HTTPContextProvider, - TCPContextProvider, - ICMPSimpleFieldsContextProvider, - BrowserContextProvider, - TLSFieldsContextProvider, -} from './contexts'; -import { normalizers } from './helpers/normalizers'; -import { IntegrationDeprecationCallout } from '../overview/integration_deprecation/integration_deprecation_callout'; +import { useEditMonitorLocator } from '../../../apps/synthetics/hooks'; /** * Exports Synthetics-specific package policy instructions @@ -34,78 +21,23 @@ import { IntegrationDeprecationCallout } from '../overview/integration_deprecati */ export const SyntheticsPolicyEditExtensionWrapper = memo( ({ policy: currentPolicy, newPolicy, onChange }) => { - const { - enableTLS: isTLSEnabled, - enableZipUrlTLS: isZipUrlTLSEnabled, - fullConfig: fullDefaultConfig, - monitorTypeConfig: defaultConfig, - monitorType, - tlsConfig: defaultTLSConfig, - } = useMemo(() => { - let enableTLS = false; - let enableZipUrlTLS = false; - const getDefaultConfig = () => { - // find the enabled input to identify the current monitor type - const currentInput = currentPolicy.inputs.find((input) => input.enabled === true); - /* Inputs can have multiple data streams. This is true of the `synthetics/browser` input, which includes the browser.network and browser.screenshot - * data streams. The `browser.network` and `browser.screenshot` data streams are used to store metadata and mappings. - * However, the `browser` data stream is where the variables for the policy are stored. For this reason, we only want - * to grab the data stream that exists within our explicitly defined list, which is the browser data stream */ - const vars = currentInput?.streams.find((stream) => - Object.values(DataStream).includes(stream.data_stream.dataset as DataStream) - )?.vars; - - const type: DataStream = vars?.[ConfigKey.MONITOR_TYPE].value as DataStream; - - const configKeys: ConfigKey[] = Object.values(ConfigKey) || ([] as ConfigKey[]); - const formattedDefaultConfigForMonitorType: MonitorFields = - configKeys.reduce((acc: MonitorFields, key: ConfigKey) => { - return { - ...acc, - [key]: normalizers[key]?.(vars), - }; - }, {} as MonitorFields); + const { application } = useKibana().services; - const tlsConfig: TLSFields = { - [ConfigKey.TLS_CERTIFICATE_AUTHORITIES]: - formattedDefaultConfigForMonitorType[ConfigKey.TLS_CERTIFICATE_AUTHORITIES], - [ConfigKey.TLS_CERTIFICATE]: - formattedDefaultConfigForMonitorType[ConfigKey.TLS_CERTIFICATE], - [ConfigKey.TLS_KEY]: formattedDefaultConfigForMonitorType[ConfigKey.TLS_KEY], - [ConfigKey.TLS_KEY_PASSPHRASE]: - formattedDefaultConfigForMonitorType[ConfigKey.TLS_KEY_PASSPHRASE], - [ConfigKey.TLS_VERIFICATION_MODE]: - formattedDefaultConfigForMonitorType[ConfigKey.TLS_VERIFICATION_MODE], - [ConfigKey.TLS_VERSION]: formattedDefaultConfigForMonitorType[ConfigKey.TLS_VERSION], - }; + const { package: pkg } = newPolicy; - enableTLS = - formattedDefaultConfigForMonitorType[ConfigKey.METADATA]?.is_tls_enabled ?? - Boolean(vars?.[ConfigKey.TLS_VERIFICATION_MODE]?.value); - enableZipUrlTLS = - formattedDefaultConfigForMonitorType[ConfigKey.METADATA]?.is_zip_url_tls_enabled ?? - Boolean(vars?.[ConfigKey.ZIP_URL_TLS_VERIFICATION_MODE]?.value); - - const formattedDefaultConfig: Partial = { - [type]: formattedDefaultConfigForMonitorType, - }; - - return { - fullConfig: formattedDefaultConfig, - monitorTypeConfig: formattedDefaultConfigForMonitorType, - tlsConfig, - monitorType: type, - enableTLS, - enableZipUrlTLS, - }; - }; - - return getDefaultConfig(); - }, [currentPolicy]); + const onCancel = useCallback(() => { + application?.navigateToApp('integrations', { + path: `/detail/${pkg?.name}-${pkg?.version}/overview`, + }); + }, [application, pkg?.name, pkg?.version]); const locators = useKibana().services?.share?.url?.locators; + const currentInput = currentPolicy.inputs.find((input) => input.enabled === true); + const vars = currentInput?.streams.find((stream) => + Object.values(DataStream).includes(stream.data_stream.dataset as DataStream) + )?.vars; - const { config_id: configId } = defaultConfig; + const configId: string = vars?.[ConfigKey.CONFIG_ID]?.value as DataStream; const url = useEditMonitorLocator({ configId, locators }); @@ -118,34 +50,9 @@ export const SyntheticsPolicyEditExtensionWrapper = memo ); + } else { + return ; } - - return ( - - - - - - - - - - - - - - - - ); } ); SyntheticsPolicyEditExtensionWrapper.displayName = 'SyntheticsPolicyEditExtensionWrapper'; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/normalizers.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/normalizers.ts deleted file mode 100644 index 4fd671732260b..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/tcp/normalizers.ts +++ /dev/null @@ -1,44 +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 { TCPFields, ConfigKey } from '../types'; -import { - Normalizer, - commonNormalizers, - getNormalizer, - getJsonToJavascriptNormalizer, -} from '../common/normalizers'; -import { tlsNormalizers } from '../tls/normalizers'; -import { defaultTCPSimpleFields, defaultTCPAdvancedFields } from '../contexts'; - -const defaultTCPFields = { - ...defaultTCPSimpleFields, - ...defaultTCPAdvancedFields, -}; - -export type TCPNormalizerMap = Record; - -export const getTCPNormalizer = (key: ConfigKey) => { - return getNormalizer(key, defaultTCPFields); -}; - -export const getTCPJsonToJavascriptNormalizer = (key: ConfigKey) => { - return getJsonToJavascriptNormalizer(key, defaultTCPFields); -}; - -export const tcpNormalizers: TCPNormalizerMap = { - [ConfigKey.METADATA]: getTCPJsonToJavascriptNormalizer(ConfigKey.METADATA), - [ConfigKey.HOSTS]: getTCPNormalizer(ConfigKey.HOSTS), - [ConfigKey.PORT]: getTCPNormalizer(ConfigKey.PORT), - [ConfigKey.PROXY_URL]: getTCPNormalizer(ConfigKey.PROXY_URL), - [ConfigKey.PROXY_USE_LOCAL_RESOLVER]: getTCPNormalizer(ConfigKey.PROXY_USE_LOCAL_RESOLVER), - [ConfigKey.RESPONSE_RECEIVE_CHECK]: getTCPNormalizer(ConfigKey.RESPONSE_RECEIVE_CHECK), - [ConfigKey.REQUEST_SEND_CHECK]: getTCPNormalizer(ConfigKey.REQUEST_SEND_CHECK), - [ConfigKey.URLS]: getTCPNormalizer(ConfigKey.URLS), - ...tlsNormalizers, - ...commonNormalizers, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts deleted file mode 100644 index 2a9ead81fce33..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.test.ts +++ /dev/null @@ -1,76 +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 { - ConfigKey, - DataStream, - HTTPFields, - MonitorFields, - ScheduleUnit, - SyntheticsMonitor, -} from '../../../../common/runtime_types'; -import { validate } from './validation'; - -describe('[Monitor Management] validation', () => { - const commonPropsValid: Partial = { - [ConfigKey.SCHEDULE]: { number: '5', unit: ScheduleUnit.MINUTES }, - [ConfigKey.TIMEOUT]: '3m', - }; - - describe('HTTP', () => { - const httpPropsValid: Partial = { - ...commonPropsValid, - [ConfigKey.RESPONSE_STATUS_CHECK]: ['200', '204'], - [ConfigKey.RESPONSE_HEADERS_CHECK]: { 'Content-Type': 'application/json' }, - [ConfigKey.REQUEST_HEADERS_CHECK]: { 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8' }, - [ConfigKey.MAX_REDIRECTS]: '3', - [ConfigKey.URLS]: 'https:// example-url.com', - }; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.HTTP]; - const keysToValidate = [ - ConfigKey.SCHEDULE, - ConfigKey.TIMEOUT, - ConfigKey.RESPONSE_STATUS_CHECK, - ConfigKey.RESPONSE_HEADERS_CHECK, - ConfigKey.REQUEST_HEADERS_CHECK, - ConfigKey.MAX_REDIRECTS, - ConfigKey.URLS, - ]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(httpPropsValid) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - }); - - describe.each([ - [ConfigKey.SOURCE_INLINE, 'step(() => {});'], - [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], - ])('Browser', (configKey, value) => { - const browserProps = { - ...commonPropsValid, - [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, - [ConfigKey.TIMEOUT]: null, - [ConfigKey.URLS]: null, - [ConfigKey.PORT]: null, - [configKey]: value, - } as SyntheticsMonitor; - - it('should return false for all valid props', () => { - const validators = validate[DataStream.BROWSER]; - const keysToValidate = [ConfigKey.SCHEDULE, ConfigKey.TIMEOUT, configKey]; - const validatorFns = keysToValidate.map((key) => validators[key]); - const result = validatorFns.map((fn) => fn?.(browserProps as Partial) ?? true); - - expect(result).not.toEqual(expect.arrayContaining([true])); - }); - }); - - // TODO: Add test for other monitor types if needed -}); diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.tsx deleted file mode 100644 index 396922c79e1fc..0000000000000 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/fleet_package/validation.tsx +++ /dev/null @@ -1,160 +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 { ConfigKey, DataStream, ScheduleUnit, MonitorFields, Validator, Validation } from './types'; - -export const digitsOnly = /^[0-9]*$/g; -export const includesValidPort = /[^\:]+:[0-9]{1,5}$/g; - -type ValidationLibrary = Record; - -// returns true if invalid -function validateHeaders(headers: T): boolean { - return Object.keys(headers).some((key) => { - if (key) { - const whiteSpaceRegEx = /[\s]/g; - return whiteSpaceRegEx.test(key); - } else { - return false; - } - }); -} - -// returns true if invalid -const validateTimeout = ({ - scheduleNumber, - scheduleUnit, - timeout, -}: { - scheduleNumber: string; - scheduleUnit: ScheduleUnit; - timeout: string; -}): boolean => { - let schedule: number; - switch (scheduleUnit) { - case ScheduleUnit.SECONDS: - schedule = parseFloat(scheduleNumber); - break; - case ScheduleUnit.MINUTES: - schedule = parseFloat(scheduleNumber) * 60; - break; - default: - schedule = parseFloat(scheduleNumber); - } - - return parseFloat(timeout) > schedule; -}; - -// validation functions return true when invalid -const validateCommon: ValidationLibrary = { - [ConfigKey.SCHEDULE]: ({ [ConfigKey.SCHEDULE]: value }) => { - const { number, unit } = value as MonitorFields[ConfigKey.SCHEDULE]; - const parsedFloat = parseFloat(number); - return !parsedFloat || !unit || parsedFloat < 1; - }, - [ConfigKey.TIMEOUT]: ({ - [ConfigKey.MONITOR_TYPE]: monitorType, - [ConfigKey.TIMEOUT]: timeout, - [ConfigKey.SCHEDULE]: schedule, - }) => { - const { number, unit } = schedule as MonitorFields[ConfigKey.SCHEDULE]; - - // Timeout is not currently supported by browser monitors - if (monitorType === DataStream.BROWSER) { - return false; - } - - return ( - !timeout || - parseFloat(timeout) < 0 || - validateTimeout({ - timeout, - scheduleNumber: number, - scheduleUnit: unit, - }) - ); - }, -}; - -const validateHTTP: ValidationLibrary = { - [ConfigKey.RESPONSE_STATUS_CHECK]: ({ [ConfigKey.RESPONSE_STATUS_CHECK]: value }) => { - const statusCodes = value as MonitorFields[ConfigKey.RESPONSE_STATUS_CHECK]; - return statusCodes.length ? statusCodes.some((code) => !`${code}`.match(digitsOnly)) : false; - }, - [ConfigKey.RESPONSE_HEADERS_CHECK]: ({ [ConfigKey.RESPONSE_HEADERS_CHECK]: value }) => { - const headers = value as MonitorFields[ConfigKey.RESPONSE_HEADERS_CHECK]; - return validateHeaders(headers); - }, - [ConfigKey.REQUEST_HEADERS_CHECK]: ({ [ConfigKey.REQUEST_HEADERS_CHECK]: value }) => { - const headers = value as MonitorFields[ConfigKey.REQUEST_HEADERS_CHECK]; - return validateHeaders(headers); - }, - [ConfigKey.MAX_REDIRECTS]: ({ [ConfigKey.MAX_REDIRECTS]: value }) => - (!!value && !`${value}`.match(digitsOnly)) || - parseFloat(value as MonitorFields[ConfigKey.MAX_REDIRECTS]) < 0, - [ConfigKey.URLS]: ({ [ConfigKey.URLS]: value }) => !value, - ...validateCommon, -}; - -const validateTCP: Record = { - [ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => { - return !value || !`${value}`.match(includesValidPort); - }, - ...validateCommon, -}; - -const validateICMP: ValidationLibrary = { - [ConfigKey.HOSTS]: ({ [ConfigKey.HOSTS]: value }) => !value, - [ConfigKey.WAIT]: ({ [ConfigKey.WAIT]: value }) => - !!value && - !digitsOnly.test(`${value}`) && - parseFloat(value as MonitorFields[ConfigKey.WAIT]) < 0, - ...validateCommon, -}; - -const validateThrottleValue = (speed: string | undefined, allowZero?: boolean) => { - if (speed === undefined || speed === '') return false; - const throttleValue = parseFloat(speed); - return isNaN(throttleValue) || (allowZero ? throttleValue < 0 : throttleValue <= 0); -}; - -export const validateParamsValue = (params?: string) => { - try { - if (params) { - JSON.parse(params ?? ''); - } - } catch (e) { - return true; - } - return false; -}; - -const validateBrowser: ValidationLibrary = { - ...validateCommon, - [ConfigKey.SOURCE_ZIP_URL]: ({ - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_INLINE]: inlineScript, - }) => !zipUrl && !inlineScript, - [ConfigKey.SOURCE_INLINE]: ({ - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_INLINE]: inlineScript, - }) => !zipUrl && !inlineScript, - [ConfigKey.DOWNLOAD_SPEED]: ({ [ConfigKey.DOWNLOAD_SPEED]: downloadSpeed }) => - validateThrottleValue(downloadSpeed), - [ConfigKey.UPLOAD_SPEED]: ({ [ConfigKey.UPLOAD_SPEED]: uploadSpeed }) => - validateThrottleValue(uploadSpeed), - [ConfigKey.LATENCY]: ({ [ConfigKey.LATENCY]: latency }) => validateThrottleValue(latency, true), - [ConfigKey.PARAMS]: ({ [ConfigKey.PARAMS]: params }) => validateParamsValue(params), -}; - -export type ValidateDictionary = Record; - -export const validate: ValidateDictionary = { - [DataStream.HTTP]: validateHTTP, - [DataStream.TCP]: validateTCP, - [DataStream.ICMP]: validateICMP, - [DataStream.BROWSER]: validateBrowser, -}; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx index e80a305afa6fa..04d86c8042c37 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/edit_monitor_config.tsx @@ -32,14 +32,12 @@ export const EditMonitorConfig = ({ monitor, throttling }: Props) => { const { enableTLS: isTLSEnabled, - enableZipUrlTLS: isZipUrlTLSEnabled, fullConfig: fullDefaultConfig, monitorTypeConfig: defaultConfig, monitorType, tlsConfig: defaultTLSConfig, } = useMemo(() => { let enableTLS = false; - let enableZipUrlTLS = false; const getDefaultConfig = () => { const type: DataStream = monitor[ConfigKey.MONITOR_TYPE] as DataStream; @@ -53,7 +51,6 @@ export const EditMonitorConfig = ({ monitor, throttling }: Props) => { }; enableTLS = Boolean(monitor[ConfigKey.METADATA]?.is_tls_enabled); - enableZipUrlTLS = Boolean(monitor[ConfigKey.METADATA]?.is_zip_url_tls_enabled); const formattedDefaultConfig: Partial = { [type]: monitor, @@ -65,7 +62,6 @@ export const EditMonitorConfig = ({ monitor, throttling }: Props) => { tlsConfig, monitorType: type, enableTLS, - enableZipUrlTLS, }; }; @@ -77,13 +73,11 @@ export const EditMonitorConfig = ({ monitor, throttling }: Props) => { policyDefaultValues={{ throttling, defaultIsTLSEnabled: isTLSEnabled, - defaultIsZipUrlTLSEnabled: isZipUrlTLSEnabled, defaultMonitorType: monitorType, defaultName: defaultConfig?.[ConfigKey.NAME] || '', // TODO - figure out typing concerns for name defaultNamespace: defaultConfig?.[ConfigKey.NAMESPACE] || DEFAULT_NAMESPACE_STRING, defaultLocations: defaultConfig[ConfigKey.LOCATIONS], isEditable: true, - isZipUrlSourceEnabled: false, allowedScheduleUnits: [ScheduleUnit.MINUTES], runsOnService: true, sourceType: monitor[ConfigKey.MONITOR_SOURCE_TYPE] || SourceType.UI, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts index dc2e5cb48c077..616041ad1bd99 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.test.ts @@ -92,10 +92,7 @@ describe('[Monitor Management] validation', () => { }); }); - describe.each([ - [ConfigKey.SOURCE_INLINE, 'step(() => {});'], - [ConfigKey.SOURCE_ZIP_URL, 'https://test.zip'], - ])('Browser', (configKey, value) => { + describe.each([[ConfigKey.SOURCE_INLINE, 'step(() => {});']])('Browser', (configKey, value) => { const browserProps = { ...commonPropsValid, [ConfigKey.MONITOR_TYPE]: DataStream.BROWSER, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts index 7c6e09811d225..d4abfbd62d6fb 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor_management/validation.ts @@ -5,7 +5,6 @@ * 2.0. */ import { isValidNamespace } from '@kbn/fleet-plugin/common'; -import { validateParamsValue } from '../fleet_package/validation'; import { ConfigKey, DataStream, @@ -30,6 +29,17 @@ function validateHeaders(headers: T): boolean { }); } +export const validateParamsValue = (params?: string) => { + try { + if (params) { + JSON.parse(params ?? ''); + } + } catch (e) { + return true; + } + return false; +}; + // returns true if invalid const validateTimeout = ({ scheduleNumber, @@ -142,14 +152,7 @@ const validateThrottleValue = (speed: string | undefined, allowZero?: boolean) = const validateBrowser: Validation = { ...validateCommon, - [ConfigKey.SOURCE_ZIP_URL]: ({ - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_INLINE]: inlineScript, - }) => !zipUrl && !inlineScript, - [ConfigKey.SOURCE_INLINE]: ({ - [ConfigKey.SOURCE_ZIP_URL]: zipUrl, - [ConfigKey.SOURCE_INLINE]: inlineScript, - }) => !zipUrl && !inlineScript, + [ConfigKey.SOURCE_INLINE]: ({ [ConfigKey.SOURCE_INLINE]: inlineScript }) => !inlineScript, [ConfigKey.DOWNLOAD_SPEED]: ({ [ConfigKey.DOWNLOAD_SPEED]: downloadSpeed }) => validateThrottleValue(downloadSpeed), [ConfigKey.UPLOAD_SPEED]: ({ [ConfigKey.UPLOAD_SPEED]: uploadSpeed }) => diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation.test.tsx index 68373ad85ba6b..fa257ceb218a6 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation.test.tsx @@ -15,7 +15,7 @@ import * as observabilityPublic from '@kbn/observability-plugin/public'; export const mockStorage = new StubBrowserStorage(); jest.mock('@kbn/observability-plugin/public'); -const DEPRECATION_TITLE = 'Migrate your Elastic Synthetics integration monitors before Elastic 8.8'; +const DEPRECATION_TITLE = 'Migrate your Elastic Synthetics integration monitors'; describe('IntegrationDeprecation', () => { const { FETCH_STATUS } = observabilityPublic; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation_callout.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation_callout.tsx index 415334f15c24e..17baeb741cbce 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation_callout.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/integration_deprecation/integration_deprecation_callout.tsx @@ -22,7 +22,7 @@ export function IntegrationDeprecationCallout({ title={ } color="warning" @@ -32,7 +32,7 @@ export function IntegrationDeprecationCallout({ { policyDefaultValues={{ throttling, runsOnService: true, - isZipUrlSourceEnabled: false, allowedScheduleUnits: [ScheduleUnit.MINUTES], }} > diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 68c4179861a16..7114cba4ea494 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -34401,7 +34401,6 @@ "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "score {value} et supérieur", "xpack.synthetics.createMonitorRoute.title": "Créer le moniteur | {baseTitle}", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.throttling_exceeded.message": "Vous avez dépassé la limite de {throttlingField} pour les nœuds synthétiques. La valeur {throttlingField} ne peut pas être supérieure à {limit} Mbits/s.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.content": "L'URL du Zip est déclassée et sera supprimée dans une prochaine version. Utilisez les moniteurs de projet à la place pour créer des moniteurs à partir d'un référentiel distant et pour migrer les moniteurs d'URL de Zip existants. {link}", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.content": "Pour créer un moniteur \"Navigateur\", veuillez vous assurer que vous utilisez le conteneur Docker {agent}, qui inclut les dépendances permettant d'exécuter ces moniteurs. Pour en savoir plus, visitez notre {link}.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.helpText": "Utilisez JSON pour définir les paramètres qui peuvent être référencés dans votre script avec {code}", "xpack.synthetics.deprecateNoticeModal.forMoreInformation": "Pour en savoir plus, {docsLink}", @@ -34779,14 +34778,8 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Prévisualisez la méthode la plus rapide permettant de créer des scripts de monitoring Elastic Synthetics avec notre enregistreur Elastic Synthetics", "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "Enregistreur de scripts", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Fournissez une configuration précise pour l'agent synthétique.", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "Utilisez ces options pour appliquer les paramètres de moniteur sélectionnés à un sous-ensemble des tests de votre suite. Seul le sous-ensemble configuré sera exécuté par ce moniteur.", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "Tests sélectifs", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "Définissez cette option sur \"true\" pour désactiver la validation TLS/SSL dans le navigateur synthétique. Cette opération est utile pour tester les sites qui utilisent des certificats autosignés.", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "Ignorer les erreurs HTTPS", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "Exécutez uniquement les parcours dont le nom correspond au glob fourni avec ce moniteur.", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "Filtrer la correspondance", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "Exécutez uniquement les parcours en utilisant les balises données avec ce moniteur.", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "Filtrer les balises", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "Définissez cette option pour gérer les captures d'écran effectuées par l'agent synthétique.", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "Options de capture d'écran", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Arguments supplémentaires à transmettre au package de l'agent synthétique. Accepte une liste de chaînes. Cela est utile dans des scénarios rares et ne devrait normalement pas avoir besoin d'être défini.", @@ -34806,7 +34799,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "Vitesse de chargement", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Options de l'agent synthétique", "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "Activer la configuration TLS", - "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Activer la configuration TLS pour l'URL du zip", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "Certificat formaté PEM pour l'authentification du client TLS.", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "certificat", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "Autorités de certificats personnalisés formatés PEM.", @@ -34865,8 +34857,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "Facultatif", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "Nom de service APM pour ce monitoring. Correspond au champ ECS service.name. Définissez-le lors du monitoring d'une application qui utilise également APM pour activer les intégrations entre les données Uptime et APM dans Kibana.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "Nom de service APM", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "URL du zip du proxy", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Proxy HTTP pour l'URL du zip.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "Script obligatoire", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "Exécute des scripts de tests synthétiques définis en ligne.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "Script en ligne", @@ -34877,19 +34867,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "Type de fichier non valide. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "Sélectionner un fichier .js généré par l'enregistreur", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "Erreur lors du chargement du fichier. Veuillez charger un fichier .js généré par l'enregistreur Elastic Synthetics au format de script en ligne.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.title": "L'URL de zip est déclassée", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "L'URL de zip est requise", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Emplacement du fichier zip du référentiel du projet synthétique.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "URL du zip", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Télécharger l'enregistreur Elastic Synthetics", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "Retirer le script", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "Afficher le script", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Chemin de répertoire relatif d'emplacement des fichiers de parcours synthétiques dans le référentiel.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "Dossier", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Mot de passe de l'URL du zip", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "Mot de passe pour l'authentification avec le point de terminaison du zip.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "Nom d'utilisateur pour l'authentification avec le point de terminaison du zip.", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Nom d'utilisateur de l'URL du zip", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "Navigateur (version bêta)", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "Désactivez cette configuration pour désactiver le moniteur.", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "Activé", @@ -34903,7 +34880,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "Type de moniteur", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "documentation Synthetics", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.title": "Exigence", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.zipUrl.deprecation.link": "En savoir plus", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "Le type de moniteur est requis", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.label": "Paramètres", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "Mot de passe pour l'authentification avec le serveur.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 24ae4e2592b2a..11c83f035f1d0 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -34380,7 +34380,6 @@ "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "スコア{value}以上", "xpack.synthetics.createMonitorRoute.title": "監視の作成 | {baseTitle}", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.throttling_exceeded.message": "Syntheticsノードの{throttlingField}上限を超えました。{throttlingField}値を{limit}Mbpsより大きくすることはできません。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.content": "Zip URLは廃止予定であり、将来のバージョンでは削除されます。リモートリポジトリからモニターを作成して、既存のZip URLモニターを移行するのではなく、プロジェクトモニターを使用してください。{link}", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.content": "「Browser」モニターを作成するには、{agent}Dockerコンテナーを使用していることを確認します。これには、これらのモニターを実行するための依存関係が含まれています。詳細については、{link}をご覧ください。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.helpText": "JSONを使用して、{code}のスクリプトで参照できるパラメーターを定義します", "xpack.synthetics.deprecateNoticeModal.forMoreInformation": "詳細については、{docsLink}", @@ -34758,14 +34757,8 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "Elastic Synthetics Recorderを使用してElastic Synthetics監視スクリプトを作成する最も簡単な方法をプレビュー", "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "スクリプトの記録", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "Syntheticsエージェントの微調整された構成を提供します。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "これらのオプションを使用すると、選択したモニター設定をスイートのテストのサブセットに適用します。構成されたサブセットのみがこのモニターによって実行されます。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "選択テスト", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "このオプションをtrueに設定すると、SyntheticsブラウザーでTLS/SSL検証を無効にします。これは自己署名証明書を使用するサイトのテストで役立ちます。", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "HTTPSエラーを無視", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "このモニターの指定されたglobと一致する名前のジャーニーのみを実行します。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "一致のフィルター", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "このモニターの特定のタグのジャーニーのみを実行します。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "タグのフィルター", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "このオプションを設定すると、Syntheticsエージェントでキャプチャされたスクリーンショットを管理します。", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "スクリーンショットオプション", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "Syntheticsエージェントパッケージに渡す追加の引数。文字列のリストを取ります。これはごくまれなシナリオで有用ですが、通常は設定する必要がありません。", @@ -34785,7 +34778,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "アップロード速度", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Syntheticsエージェントオプション", "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "TLS構成を有効にする", - "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "Zip URLのTLS構成を有効にする", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "TLSクライアント認証用のPEM形式の証明書。", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "証明書", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM形式のカスタム認証局。", @@ -34844,8 +34836,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "オプション", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "このモニターのAPMサービス名。service.name ECSフィールドに対応します。APMを使用して、アップタイムとKibanaのAPMデータ間の統合を有効にするアプリを監視しているときには、これを設定します。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APMサービス名", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "プロキシZip URL", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "Zip URLのHTTPプロキシ。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "スクリプトが必要です", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "インラインで定義されたSyntheticテストスクリプトを実行します。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "インラインスクリプト", @@ -34856,19 +34846,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "無効なファイルタイプです。Elastic Synthetics Recorderで生成された.jsファイルをアップロードしてください。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "レコーダーで生成された.jsファイルを選択", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "ファイルのアップロードエラーです。インラインスクリプト形式でElastic Synthetics Recorderによって生成された.jsファイルをアップロードしてください。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.title": "Zip URLは廃止予定です", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "Zip URLは必須です", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Syntheticsプロジェクトリポジトリzipファイルの場所。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "Elastic Synthetics Recorderをダウンロード", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "スクリプトを削除", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "スクリプトを表示", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "Synthetic journeyファイルが配置されるリポジトリの相対ディレクトリパス。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "フォルダー", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URLパスワード", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "zipエンドポイントに対して認証するためのパスワード。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "zipエンドポイントに対して認証するためのユーザー名。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URLユーザー名", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "ブラウザー(ベータ)", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "この構成をオフにすると、モニターが無効になります。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "有効", @@ -34882,7 +34859,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "モニタータイプ", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Syntheticsドキュメンテーション", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.title": "要件", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.zipUrl.deprecation.link": "詳細", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "モニタータイプは必須です", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.label": "パラメーター", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "サーバーと認証するためのパスワード。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a7325f0d55757..aa75fdff53bd7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -34396,7 +34396,6 @@ "xpack.synthetics.controls.selectSeverity.scoreDetailsDescription": "分数 {value} 及以上", "xpack.synthetics.createMonitorRoute.title": "创建监测 | {baseTitle}", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.throttling_exceeded.message": "您已超出 Synthetic 节点的 {throttlingField} 限制。{throttlingField} 值不能大于 {limit}Mbps。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.content": "Zip URL 已弃用,将在未来版本中移除。请改用项目监测以从远程存储库创建监测并迁移现有 Zip URL 监测。{link}", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.content": "要创建“浏览器”监测,请确保使用 {agent} Docker 容器,其中包含运行这些监测的依赖项。有关更多信息,请访问我们的 {link}。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.helpText": "请使用 JSON 来定义可在您的脚本中通过 {code} 引用的参数", "xpack.synthetics.deprecateNoticeModal.forMoreInformation": "有关更多信息,{docsLink}", @@ -34774,14 +34773,8 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.experimentalTooltip": "预览通过 Elastic Synthetics 记录器创建 Elastic Synthetics 监测脚本的最快方式", "xpack.synthetics.createPackagePolicy.stepConfigure.browser.scriptRecorder.label": "脚本记录器", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.description": "为 Synthetics 代理提供微调的配置。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.description": "使用这些选项可将选定监测设置应用于您套件中的测试子集。仅配置的子集由此监测运行。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.filtering.title": "选择性测试", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.helpText": "将此选项设为 true 可在 Synthetics 浏览器中禁用 TLS/SSL 验证。这对于使用自签名证书的测试站点很有用。", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.ignoreHttpsErrors.label": "忽略 HTTPS 错误", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.helpText": "通过此监测仅运行名称与提供的 glob 匹配的过程。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersMatch.label": "筛选匹配", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.helpText": "通过此监测仅运行具有给定标签的过程。", - "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.journeyFiltersTags.label": "筛选标签", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.helpText": "设置此选项以管理 Synthetics 代理捕获的屏幕截图。", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.screenshots.label": "屏幕截图选项", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.syntheticsArgs.helpText": "要传递给 Synthetics 代理软件包的附加参数。取字符串列表。这在极少情况下有用,通常应不需要设置。", @@ -34801,7 +34794,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.throttling.upload.label": "上传速度", "xpack.synthetics.createPackagePolicy.stepConfigure.browserAdvancedSettings.title": "Synthetics 代理选项", "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableSSLSettings.label": "启用 TLS 配置", - "xpack.synthetics.createPackagePolicy.stepConfigure.certificateSettings.enableZipUrlSSLSettings.label": "启用用于 Zip URL 的 TLS 配置", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.helpText": "用于 TLS 客户端身份验证的 PEM 格式证书。", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificate.label": "证书", "xpack.synthetics.createPackagePolicy.stepConfigure.certsField.certificateAuthorities.helpText": "PEM 格式自定义证书颁发机构。", @@ -34859,9 +34851,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.icmpAdvancedOptions": "高级 ICMP 选项", "xpack.synthetics.createPackagePolicy.stepConfigure.inputVarFieldOptionalLabel": "可选", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.helpText": "此监测的 APM 服务名称。对应于 service.name ECS 字段。监测也使用 APM 的应用时设置此选项以启用 Kibana 中的 Uptime 和 APM 数据之间的集成。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.APMServiceName.label": "APM 服务名称", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.brower.proxyURL.label": "代理 Zip URL", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.http.helpText": "用于 Zip URL 的 HTTP 代理。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.error": "“脚本”必填", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.helpText": "运行内联定义的 Synthetics 测试脚本。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.inlineScript.label": "内联脚本", @@ -34872,19 +34861,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.invalidFileError": "文件类型无效。请上传由 Elastic Synthetics 记录器生成的 .js 文件。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.label": "选择记录器生成的 .js 文件", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.uploader.parsingError": "上传文件时出错。请上传 Elastic Synthetics 记录器以内联脚本格式生成的 .js 文件。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.deprecation.title": "Zip URL 已过时", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.error": "ZIP URL 必填", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.helpText": "Synthetics 项目存储库 zip 文件的位置。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.label": "Zip URL", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.recorderLink": "下载 Elastic Synthetics 记录器", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.removeScriptLabel": "移除脚本", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrl.showScriptLabel": "显示脚本", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.helpText": "合成旅程文件在存储库中所在的相对目录路径。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlFolder.label": "文件夹", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.abel": "Zip URL 密码", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlPassword.helpText": "用于在 zip 终端上进行身份验证的密码。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.helpText": "用于在 zip 终端上进行身份验证的用户名。", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browser.zipUrlUsername.label": "Zip URL 用户名", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.browserLabel": "浏览器(公测版)", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.helpText": "关闭此配置以禁用监测。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.enabled.label": "已启用", @@ -34898,7 +34874,6 @@ "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType": "监测类型", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.link": "Synthetics 文档", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.warning.title": "要求", - "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.browser.zipUrl.deprecation.link": "了解详情", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.monitorType.error": "“监测类型”必填。", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.params.label": "参数", "xpack.synthetics.createPackagePolicy.stepConfigure.monitorIntegrationSettingsSection.password.helpText": "用于在服务器上进行身份验证的密码。",